具有自签名证书颁发机构的Nodejs TLS

时间:2015-12-12 14:56:51

标签: node.js ssl client-certificates ca tls1.2

背景:

我试图通过TLS在服务器和服务器之间进行通信(应该可以是多个 - 因此需要CA)。

每个节点都有一个使用公共CA签名的证书。 CA又是自签名的。

每个节点的私钥导出为 Intent getImageIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(getImageIntent, 1); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 1) { if (resultCode == Activity.RESULT_OK) { imageCounter++; takePicture(data); } else if (resultCode == Activity.RESULT_CANCELED) { } } } protected void takePicture(Intent data) { Bundle b = data.getExtras(); Bitmap pic = (Bitmap) b.get("data"); if (pic != null) { ImageView img = new ImageView(this); ((LinearLayout) findViewById(R.id.captured_image_layout)) .addView(img); img.setLayoutParams(new LinearLayout.LayoutParams(0, LinearLayout.LayoutParams.WRAP_CONTENT, 0.33f)); img.setPadding(5, 5, 5, 5); img.setImageBitmap(pic); } } 。 每个节点的证书导出为key.pem。 CA证书将导出为certificate.crt。 证书未捆绑,只是按原样导出。

服务器使用以下设置:

ca.crt

客户端使用以下设置:

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

var options = {
  key: fs.readFileSync("keys/key.pem", "utf8"),
  cert: fs.readFileSync("keys/certificate.crt", "utf8"),

  requestCert: true,
  rejectUnauthorized: true,

  ca: [fs.readFileSync('keys/ca.crt')]
}

var server = tls.createServer(options, function(res) {
  console.log("Client connected");

  console.log('Client connected',
              res.authorized ? 'authorized' : 'unauthorized');

  res.write("Hello World!");
  res.setEncoding("utf8");
  res.pipe(res);
}).listen(3000);

关于密钥/证书的说明:

密钥和证书是使用openssl GUI / manager XCA生成的。

树看起来如下: A visualisation of the certificate chain

问题:

如您所见,我正在使用显式客户端证书身份验证,我想禁止任何不允许的连接。

问题是客户端无法连接,即使所有证书都来自同一个CA.

我从服务器(客户端连接时)和客户端(连接时)得到的错误是:

var tls = require("tls"); var fs = require("fs"); var options = { key: fs.readFileSync("keys/key.pem", "utf8"), cert: fs.readFileSync("keys/certificate.crt", "utf8"), requestCert: true, rejectUnauthorized: true, ca: [fs.readFileSync('keys/ca.crt')] } var client = tls.connect(3000, options, function(){ console.log("Connected to server"); console.log(client.authorized ? "Authorized" : "Not authorized"); }); client.on("data", function(data){ console.log("Received from server", data); client.end(); });

如果我禁用Error: socket hang up, code: ECONNRESET客户端可以连接,但rejectUnauthorized返回false。

是什么导致授权客户无法进行身份验证?

1 个答案:

答案 0 :(得分:0)

你的代码很好。我希望你的证书有问题。没有失效日期这一事实对我而言非常重要。我发现这个OpenSSL Certificate Authority by Jamie Nguyen非常有用。 请记住,Nodejs不支持一个证书文件中的多个证书,因此如果您遵循该指南,则无需将根ca和中间ca复制到一个文件中。您必须将它们作为单独的文件条目添加到ca list参数中。

Afaik xca工具是在openssl上构建的,因此可能能够将openssl中的命令映射到xca。