menu-icon

Windowsで自己証明書を作って導入する

Windowsで自己証明書(オレオレ証明書)を作って、Nginxに導入します。Nginxのインストールはコチラです。

事前準備

必要なものをインストールしておきます。

OpenSSLのインストール

ここでインストーラが配布されているのでダウンロードしてインストールします。自分はWin64 OpenSSL v1.1.1gをインストールしました。Light(軽量版)は、"Recommended for users by the creators of OpenSSL" とあったので試してないですが、そちらでもいけるかもしれません。

Active Perlのインストール

証明書を作るためのバッチの実行に使用します。ここからダウンロードしてインストールします。自分は過去に使ったことがあるActive Perlを選択しましたが、Perlが実行できるなら何でも構いません。

コンフィグの作成

作業用ディレクトリを用意し、C:\Program Files\OpenSSL-Win64\bin\cnf\openssl.cnf をコピーして rca.cnf とリネームします。そして、以下の様に変更します。有効期限とalt_namesは適宜変更してください。

ファイル C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CNF\openssl.cnf と RCA.CNF を比較しています
***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CNF\openssl.cnf
   44:  
   45:  dir             = ./demoCA              # Where everything is kept
   46:  certs           = $dir/certs            # Where the issued certs are kept
***** RCA.CNF
   44:  
   45:  dir             = ./RCA         # Where everything is kept
   46:  certs           = $dir/certs            # Where the issued certs are kept
*****

***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CNF\openssl.cnf
   74:  
   75:  default_days    = 365                   # how long to certify for
   76:  default_crl_days= 30                    # how long before next CRL
***** RCA.CNF
   74:  
   75:  default_days    = 730                   # how long to certify for
   76:  default_crl_days= 30                    # how long before next CRL
*****

***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CNF\openssl.cnf
  126:  
  127:  # req_extensions = v3_req # The extensions to add to a certificate request
  128:  
***** RCA.CNF
  126:  
  127:  req_extensions = v3_req # The extensions to add to a certificate request
  128:  
*****

***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CNF\openssl.cnf
  177:  # This is OK for an SSL server.
  178:  # nsCertType                    = server
  179:  
***** RCA.CNF
  177:  # This is OK for an SSL server.
  178:  nsCertType                      = server
  179:  
*****

***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CNF\openssl.cnf
  196:  subjectKeyIdentifier=hash
  197:  authorityKeyIdentifier=keyid,issuer
  198:  
***** RCA.CNF
  196:  subjectKeyIdentifier=hash
  197:  authorityKeyIdentifier=keyid,issuer:always
  198:  
*****

***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CNF\openssl.cnf
  203:  # deprecated according to PKIX.
  204:  # subjectAltName=email:move
  205:  
***** RCA.CNF
  203:  # deprecated according to PKIX.
  204:  subjectAltName=@alt_names
  205:  
*****

***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CNF\openssl.cnf
  224:  keyUsage = nonRepudiation, digitalSignature, keyEncipherment
  225:  
***** RCA.CNF
  224:  keyUsage = nonRepudiation, digitalSignature, keyEncipherment
  225:  subjectAltName=@alt_names
  226:  
  227:  [ alt_names ]
  228:  DNS.1=*.tdomy.com
  229:  
*****

***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CNF\openssl.cnf
  245:  # Some might want this also
  246:  # nsCertType = sslCA, emailCA
  247:  
***** RCA.CNF
  249:  # Some might want this also
  250:  nsCertType = sslCA, emailCA
  251:  
*****

***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CNF\openssl.cnf
  249:  # subjectAltName=email:copy
  250:  # Copy issuer details
***** RCA.CNF
  253:  # subjectAltName=email:copy
  254:  
  255:  # Copy issuer details
*****

***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CNF\openssl.cnf
  327:  # These are used by the TSA reply generation only.
  328:  dir             = ./demoCA              # TSA root directory
  329:  serial          = $dir/tsaserial        # The current serial number (mandatory)
***** RCA.CNF
  332:  # These are used by the TSA reply generation only.
  333:  dir             = ./RCA         # TSA root directory
  334:  serial          = $dir/tsaserial        # The current serial number (mandatory)
