我正在尝试通过https连接到我的后端。 我有2个证书* .p12和* .cer。我是用命令导入的(参见代码) 我用命令导入了密钥:
keytool -v -importkeystore -srckeystore bonus-testagent.p12 -srcstoretype PKCS12 -destkeystore truststore.jks -deststoretype JKS
我的代码是(grails服务):
private SSLSocketFactory getSSLFactory() throws Exception {
KeyStore keyStore = KeyStore.getInstance("JKS");
String keystoreFile = 'D:\\grails_wide\\certificates\\truststore.jks'
File binaryFile = new File(keystoreFile);
InputStream is = binaryFile.newInputStream()
if (is == null) {
return null;
}
String password = "****";
keyStore.load(is, password.toCharArray());
is.close();
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
return ctx.getSocketFactory();
}
def accountInfo(String cardNumber, Cookie[] cookies) {
String urlStr = "https://app-domain.com";
URL url = new URL(urlStr);
HttpsURLConnection conn = (HttpsURLConnection)url.openConnection();
conn.setSSLSocketFactory(getSSLFactory());
conn.setRequestMethod("GET");
conn.setRequestProperty("Cookie", WebUtils.buildCookiesHeader(cookies))
InputStream is = conn.getInputStream();
BufferedReader rd = new BufferedReader(new InputStreamReader(is));
String line;
StringBuffer stringBuffer = new StringBuffer();
while ((line = rd.readLine()) != null) {
stringBuffer.append(line);
}
rd.close();
def response = stringBuffer.toString();
但它有错误:
ERROR errors.GrailsExceptionResolver - SunCertPathBuilderException occurred when processing request: [POST] /club/account
unable to find valid certification path to requested target. Stacktrace follows:
Message: unable to find valid certification path to requested target
在字符串中:
InputStream is = conn.getInputStream();
答案 0 :(得分:0)
首先,您通常不需要将PKCS#12(.p12)文件转换为JKS存储,您可以直接使用PKCS12
密钥库类型。
其次,.p12
文件通常不用作信任库,而是用作密钥。 (例如,请参阅this question了解密钥库和信任库之间的区别。).p12
文件将包含私钥材料,该资料不属于信任库。
您在此处所做的是使用.p12
文件替换默认信任库,因此它只能在远程连接时验证.p12
文件中的证书(而不是针对CA证书进行验证) )。因此,它失败了“无法找到有效的证书路径到请求的目标”。
据推测,您试图连接客户端证书。在这种情况下,您需要将该.p12
文件用作密钥库。要做到这一点:
.p12
,请改用KeyStore.getInstance("PKCS12")
。 (你不需要那个keytool转换。)KeyManagerFactory
代替TrustManagerFactory
使用它。 init密码将是密钥本身的密码,与PKCS#12中的商店密钥相同。ctx.init(kmf.getKeyManagers(), null, null)
。第二个null
参数将使用JRE的默认信任库(假设您的服务器以这种方式受信任)。