具体案例:UNABLE_TO_VERIFY_LEAF_SIGNATURE

时间:2015-04-22 05:15:28

标签: node.js ssl twitter authorization

我一直在尝试对服务器和客户端之间的TLS连接进行测试。 (SSL客户端身份验证)

我有一个自签名密钥对。

如果我尝试使用tls.connect()连接我的API服务器,则我的连接似乎为unauthorizedauthorizationError值为UNABLE_TO_VERIFY_LEAF_SIGNATURE,如下面的屏幕截图所示。

但是,如果我尝试连接https://api.twitter.com而不是https://hellolarim.club,则表示没有错误,authorization值为true。此外,当我尝试Twitter时,我不必使用rejectUnauthorized: false参数。

我也添加了以下server.js代码。

问题:我想知道为什么我无法以authorized: true身份连接?

我必须对我的API服务器实施SSL客户端身份验证。

尝试连接到我的API服务器


client.js

var tls = require('tls');
var fs = require('fs');

var options = {
  key: fs.readFileSync('client-private-key.pem'),
  cert: fs.readFileSync('client-certificate.pem'),

  rejectUnauthorized: false,
};

{
var cleartextStream = tls.connect(443, 'www.hellolarim.club', options, function() {

  console.log('\nclient connected', cleartextStream.authorized ? 'authorized' : 'unauthorized'); 
  if(!cleartextStream.authorized) {
    console.log("authorizationError: " + cleartextStream.authorizationError);
  }

  process.stdin.resume();
  process.stdin.pipe(cleartextStream);
});
cleartextStream.setEncoding('utf8');
cleartextStream.on('data', function(data) {
  console.log("\n" + data);
});
cleartextStream.on('end', function() {
  server.close();
});

enter image description here

尝试连接到Twitter API服务器


enter image description here


Server.js

var tls = require('tls');
var fs = require('fs');

var options = {
  key: fs.readFileSync('key.pem'),
  cert: fs.readFileSync('cert.pem'),
  requestCert: true,
  rejectUnauthorized: true,

  ca: [ fs.readFileSync('../client/client-certificate.pem') ]
};

var server = tls.createServer(options, function(cleartextStream) {

  console.log(cleartextStream.getPeerCertificate());

  console.log('server connected',
              cleartextStream.authorized ? 'authorized' : 'unauthorized');
  cleartextStream.write("Hello from server to client!\n");
  cleartextStream.setEncoding('utf8');
  cleartextStream.pipe(cleartextStream);
});
server.listen(443, function() {
  console.log('server bound');
});

1 个答案:

答案 0 :(得分:0)

问题出在客户端。

客户无法识别服务器的证书,尽管证书是从商业CA获得的,因为客户端选项上没有ca参数!

如果我们有很多根证书,我们可以通过转换如下所示的字符串数组来安装它们,或者使用node-ssl-root-cas

var CAcerts = [ 
  // A Root CA cert.
  "-----BEGIN CERTIFICATE-----\n" +
  "MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE\n" +
  "BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG\n" +
  "tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW\n" +
  "sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp\n" +
  "7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I\n" +
  "LaZRfyHBNVOFBkpdn627G190\n" +
  "-----END CERTIFICATE-----\n",
  // Another Root CA cert.
  "-----BEGIN CERTIFICATE-----\n" +
  "MIIF2DCCA8CgAwIBAgIQTKr5yttjb+Af907YWwOGnTANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UE\n" +
  "BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG\n" +
  "tZx8jb8uk2IntznaFxiuvTwJaP+EmzzV1gsD41eeFPfR60/IvYcjt7ZJQ3mFXLrrkguhxuhoqEwW\n" +
  "sRqZCuhTLJK7oQkYdQxlqHvLI7cawiiFwxv/0Cti76R7CZGYZ4wUAc1oBmpjIXUDgIiKboHGhfKp\n" +
  "7RH89elWsn2/x20Kk4yl0MC2Hb46TpSi125sC8KKfPog88Tk5c0NqMuRkrF8hey1FGlmDoLnzc7I\n" +
  "LaZRfyHBNVOFBkpdn627G190\n" +
  "-----END CERTIFICATE-----\n"
  ];

var options = {
  key: fs.readFileSync('client-private-key.pem'),
  cert: fs.readFileSync('client-certificate.pem'),
  ca: CAcerts,
  requestCert: true,
  rejectUnauthorized: true,
};