*****

次に、rca.cnf をコピーして ica.cnfを作り、下記の様に編集します。

ファイル rca.cnf と ICA.CNF を比較しています
***** rca.cnf
   44:  
   45:  dir             = ./RCA         # Where everything is kept
   46:  certs           = $dir/certs            # Where the issued certs are kept
***** ICA.CNF
   44:  
   45:  dir             = ./ICA         # Where everything is kept
   46:  certs           = $dir/certs            # Where the issued certs are kept
*****

***** rca.cnf
  332:  # These are used by the TSA reply generation only.
  333:  dir             = ./RCA         # TSA root directory
  334:  serial          = $dir/tsaserial        # The current serial number (mandatory)
***** ICA.CNF
  332:  # These are used by the TSA reply generation only.
  333:  dir             = ./ICA         # TSA root directory
  334:  serial          = $dir/tsaserial        # The current serial number (mandatory)
*****

バッチの作成

作業用ディレクトリに、C:\Program Files\OpenSSL-Win64\bin\CA.pl をコピーし、rca.pl にリネームします。以下のように編集します。

ファイル C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CA.pl と RCA.PL を比較しています
***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CA.pl
   26:  
   27:  my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} || "";
   28:  my $DAYS = "-days 365";
***** RCA.PL
   26:  
   27:  my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} || "-config ./rca.cnf";
   28:  my $DAYS = "-days 365";
*****

***** C:\PROGRAM FILES\OPENSSL-WIN64\BIN\CA.pl
   36:  # default openssl.cnf file has setup as per the following
   37:  my $CATOP = "./demoCA";
   38:  my $CAKEY = "cakey.pem";
***** RCA.PL
   36:  # default openssl.cnf file has setup as per the following
   37:  my $CATOP = "./RCA";
   38:  my $CAKEY = "cakey.pem";
*****

そして、rca.plをコピーしてipa.plを作成し、編集します。

ファイル rca.pl と ICA.PL を比較しています
***** rca.pl
   26:  
   27:  my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} || "-config ./rca.cnf";
   28:  my $DAYS = "-days 365";
***** ICA.PL
   26:  
   27:  my $OPENSSL_CONFIG = $ENV{"OPENSSL_CONFIG"} || "-config ./ica.cnf";
   28:  my $DAYS = "-days 365";
*****

***** rca.pl
   36:  # default openssl.cnf file has setup as per the following
   37:  my $CATOP = "./RCA";
   38:  my $CAKEY = "cakey.pem";
***** ICA.PL
   36:  # default openssl.cnf file has setup as per the following
   37:  my $CATOP = "./ICA";
   38:  my $CAKEY = "cakey.pem";
*****

証明書の作成

以下、Win64 OpenSSL Command Promptで作業します。

ルートCAの作成

>mkdir dist

>perl rca.pl -newca
CA certificate filename (or enter to create)
(何も入力せずenter)

Making CA certificate ...
====
openssl req -config ./rca.cnf -new -keyout ./RCA/private/cakey.pem -out ./RCA/careq.pem
Generating a RSA private key
............................+++++
........+++++
writing new private key to './RCA/private/cakey.pem'
Enter PEM pass phrase:
(パスワード設定)
Verifying - Enter PEM pass phrase:
(上記のパスワード再入力)

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

(上記の情報は適当に入力)

openssl ca -config ./rca.cnf -create_serial -out ./RCA/cacert.pem -days 1095 -batch -keyfile ./RCA/private/cakey.pem -selfsign -extensions v3_ca  -infiles ./RCA/careq.pem
Using configuration from ./rca.cnf
Enter pass phrase for ./RCA/private/cakey.pem:
(設定したパスワード入力)
Check that the request matches the signature
Signature ok
(略)
CA certificate is in ./RCA/cacert.pem

>openssl x509 -in RCA/cacert.pem -out dist\rca.crt

以上で、クライアントに配布するルートCA証明書 dist\rca.crt ができました。

中間CAの作成

