码头客户/服务器相互认证

问题描述

我正在尝试构建具有以下一般要求的客户机/服务器servlet应用程序:

  • 客户端和服务器都是码头嵌入式的;
  • 服务器公开一个servlet,以便通过POST接收json数据;
  • 连接必须通过SSL保护(即连接将通过互联网通过https完成);
  • 我希望我的Jetty客户端能够将数据发送到我的服务器,服务器必须拒绝所有其他尝试;
  • 服务器和客户端是无人值守的机器(即人工无法插入通过命令行输入的密码);
  • 没有明文密码必须存储在客户端设备上。通常,我不希望有人可以打开远程客户端设备并窃取密码并构建能够将数据发送到我的服务器的假远程设备。

我已经通过HTTP构建了一个运行良好的客户端/服务器应用程序,但是我对安全性感到困惑。 我已经读过,有可能使用客户端/服务器相互身份验证,并且似乎是我在寻找什么,但我没有完整的图片。 在本文档client-certificate-authentication中,关于如何构建共享的受信任CA 或多或少有清晰的解释,但是访问TrustStoreKeyStore的密码是在代码中明确。 我想我在拼图中缺少一块瓷砖。 有人可以指出我正确的方向吗?

谢谢

S。

解决方法

我现在有一个简单的答案。

如果只希望您的客户端与服务器通信,那么可以,使用客户端SSL / TLS证书是可以的。

您需要将服务器的SslContextFactory.Server.setNeedClientAuth(true)设置为true。反过来,这将导致在传入连接建立时设置Java的javax.net.ssl.SSLParameters.setNeedClientAuth(true)。如果客户端无法提供客户端证书,则连接将关闭,并且不会发送或处理任何HTTP请求。

对于保护客户端证书,这取决于您,您可以做任何您想做的事情,只要它可以产生一个有效的客户端SslContextFactory.Client,Jetty客户端可以访问该客户端。这包括...

  • 使用纯文本密码
  • 使用obfuscated passwords(省力,安全性最低)
  • 客户端中其他位置的加密密钥库/信任库密码,在最后一分钟提供给SslContextFactory.Client。 (适度的安全性,不难理解)
  • 在启动Jetty客户端之前,自己创建java.security.KeyStore对象,并将其交给SslContextFactory.Client.setKeyStore(KeyStore)SslContextFactory.Client.setTrustStore(KeyStore)方法。 (更好的安全性,代表您进行更多工作)

您可能要考虑从服务器动态刷新客户端证书的寿命(24小时?),如果遇到滥用情况,可以取消客户端证书(在服务器/ CA端)。 (例如来自多个不同客户端IP的同一客户端证书)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...