我有一段很棒的Java代码(不是我写的),我需要将其转换为等效的NodeJS。它需要应用正确的SSL证书并进行https调用。我有两个带有相应密码的证书:
Java代码可以正常工作,并且基本上可以做到:
SSLContext sslcontext = SSLContexts.custom().useProtocol("TLS")
.loadKeyMaterial(getKeyStore(), getKeyStorePwd())
.loadTrustMaterial(getTrustStore(), null).build();
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslcontext);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSocketFactory).build();
this.setHttpClient(httpClient);
其中的getKeyStore / getTrustStore方法是这样的(为简洁起见删除了一些代码):
try(InputStream keystoreInputStream = getKeyStoreInputStream(KEYSTORE_PATH)) {
if (keyStore == null) keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(keystoreInputStream, getKeyStorePwd());
///
try (InputStream truststoreInputStream = getKeyStoreInputStream(TRUSTSTORE_PATH)) {
if (trustStore == null) trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(truststoreInputStream, getTrustStorePwd());
我在Node中尝试做的事情是这样的:
const https = require('https');
const fs = require('fs');
const jks = require('jks-js');
const keystore = jks.toPem(
fs.readFileSync('./src/resources/keystore/my_truststore.jks'),
'TruststorePassword'
);
const {ca} = keystore['firstca'];
console.log(ca);
// prints
// -----BEGIN CERTIFICATE-----
// MIIDrzCCApe... etc.
const options = {
pfx: fs.readFileSync('./src/resources/keystore/my_keystore.p12'),
passphrase: 'KeystorePassword',
ca: ca,
};
const sslConfiguredAgent = new https.Agent(options);
let url = 'https://the.service';
let body = {a:'aaa', b:'bbb'};
const response = await fetch(url, {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
agent: sslConfiguredAgent,
body: JSON.stringify(body)
});
这不起作用,并且出现以下错误:
FetchError: request to https://the.service failed, reason: write EPROTO 4559838656:error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/record/rec_layer_s3.c:1536:SSL alert number 40
由于我得到了正确的日志ca
,因此我认为可以。因为如果将KeystorePassword更改为错误的值会导致验证失败,所以我假设在上面的代码中正确读取了my_keystore。我还假设my_keystore.p12同时包含私钥和证书,尽管我无法查看其中的内容。
那么,我想念什么?