>perl ica.pl -newreq
Use of uninitialized value $1 in concatenation (.) or string at ica.pl line 133.
====
openssl req -config ./ica.cnf -new  -keyout newkey.pem -out newreq.pem -days 365
Ignoring -days; not generating a certificate
Generating a RSA private key
.+++++
...........................................................................+++++
writing new private key to 'newkey.pem'
Enter PEM pass phrase:
(パスワード設定)
Verifying - Enter PEM pass phrase:
(上記のパスワード再入力)

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

(上記の情報は適当に入力)

==> 0
====
Request is in newreq.pem, private key is in newkey.pem

>perl rca.pl -signCA
====
openssl ca -config ./rca.cnf -policy policy_anything -out newcert.pem -extensions v3_ca  -infiles newreq.pem
Using configuration from ./rca.cnf
Enter pass phrase for ./RCA/private/cakey.pem:
(ルートCAで設定したパスワード入力)

(略)
Certificate is to be certified until May 20 02:18:06 2022 GMT (730 days)
Sign the certificate? [y/n]:y

1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
==> 0
====
Signed CA certificate is in newcert.pem

>perl ica.pl -newca
CA certificate filename (or enter to create)
(newcert.pem と入力)

>move /Y newkey.pem ICA\private\cakey.pem
>openssl x509 -in newcert.pem -out ica.crt
>openssl x509 -in ICA/cacert.pem -out dist\ica.crt

以上で、中間CA証明書 ica.crt、クライアントに配布する中間CA証明書 dist\ica.crt が作成できました。

サーバ証明書の作成

>openssl genrsa -aes256 2048 > newkey.pem

Enter pass phrase:
(パスワード設定)
Verifying - Enter pass phrase:
(上記のパスワード再入力)

>openssl rsa -in newkey.pem -out newkey.pem
Enter pass phrase for newkey.pem:
(設定したパスワード入力)

>openssl req -new -key newkey.pem -out newreq.pem

Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:

A challenge password []:
An optional company name []:
(上記の情報は適当に入力)

ここでICAフォルダに適当な初期値を記載したserialというファイルを作成してください。そうしないと次のコマンドでエラーが発生します。

>perl ica.pl -sign
====
openssl ca -config ./ica.cnf -policy policy_anything -out newcert.pem  -infiles newreq.pem
Using configuration from ./ica.cnf
Enter pass phrase for ./ICA/private/cakey.pem:
./ICA/serial: No such file or directory
error while loading serial number
14392:error:02001002:system library:fopen:No such file or directory:crypto\bio\bss_file.c:69:fopen('./ICA/serial','r')
14392:error:2006D080:BIO routines:BIO_new_file:no such file:crypto\bio\bss_file.c:76:
==> 256
====

今回は '01' としました。

>type ICA\serial
01

serialが準備できたら以下を実行します。

>perl ica.pl -sign
====
openssl ca -config ./ica.cnf -policy policy_anything -out newcert.pem  -infiles newreq.pem
Using configuration from ./ica.cnf
Enter pass phrase for ./ICA/private/cakey.pem:
(中間CAで設定したパスワード入力)

(略)
Certificate is to be certified until May 20 02:46:12 2022 GMT (730 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
==> 0
====
Signed certificate is in newcert.pem

>openssl x509 -in newcert.pem -out server.crt

>move newkey.pem server.key

以上で、サーバ秘密鍵 server.key, サーバ証明書 server.crtが生成できました。

Nginxへ証明書を導入する

まずNginx導入用にサーバ証明書と中間CA証明書を一つの証明書にまとめておきます。

>type server.crt ica.crt > server-ica.crt

Nginx のコンフィグ

先程まとめた証明書をssl_certificateに、サーバ秘密鍵をssl_certificate_key に設定します。

server {
    listen 443 ssl;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    server_name test.tdomy.com;

    ssl_certificate ../cert/server-ica.crt;
    ssl_certificate_key ../cert/server.key;

    location / {
        root   html;
        index  index.html index.htm;
    }
}

設定したらNginxを再起動します。

確認

クライアントでの証明書のインストール

dist\rca.crt を[信頼されたルート証明機関]に、dist\ica.crtを[中間証明機関]にインストールします。

httpsでアクセスしてエラーがでなければOKです!

参考

Chromeに怒られないオレオレ証明書の作り方