如何在grails中使用* .p12证书来建立https连接?

时间:2014-02-27 15:08:29

标签: grails ssl https

我正在尝试通过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();

1 个答案:

答案 0 :(得分:0)

首先,您通常不需要将PKCS#12(.p12)文件转换为JKS存储,您可以直接使用PKCS12密钥库类型。

其次,.p12文件通常不用作信任库,而是用作密钥。 (例如,请参阅this question了解密钥库和信任库之间的区别。).p12文件将包含私钥材料,该资料不属于信任库。

您在此处所做的是使用.p12文件替换默认信任库,因此它只能在远程连接时验证.p12文件中的证书(而不是针对CA证书进行验证) )。因此,它失败了“无法找到有效的证书路径到请求的目标”。

据推测,您试图连接客户端证书。在这种情况下,您需要将该.p12文件用作密钥库。要做到这一点:

  1. (可选)如果您想直接加载.p12,请改用KeyStore.getInstance("PKCS12")。 (你不需要那个keytool转换。)
  2. KeyManagerFactory代替TrustManagerFactory使用它。 init密码将是密钥本身的密码,与PKCS#12中的商店密钥相同。
  3. 使用ctx.init(kmf.getKeyManagers(), null, null)。第二个null参数将使用JRE的默认信任库(假设您的服务器以这种方式受信任)。