如何在Java客户端中存储服务器密码以供以后重新连接?
我有一个通过安全/SSL 套接字连接到服务器的客户端应用程序。应用程序启动时需要用户登录。现在,我需要将实际密码发送到服务器(通过 SSL 加密),而不是发送密码哈希的首选方法。话虽如此,如何将密码安全地存储在客户端内存中,以便在客户端由于连接丢失而需要在后台重新连接到服务器时可以重新使用该密码?
我可以轻松加密密码,甚至将其放入 KeyStore 中并稍后检索以重新连接,但是,即使我这样做,在我看来,如果黑客有权在调试器中访问应用程序,他也可以检索密码。当人们需要在客户端上临时存储密码时,这只是生活中的事实吗?
是否有更好/首选的方法来实现相同的目标(即允许客户端重新连接到服务器而不要求用户在初始登录后再次输入密码)?从服务器发送的过期登录令牌是否是更好的方法(我可以在重新连接时将此过期令牌而不是密码传递回服务器)?
最后,一般来说,当应用程序正确“删除”调试符号时,将调试器连接到 Java 桌面或 Android 上正在运行的应用程序有多容易?我是否需要担心这种情况,或者 Java 是否会保护我的运输应用程序不被调试器或其他内存分析器附加到它?
I have a client application that connects to a server over a secure/SSL socket. The user is required to log in when the app starts. Right now I have a requirement that I need to send the actual password to the server (encrypted over the SSL), instead of the preferred method of sending a hash of the password. With that said, how do I go about securely storing the password in the client memory such that I can re-use this password if the client needs to reconnect to the server behind the scenes due to a lost connection?
I can easily encrypt the password, or even put it into a KeyStore and retrieve it later for the reconnect, however, even if I do this, it seems to me a hacker could retrieve the password if he had access to the application in a debugger. Is this just a fact of life when one needs to store the password on the client for a temporary time?
Is there a better/preferred way of achieving the same thing (i.e. allowing the client to reconnect to the server without requiring the user to enter his password again after the initial login)? Would an expiring login token sent from the server be a better way to go (where I can pass this expiring token back to the server instead of a password upon a reconnect)?
Finally, in general, how easy is it for someone to connect a debugger to a running application on Java desktop or Android, when the Application is correctly 'stripped' of debugging symbols? Do I even need to worry about this case, or will Java protect my shipping application from having a debugger, or other memory analyzer, attach to it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
正确的。当黑客通过用物理眼球观察用户的物理肩膀来观察用户输入时,也可以访问密码。
黑客在用户计算机上存储键盘记录器后就可以进行访问。
不。
另一种方法是您亲自访问每个用户并告诉他们不要使用调试器来破坏安全性。
让我们考虑一下用户(知道密码)在调试器中启动应用程序以了解密码的用例。他们已经知道了。
在考虑用户启动在调试器下运行的客户端应用程序的唯一用例之后,我不确定安全性是否“被破坏”,因为他们已经知道密码。
我想 Henry Hacker 有可能在调试器中启动应用程序,通过关闭电源将其隐藏在另一个显示器上,然后运行以获取真实用户并让他们在具有以下功能之一的开发工作站上输入密码:监视器关闭了。这就是您所说的“在调试器中访问应用程序”场景吗?
不是真的
不,Java 不保护您的用户。常识可以保护您的用户。
如果调试器正在运行,他们不应该使用计算机。
99% 的情况下,他们不会启动调试器。
1% 的情况下,他们会意外运行调试器——因为用户单击随机图标。其中 1% 实际上会让您的应用程序在调试器下运行。再次,通过单击随机图标。其中 1% 的人实际上会通过单击屏幕上的随机图标来输入密码。
用户可能可能会以某种方式在调试器下运行您的客户端。但。由于他们已经知道密码,因此无需担心。
这与中间人攻击或远程控制攻击完全不同。
如果有人远程控制您的用户计算机、运行调试器并监视事务,那么这是完全独立的。这是被防火墙和操作系统阻止的。不是Java。
这就是您所能做的。您的应用程序无法阻止“连接调试器”场景。操作系统的工作是提醒用户调试器正在连接。
如果您担心责任,请不要存储密码。责任结束。
Correct. The hacker also has access to the password when they watch the user type by looking over the user's physical shoulder with their physical eyeballs.
And the hacker has access after they store a keylogger on the users computer.
No.
The alternative is for you to personally visit each user and tell them not to use the debugger to break security.
Let's just think about the use case where the user (who knows the password) fires up the application in a debugger to learn the password. Which they already knew.
After thinking about the only use case in which the user fires up the client application running under a debugger, I'm not sure security is "broken", since they already knew the password.
I guess it would be possible for Henry Hacker to start the app in the debugger, conceal that on another display by turning the power off, then running to get the real user and having them type in their password on a development workstation that has one of the monitors turned off. Is that the "access to the application in a debugger" scenario you're talking about?
Not really
No, Java doesn't protect your users. Common sense protects your users.
If a debugger is running, they shouldn't be using the computer.
And 99% of the time, they won't get a debugger started.
1% of the time, they'll accidentally run a debugger -- because users click random icons. Of those 1% will actually get your application to run under the debugger. Again, by clicking random icons. Of those 1% will actually get to the place where they could type in a password by clicking random icons on the screen.
It could happen that a user could somehow run your client under a debugger. But. Since they already know the password, there's little point in worrying about it.
This is entirely different from a man-in-the-middle attack or a remote control attack.
If someone takes remote control of your user's computer, runs the debugger, and watches the transaction, that's entirely separate. That's stopped by firewalls and operating systems. Not Java.
That's all you can ever do. The "connect a debugger" scenario cannot be prevented by your applications. It's the OS's job to alert the user that a debugger is being connected.
If you're worried about liability, don't store passwords. End of liability.
您无法对应用程序中的(系统范围的)键盘记录器执行任何操作。因此,将密码存储在内存中是有风险的,但比会话令牌的风险要小:
黑客可以使用伪造 SSL/安全重新连接的恶意客户端并暴力破解令牌。这种方法比将密码存储在内存中会带来更多风险。
You can do nothing against a (system-wide) key logger in your application. So storing the password in memory is risky but less risky than session tokens:
A hacker can use a malicious client that has faked a SSL/secure reconnection and brute-forces the tokens. This approach would impose more risks than storing the password in memory.
我会按照你的建议去做,在服务器端创建某种会话令牌。将其与用户关联,并将其发送回客户端。
取决于你所说的简单是什么意思。我认为调试 Java 应用程序相当容易,即使它们去掉了调试符号。如果它们被混淆了,甚至可能能够调试它们。
I would do what you suggest, create some kind of session token on the server side. Associate it with the user, and send it back to the client.
Depends on what you mean by easy. I think it's rather easy to debug Java applications even if they are stripped of debugging symbols. Might even be able to debug them if they are obfuscated.