Last-modified: 2016-04-01 (金) 00:06:27
node.js/クライアント認証がしたい

概要

node.jsでクライアント認証(自己証明書)をします。
なおWebサイトでのクライアント認証は、SSL/TLSハンドシェイク内でクライアント証明書要求/検証を行うため、必然的にHTTPSになります。
今回はサーバー証明書も解説目的で自己証明書を使います。
Auzre上で動かす場合は、Azure/App Serviceでクライアント認証がしたい

サーバー証明書、クライアント証明書を作成

  1. 自己証明書を作成
    opensslが入っていない場合は、gitなど同梱されているものを入れるか、chocolateyでopensslを入れるか、公式サイトからいれておく
    Everything is expanded.Everything is shortened.
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
    
    -
    !
    -
    |
    !
    -
    !
     
    -
    !
     
     
     
    -
    !
     
     
    
    REM private key作成
    openssl genrsa 4096 > <private key出力先>
    REM 証明書署名要求(CSR)作成
    REM -configはつけなくてもいける環境と[Unable to load config info from /usr/local/ssl/openssl.cnf]などとでる環境があった
    openssl req -batch -new -sha256 -key <private keyパス> -out <CSR出力パス> -subj <証明書名(C:国名, ST:都道府県, L:都市名, O:組織名, OU:部署, CN:発行元)> -config <openssl.cnfのパス>
    REM 証明書作成
    openssl x509 -req -days 3650 -signkey <private keyパス> -in <CSRパス> -out <証明書出力パス>
     
    REM 例. SSLサーバー証明書作成(証明書内の公開鍵と対をなすprivate key:server.key, 証明書:server.crt)
    openssl genrsa 4096 > "D:\server.key"
    openssl req -batch -new -sha256 -key "D:\server.key" -out "D:\server.csr" -subj "/C=JP/ST=Tokyo/L=hoge/O=foo/OU=bar/CN=foo.bar.com" -config "..\ssl\openssl.cnf"
    openssl x509 -req -days 3650 -signkey "D:\server.key" -in "D:\server.csr" -out "D:\server.crt"
     
    REM 例. SSLクライアント証明書作成(証明書内の公開鍵と対をなすprivate key:client.key, 証明書:client.crt)
    openssl genrsa 4096 > "D:\client.key"
    openssl req -batch -new -sha256 -key "D:\client.key" -out "D:\client.csr" -subj "/C=JP/ST=Tokyo/L=hoge/O=foo/OU=bar/CN=foo.bar.com" -config "..\ssl\openssl.cnf"
    openssl x509 -req -days 3650 -signkey "D:\client.key" -in "D:\client.csr" -out "D:\client.crt"
  2. クライアント証明書(X509形式)をPKCS12形式に変換
    PKCS12形式に変換した証明書をダブルクリックしてインストールすると、IEなどでCertificateRequestを受信すると、証明書選択ダイアログが出るようになる
    Everything is expanded.Everything is shortened.
      1
      2
      3
      4
    
     
     
    -
    !
    
    openssl pkcs12 -export -in <証明書(X509)パス> -inkey <private keyパス> -out <証明書(PKCS12)出力パス>
     
    REM 例.
    openssl pkcs12 -export -in "D:\client.crt" -inkey "D:\client.key" -out "D:\client.pfx"
  3. 必要ならばクライアント証明書(PKCS12)をダブルクリックしてWindowsにインストール
    000013.png

server.js

Everything is expanded.Everything is shortened.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 
 
 
 
 
-
|
|
!
 
-
|
|
|
|
|
!
 
-
|
!
var https = require('https');
var fs = require('fs');
var express = require('express');
var app = express();
 
app.get('/', function (req, res) {
    console.log(req.connection.getPeerCertificate());
    res.send("/");
});
 
var option = {
    key: fs.readFileSync('server.key'),    // サーバー証明書内の公開鍵と対をなすprivate key
    cert: fs.readFileSync('server.crt'),    // サーバー証明書
    ca: fs.readFileSync('client.crt'),    // クライアント証明書
    requestCert: true,            // クライアント認証(true:する, false:しない)
    rejectUnauthorized: true        // 認証失敗時に破棄(true:する, false:しない)
};
 
var server = https.createServer(option, app).listen(process.env.port, function () {
    console.log("server listening on port %d", server.address().port);
});

確認

検証時の環境