如何在NodeJS中使用HTTPS获取?

时间:2020-11-02 14:53:37

标签: node.js ssl https fetch-api public-key-encryption

我有一段很棒的Java代码(不是我写的),我需要将其转换为等效的NodeJS。它需要应用正确的SSL证书并进行https调用。我有两个带有相应密码的证书:

  • my_keystore.p12
  • my_truststore.jks

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同时包含私钥和证书,尽管我无法查看其中的内容。

那么,我想念什么?

0 个答案:

没有答案