Java:通过资源加载 SSL 密钥库
如果我有:
System.setProperty("javax.net.ssl.keyStore", '/etc/certificates/fdms/WS1001237590._.1.ks');
System.setProperty("javax.net.ssl.keyStorePassword", 'DV8u4xRVDq');
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
我能够毫无问题地打开安全连接。
但是,我希望将证书直接存储在战争中,因此我使用:(文件输入流最终将成为资源流,但我这样做是为了让它工作。)
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("/etc/certificates/fdms/WS1001237590._.1.ks"), "DV8u4xRVDq".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "DV8u4xRVDq".toCharArray());
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);
现在,如果我打开相同的连接,我得到:javax.net.ssl.SSLHandshakeException:收到致命警报:handshake_failure
If I have:
System.setProperty("javax.net.ssl.keyStore", '/etc/certificates/fdms/WS1001237590._.1.ks');
System.setProperty("javax.net.ssl.keyStorePassword", 'DV8u4xRVDq');
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
I'm able to open a secure connection without a problem.
However, I'd like to have the certificates stored directly in the war, so I use: (The file input stream will eventually become a resource stream, but I'm doing this to get it to work.)
System.setProperty("sun.security.ssl.allowUnsafeRenegotiation", "true");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream("/etc/certificates/fdms/WS1001237590._.1.ks"), "DV8u4xRVDq".toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks, "DV8u4xRVDq".toCharArray());
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(kmf.getKeyManagers(), null, null);
Now, if I open the same connection, I get: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不久前我不得不做类似的事情。我有一个证书文件,我必须找到一种方法来加载它并将其用于 SSL 连接。希望我所做的能够帮助你。
首先我必须创建一个信任管理器:
之后我必须创建一个使用我的信任管理器的套接字工厂:
然后我使用该套接字工厂发送我的帖子:
我唯一不明白的是如何简单地添加证书文件到常规密钥库。我在研究过程中发现的所有示例源代码都指向创建一个套接字因子,然后向该套接字工厂注册一个协议。也许有一种方法可以简单地使用套接字工厂来建立连接,而无需注册协议;我还没有调查得很彻底。在我的特殊情况下,创建一个特定的协议是必要的。希望这能让您走得更远。我承认这似乎有点迂回;当我最初这样做时,我也有同样的感觉。但这是我让它发挥作用的唯一方法。也许其他人有更好的解决方案。
I had to do something similar a while back. I had a certificate file and I had to figure out a way to load it in and use it for an SSL connection. Hopefully what I did will help you out.
First I had to create a trust manager:
After that I had to create a socket factory that used my trust manager:
Then I used that socket factory to send my POST:
The only thing I couldn't figure out was how to simply add the certificate file to the regular keystore. All the example source code I found during my research pointed to creating a socket factor and then registering a protocol with that socket factory. Perhaps there is a way to simply use the socket factory to make a connection without registering a protocol; I haven't investigated that thoroughly. In my particular situation, creating a specific protocol was necessary. Hopefully this will get your further along the way. I admit it seems a bit roundabout; I felt the same way when I did it initially. But this was the only way I got it to work. Maybe other people have a better solution.
为了后代的缘故,所有这些都太复杂了,我们几乎只是在静态块中进行了检查:
For posterity's sake, all of this was far too complicated, and we pretty much just had a check in the static block:
对于Axis,我认为您需要通过以下方式配置其
SSLSocketFactory
:其中
com.example.MySSLSocketFactory
是实现org.apache.axis.components.net的类.SecureSocketFactory
(也许您可以扩展org.apache.axis.components.net.JSSESocketFactory
)。在
create
方法中,使用从您配置的SSLContext
获取的套接字工厂创建套接字。With Axis, I think you need to configure its
SSLSocketFactory
via:where
com.example.MySSLSocketFactory
is your class that implementsorg.apache.axis.components.net.SecureSocketFactory
(you could extendorg.apache.axis.components.net.JSSESocketFactory
perhaps).In the
create
method, create a socket using the socket factory obtained from theSSLContext
you've configured.如果您愿意,这里有一个可以轻松创建 SSLSocket 和 SSLServerSocket 的 API:
https://github.com/gpotter2/SSLKeystoreFactories
它不需要任何其他罐子....只需获取文件并使用它们,例如:
或者:
这更容易使用:)
If you want, here's an API to create SSLSocket and SSLServerSocket easily:
https://github.com/gpotter2/SSLKeystoreFactories
It does not require any other jars.... just get the files and use them like:
Or:
That's much easier to use :)
我遇到了类似的问题,我解决了创建一个使用来自输入流的密钥库返回 SSL 上下文的函数。
希望这有帮助。
I had similar problem, I solved creating a function that returns an SSL context using a keystore coming from and input stream.
Hope this helps.