英文:
Jetty client / server mutual authentication
问题
我正在尝试构建一个客户端/服务器servlet应用程序,具有以下一般要求:
- 客户端和服务器都是嵌入式的Jetty;
- 服务器公开一个servlet,以便通过
POST
接收JSON数据; - 连接必须通过SSL进行安全连接(即连接将通过https在Internet上进行);
- 我希望只有我的Jetty客户端能够向服务器发送数据,所有其他尝试都必须被服务器拒绝;
- 服务器和客户端都是无人值守的机器(即不能通过命令行插入人工密码);
- 客户端设备上不得存储明文密码。一般情况下,我不希望有人能够打开远程客户端设备并窃取密码,并构建一个能够向我的服务器发送数据的虚假远程设备。
我已经构建了一个完美工作的客户端/服务器应用程序通过HTTP
,但是我对安全性感到困惑。
我已经阅读到可以使用客户端/服务器相互认证,并且似乎符合我要寻找的内容,但我无法完整地理解。
在这份文档中client-certificate-authentication中,对如何构建共享的受信任CA有一个比较清晰的解释,但是访问TrustStore
和KeyStore
的密码在代码中是明文。
我想我在拼图中缺少了一块。
有人可以指点我正确的方向吗?
谢谢,
S.
英文:
I am trying to build a client / server servlet application with these general requisites:
- both the client and the server are jetty embedded;
- the server expose a servlet in order to receive json data via
POST
; - the connection must be secured via SSL (i.e. the connection will be done via Internet via https);
- I want that only my Jetty client be able to send data to my server, all other tentative must be refused by the server;
- the server and the client are unattended machines (i.e. not password via command line could be inserted by human);
- no password in clear must be stored on the client device. In general I don't want someone could open the remote client device and stole the password and building a fake remote device capable to send data to my server too.
I have build a perfectly working client / server application via HTTP
but I am confused about the security.
I have read that there is the possibility to use client / server mutual authentication and seems what I am looking for but I can't get the complete picture.
In this document client-certificate-authentication there is a more or less clear explanation about how to build a shared trusted CA but the password for accessing the TrustStore
and the KeyStore
are in clear in the code.
I think I am missing a tile in the puzzle.
Could someone point me in the right direction?
Thanks,
S.
答案1
得分: 2
我现在给一个简单的答案(暂时)。
如果你只想让你的客户端与服务器进行通信,那么是的,客户端SSL/TLS证书是可行的方法。
你需要将服务器的 SslContextFactory.Server.setNeedClientAuth(true)
设置为true。这将进而导致Java的 javax.net.ssl.SSLParameters.setNeedClientAuth(true)
在传入连接建立时被设置。如果客户端未能提供客户端证书,连接将被关闭,不会发送或处理任何HTTP请求。
至于保护客户端证书,那取决于你,你可以做任何你想做的事情,只要最终能得到一个Jetty客户端可以访问的有效客户端 SslContextFactory.Client
。这包括...
- 使用明文密码
- 使用混淆密码(付出最小努力,安全性较低)
- 在客户端的其他地方使用加密的密钥库/信任库密码,然后在最后一刻提供给SslContextFactory.Client。(安全性适中,不太难破解)
- 自己创建
java.security.KeyStore
对象,并在启动Jetty客户端之前将其传递给SslContextFactory.Client.setKeyStore(KeyStore)
和SslContextFactory.Client.setTrustStore(KeyStore)
方法。(从安全性上来说更好一些,但需要更多的工作)
你可能考虑让客户端证书具有短期有效性(24小时?),从服务器动态刷新,并且如果遇到滥用情况,可以在服务器/CA端撤销客户端证书。(比如同一个客户端证书从多个不同的客户端IP出现的情况)
英文:
I'm going with a simple answer (for now).
If you just want only your clients to talk to the server, then yes, Client SSL/TLS certificates are the way to go.
You'll want the server's SslContextFactory.Server.setNeedClientAuth(true)
set to true. That will in turn cause Java's javax.net.ssl.SSLParameters.setNeedClientAuth(true)
to be set on incoming connection establishment. If the client fails to provide the client certificate, the connection is closed, and no HTTP request is sent or processed.
As for securing the client certificate, that's up to you, you can do anything you want to do, as long as it results in a valid client SslContextFactory.Client
that the Jetty client can access. This includes ...
- Using plaintext passwords
- Using obfuscated passwords (minimal effort, minimal security)
- Encrypted keystore/truststore passwords elsewhere in your client, provided to the SslContextFactory.Client at the last minute. (modest security, wouldn't be that hard to figure out)
- Creating the
java.security.KeyStore
object yourself and handing it toSslContextFactory.Client.setKeyStore(KeyStore)
andSslContextFactory.Client.setTrustStore(KeyStore)
methods prior to starting the Jetty Client. (a bit better security wise, puts more work on your behalf)
You might want to consider having the client certificates be short-lived (24 hours?) dynamically refreshed from the server, and have the client certificates be revokable (at the server/CA side) if you encounter abuse. (such as the same client certificate from multiple different client IPs)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论