我需要使用https证书连接到服务器。
使用以下命令从JKS密钥库中生成证书:
# CERTIFICATE
$ keytool -export -alias XXX -file certificate.der -keystore KEYSTORE.jks
$ openssl x509 -inform der -in certificate.der -out CERTIFICATE.pem
# PRIVATE KEY
$ keytool -importkeystore -srckeystore KEYSTORE.jks -destkeystore keystore.p12 -deststoretype PKCS12
$ openssl pkcs12 -in keystore.p12 -nodes -nocerts -out MYKEY.key
然后我尝试在Node中使用证书,但它失败了:
var fs = require('fs');
var https = require('https');
var options = {
hostname: 'XXX.com',
port: 4443,
path: '/endpoint',
method: 'GET',
key: fs.readFileSync('private.key', {encoding: 'utf8'}),
cert: fs.readFileSync('public.pem', {encoding: 'utf8'}),
rejectUnauthorized: false,
};
var req = https.request(options, function(res) {
res.on('data', function(data) {
process.stdout.write(data);
});
});
req.end();
req.on('error', function(e) {
console.error(e);
});
结果:
$ node req-raw.js
{ Error: write EPROTO 139684249024320:error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure:../deps/openssl/openssl/ssl/s23_clnt.c:802:
at _errnoException (util.js:1022:11)
at WriteWrap.afterWrite [as oncomplete] (net.js:867:14) code: 'EPROTO', errno: 'EPROTO', syscall: 'write' }
令人惊讶的是,CURL和S_CONNECT都有效
CURL输出:
$ curl -i -v https://SERVER:4443/ENDPOINT
/ENDPOIRT --cert MYCERT.pem --key MYKEY.key --insecure
* Trying X.X.X.X...
* Connected to SERVER (X.X.X.X) port 4443 (#0)
* found 148 certificates in /etc/ssl/certs/ca-certificates.crt
* found 597 certificates in /etc/ssl/certs
* ALPN, offering http/1.1
* SSL connection using TLS1.0 / RSA_3DES_EDE_CBC_SHA1
* server certificate verification SKIPPED
* server certificate status verification SKIPPED
* common name: *.XXXX.com (does not match 'XXXX.com')
* server certificate expiration date OK
* server certificate activation date OK
* certificate public key: RSA
* certificate version: #3
* subject: C=AT,ST=Vienna,L=Vienna,O=XXXXX AG,CN=*.XXXX.com
* start date: Thu, 03 Sep 2015 00:00:00 GMT
* expire date: Wed, 07 Nov 2018 12:00:00 GMT
* issuer: C=US,O=DigiCert Inc,OU=www.digicert.com,CN=DigiCert SHA2 High Assurance Server CA
* compression: NULL
* ALPN, server did not agree to a protocol
> GET /ENDPOINT HTTP/1.1
> Host: SERVER:4443
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
...
S_CONNECT输出:
$ openssl s_client -cert MYCERT.pem -key MYKEY.key -connect SERVER:4443
CONNECTED(00000003)
depth=2 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert High Assurance EV Root CA
verify return:1
depth=1 C = US, O = DigiCert Inc, OU = www.digicert.com, CN = DigiCert SHA2 High Assurance Server CA
verify return:1
depth=0 C = AT, ST = Vienna, L = Vienna, O = XXXXX, CN = XXXXX.com
verify return:1
---
Certificate chain
0 s:/C=AT/ST=Vienna/L=Vienna/O=XXXXX AG/CN=XXXXXX.com
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
1 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
2 s:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
i:/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
---
Server certificate
-----BEGIN CERTIFICATE-----
MIIFQTCC...T05kw=
-----END CERTIFICATE-----
subject=/C=AT/ST=Vienna/L=Vienna/O=XXXXX/CN=XXXXX
issuer=/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
---
Acceptable client certificate CA names
/C=US/O=VeriSign, Inc./OU=Class 1 Public Primary Certification Authority
/C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
/C=US/O=VeriSign, Inc./OU=Class 2 Public Primary Certification Authority
/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert High Assurance EV Root CA
/C=US/O=DigiCert Inc/OU=www.digicert.com/CN=DigiCert SHA2 High Assurance Server CA
/C=AT/ST=Vienna/L=Vienna/O=XXXX/OU=XXXXX/CN=XXXX non-productive System/emailAddress=XXXXX
Client Certificate Types: RSA sign, DSA sign
---
SSL handshake has read 4523 bytes and written 1829 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
Protocol : TLSv1
Cipher : RC4-SHA
Session-ID: XXXXX
Session-ID-ctx:
Master-Key: XXXXXX
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1527939931
Timeout : 300 (sec)
Verify return code: 0 (ok)
---
你有线索吗?