【问题标题】:Java - encrypt / decrypt user name and password from a configuration fileJava - 从配置文件中加密/解密用户名和密码
【发布时间】:2023-04-01 09:24:01
【问题描述】:

我们正忙于为客户开发 Java Web 服务。有两种可能的选择:

  • 将加密的用户名/密码存储在 Web 服务客户端上。从配置中读取。文件在客户端,解密并发送。

  • 将加密的用户名/密码存储在 Web 服务器上。从配置中读取。 Web服务器上的文件,解密并在Web服务中使用。

Web 服务使用用户名/密码访问第三方应用程序。

客户端已经有提供此功能的类,但此方法涉及以明文形式发送用户名/密码(尽管在 Intranet 中)。他们更喜欢存储信息。在网络服务中,但不想为他们已经拥有的东西付费。 (安全性不是一个重要的考虑因素,因为它只存在于他们的 Intranet 中)。

所以我们需要在 Java 中快速简单的东西。

有什么建议吗?

服务器是 Tomkat 5.5。 Web 服务是 Axis2。

  • 我们应该使用什么加密/解密包?
  • 密钥库怎么样?
  • 我们应该使用什么配置机制?
  • 这是否易于部署?

【问题讨论】:

    标签: java encryption configuration-files


    【解决方案1】:

    据我所知,为了调用第 3 方网络服务,您将密码作为纯文本传递,并且不涉及安全证书。

    然后我想说最简单的方法是以加密格式存储密码(通过 java 加密机制),而加密/解密密钥只是硬编码在代码中。

    我肯定会将它存储在服务器端(文件系统或数据库),而不是在多个客户端上分发和维护它。

    这是如何使用“DES”加密的:

    // only the first 8 Bytes of the constructor argument are used 
    // as material for generating the keySpec
    DESKeySpec keySpec = new DESKeySpec("YourSecr".getBytes("UTF8")); 
    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    SecretKey key = keyFactory.generateSecret(keySpec);
    sun.misc.BASE64Encoder base64encoder = new BASE64Encoder();
    sun.misc.BASE64Decoder base64decoder = new BASE64Decoder();
    .........
    
    // ENCODE plainTextPassword String
    byte[] cleartext = plainTextPassword.getBytes("UTF8");      
    
    Cipher cipher = Cipher.getInstance("DES"); // cipher is not thread safe
    cipher.init(Cipher.ENCRYPT_MODE, key);
    String encrypedPwd = base64encoder.encode(cipher.doFinal(cleartext));
    // now you can store it 
    ......
    
    // DECODE encryptedPwd String
    byte[] encrypedPwdBytes = base64decoder.decodeBuffer(encryptedPwd);
    
    Cipher cipher = Cipher.getInstance("DES");// cipher is not thread safe
    cipher.init(Cipher.DECRYPT_MODE, key);
    byte[] plainTextPwdBytes = (cipher.doFinal(encrypedPwdBytes));
    

    【讨论】:

    • “你的密钥短语”从何而来?如果该来源是安全的,为什么不使用它来保存实际密码?
    • 正如我提到的,关键短语在 java 类中是硬编码的,或者它可以存储在数据库中。每次更改密码时,使用密码本身都需要重新编译代码。
    • 任何能够访问该文件的人也可以访问您的代码并对其进行反编译(或简单地使用它)以获取密钥。 Microsoft 尝试了类似的方法来保护 SAM,但它几乎立即被破坏了。
    • @frankodwyer 你是对的,但我的回答(以及问题本身)并没有假装提供完全安全的解决方案,而是提供一定程度的安全性。所以对我来说,@ericson 方法之间的问题更多:“什么都不做”和另一种方法:“做一些最小的事情是有价值的”。
    • 有问题!如果您将“您的密钥短语”更改为“您的密钥短语eek434jlh72eee”,您仍然可以正确解密。错了。
    【解决方案2】:

    在 Intranet 上当然不能成为忽视安全性的理由。对信息造成的大多数损害是由内部人员造成的。查看受保护内容的价值,并适当考虑安全性。

    听起来有一个第三方应用程序,您有一组凭据,并且一些客户端在使用第三方应用程序时有效地共享此身份。如果是这种情况,我推荐以下方法。

    请勿将第三方密码分发到您的网络服务器之外。

    执行此操作的最安全方法是以交互方式将其提供给 Web 应用程序。这可能是在应用程序启动时提示输入密码的 ServletContextListener,或者是应用程序中的一个页面,以便管理员可以通过表单输入它。密码存储在 ServletContext 中,用于验证对第三方服务的请求。

    安全的一个步骤是将密码存储在服务器的文件系统中,这样只有运行服务器的用户才能读取它。这依赖于服务器的文件系统权限进行保护。

    尝试在客户端或服务器上存储加密形式的密码只是退步了一步。当你试图用另一个秘密来保护一个秘密时,你会陷入无限倒退。

    此外,客户端应向服务器验证自己的身份。如果客户端是交互式的,则让用户输入密码。然后服务器可以决定该用户是否被授权访问第三方服务。如果客户端不是交互式的,次佳的安全措施是使用文件系统权限保护客户端的密码。

    为了保护客户端的凭据,客户端和您的网络服务器之间的通道应该使用 SSL 保护。在这里,在 Intranet 上操作是有利的,因为您可以在服务器上使用自签名证书。

    如果您确实将密码存储在文件中,请将它们自己放入文件中;它使仔细管理权限的需要更加突出,并最大限度地减少了许多用户编辑该文件并因此查看密码的需要。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-05-18
      • 2014-05-20
      • 2017-04-15
      • 2018-05-22
      • 2012-05-08
      • 2013-12-07
      • 1970-01-01
      相关资源
      最近更新 更多