har*_*mic 5 java security authentication ssl
我正在编写一个程序,需要与Web服务器建立HTTPS连接,需要使用SSL客户端身份验证.
该程序的用户将使用来自Windows环境的证书来验证自己.
我发现了大量示例说明如何设置客户端身份验证,如果我首先将证书导出为pkcs12格式,它可以正常工作,但我不想强迫我的用户这样做.但是,当我尝试使用MSCAPI时,它总是会发生异常:
javax.net.ssl.SSLHandshakeException: Error signing certificate verify
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverHelloDone(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at sun.security.ssl.AppInputStream.read(Unknown Source)
at java.io.BufferedInputStream.fill(Unknown Source)
at java.io.BufferedInputStream.read1(Unknown Source)
at java.io.BufferedInputStream.read(Unknown Source)
at sun.net.www.http.HttpClient.parseHTTPHeader(Unknown Source)
at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
at sun.net.www.http.HttpClient.parseHTTP(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
at com.example.Win2.main(Win2.java:62)
Caused by: java.security.SignatureException: Bad Key.
at sun.security.mscapi.RSASignature.signHash(Native Method)
at sun.security.mscapi.RSASignature.engineSign(RSASignature.java:390)
at java.security.Signature$Delegate.engineSign(Unknown Source)
at java.security.Signature.sign(Unknown Source)
at sun.security.ssl.RSASignature.engineSign(Unknown Source)
at java.security.Signature$Delegate.engineSign(Unknown Source)
at java.security.Signature.sign(Unknown Source)
at sun.security.ssl.HandshakeMessage$CertificateVerify.<init>(Unknown Source)
... 16 more
Run Code Online (Sandbox Code Playgroud)
我无法确定该异常中的密钥可能出现的问题.
我做了一个很小的测试程序来重现我遇到的问题:
String passwd = .....";
URL url = new URL("https://.........");
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
KeyStore keyStore = KeyStore.getInstance("Windows-MY");
keyStore.load(null, passwd.toCharArray());
keyManagerFactory.init(keyStore, passwd.toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), null, null);
SSLSocketFactory socketFactory = context.getSocketFactory();
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(socketFactory);
Run Code Online (Sandbox Code Playgroud)
很明显我在这里不了解的API.它如何知道我想要使用的密钥库中的哪些密钥?我期待Windows提示我,就像其他需要进行身份验证的应用程序一样,但我怀疑它只是选择它找到的第一个.
我是否需要实现自己的密钥管理器,以便选择使用哪个密钥?
如果我遍历密钥库,我可以看到其中的密钥,并可以通过调用getKey来提取密钥.更复杂的是,商店中有多个具有相同别名的键(但有效性不同).其他(非Java)应用程序,例如.Chrome,似乎能够以某种方式确定使用哪些密钥.
编辑:我忘了提,我使用的是Java 1.7.
归档时间: |
|
查看次数: |
1273 次 |
最近记录: |