Java - 从配置文件加密/解密用户名和密码

时间:2021-08-23 18:26:11

We are busy developing a Java web service for a client. There are two possible choices:

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

  • Store the encrypted user name / password on the web service client. Read from a config. file on the client side, decrypt and send.

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

  • Store the encrypted user name / password on the web server. Read from a config. file on the web server, decrypt and use in the web service.

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

The user name / password is used by the web service to access a third-party application.

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

The client already has classes that provide this functionality but this approach involves sending the user name / password in the clear (albeit within the intranet). They would prefer storing the info. within the web service but don't really want to pay for something they already have. (Security is not a big consideration because it's only within their intranet).

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

So we need something quick and easy in Java.

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

Any recommendations?

The server is Tomkat 5.5. The web service is Axis2.

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

  • What encrypt / decrypt package should we use?
  • 我们应该使用什么加密/解密包?

  • What about a key store?
  • 关键商店怎么样?

  • What configuration mechanism should we use?
  • 我们应该使用什么配置机制?

  • Will this be easy to deploy?
  • 这是否易于部署?

2 个解决方案

#1


18  

Being on the intranet certainly does not justify dismissing security. Most damage done to information is by insiders. Look at the value of what's being protected, and give due consideration to security.

在内联网上肯定不能解雇安全。对信息造成的损害最大的是内部人员。查看受保护的内容的价值,并充分考虑安全性。

It sounds like there's a third-party application, for which you have one set of credentials, and some clients that effectively share this identity when using the third-party application. If that's the case, I recommend the following approach.

这听起来像是第三方应用程序,您有一组凭据,以及一些在使用第三方应用程序时有效共享此身份的客户端。如果是这种情况,我建议采用以下方法。

Don't distribute the third-party password beyond your web server.

请勿将第三方密码分发到Web服务器之外。

The safest way to do this is to provide it to the web application interactively. This could be ServletContextListener that prompts for the password as the application starts, or a page in the application so that a admin can enter it through a form. The password is stored in the ServletContext and used to authenticate requests to the third-party service.

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

A step down in safety is to store the password on the server's file system so that it's readable only by the user running the server. This relies on the server's file system permissions for protection.

安全性降低是将密码存储在服务器的文件系统上,以便只有运行服务器的用户才能读取密码。这依赖于服务器的文件系统权限进行保护。

Trying to store an encrypted form of the password, on the client or the server, is just taking one step backward. You fall into an infinite regress when trying to protect a secret with another secret.

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

In addition, the clients should authenticate themselves to the server. If the client is interactive, have the users enter a password. The server can then decide if that user is authorized to access the third-party service. If the client is not interactive, the next best security is to protect the client's password using file system permissions.

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

To protect the clients' credentials, the channel between the client and your web server should be protected with SSL. Here, operating on an intranet is advantageous, because you can use a self-signed certificate on the server.

为保护客户端的凭据,客户端和Web服务器之间的通道应使用SSL进行保护。在此,在Intranet上运行是有利的,因为您可以在服务器上使用自签名证书。

If you do store passwords in a file, put them in a file by themselves; it makes the need to manage permissions carefully more conspicuous, and minimizes the need for many users to be editing that file and thus seeing the password.

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

#2


25  

As I understand anyhow in order to call 3rd party web service you pass password as plain text and no security certificates are involved.

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

Then I would say the easiest approach would be to store password in encrypted format (via java encryption mechanism) when the encryption/decryption key is just hard coded in the code.

然后我会说最简单的方法是在加密/解密密钥刚刚在代码中进行硬编码时以加密格式存储密码(通过java加密机制)。

I would definitely store it on the server side (file system or db) rather then distribute and maintain it on the multiple clients.

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

Here is how that could work with "DES" encryption:

以下是“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));

#1


18  

Being on the intranet certainly does not justify dismissing security. Most damage done to information is by insiders. Look at the value of what's being protected, and give due consideration to security.

在内联网上肯定不能解雇安全。对信息造成的损害最大的是内部人员。查看受保护的内容的价值,并充分考虑安全性。

It sounds like there's a third-party application, for which you have one set of credentials, and some clients that effectively share this identity when using the third-party application. If that's the case, I recommend the following approach.

这听起来像是第三方应用程序,您有一组凭据,以及一些在使用第三方应用程序时有效共享此身份的客户端。如果是这种情况,我建议采用以下方法。

Don't distribute the third-party password beyond your web server.

请勿将第三方密码分发到Web服务器之外。

The safest way to do this is to provide it to the web application interactively. This could be ServletContextListener that prompts for the password as the application starts, or a page in the application so that a admin can enter it through a form. The password is stored in the ServletContext and used to authenticate requests to the third-party service.

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

A step down in safety is to store the password on the server's file system so that it's readable only by the user running the server. This relies on the server's file system permissions for protection.

安全性降低是将密码存储在服务器的文件系统上,以便只有运行服务器的用户才能读取密码。这依赖于服务器的文件系统权限进行保护。

Trying to store an encrypted form of the password, on the client or the server, is just taking one step backward. You fall into an infinite regress when trying to protect a secret with another secret.

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

In addition, the clients should authenticate themselves to the server. If the client is interactive, have the users enter a password. The server can then decide if that user is authorized to access the third-party service. If the client is not interactive, the next best security is to protect the client's password using file system permissions.

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

To protect the clients' credentials, the channel between the client and your web server should be protected with SSL. Here, operating on an intranet is advantageous, because you can use a self-signed certificate on the server.

为保护客户端的凭据,客户端和Web服务器之间的通道应使用SSL进行保护。在此,在Intranet上运行是有利的,因为您可以在服务器上使用自签名证书。

If you do store passwords in a file, put them in a file by themselves; it makes the need to manage permissions carefully more conspicuous, and minimizes the need for many users to be editing that file and thus seeing the password.

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

#2


25  

As I understand anyhow in order to call 3rd party web service you pass password as plain text and no security certificates are involved.

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

Then I would say the easiest approach would be to store password in encrypted format (via java encryption mechanism) when the encryption/decryption key is just hard coded in the code.

然后我会说最简单的方法是在加密/解密密钥刚刚在代码中进行硬编码时以加密格式存储密码(通过java加密机制)。

I would definitely store it on the server side (file system or db) rather then distribute and maintain it on the multiple clients.

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

Here is how that could work with "DES" encryption:

以下是“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));