してみるテストロゴ
Apache 2.4系でHTTP/2サーバを構築してみるテスト。

マルチアルゴリズム証明書の使い方

さて、当サイトでは前方秘匿性を確保するECDHE鍵交換と、サーバの負荷を下げられるECDSA鍵認証の組み合わせをご説明してきましたが、フィーチャーフォン用のサイトを含めて運用していると、フィーチャーフォンの多くがECDSAに対応していないため、証明書をRSAのものにしなければならなくなります。

つまり、RSAのサーバ証明書しか利用できないため、スマートフォン・PC向けにECDHE鍵交換-RSA鍵認証、フィーチャーフォン用にRSA-RSA(鍵交換・鍵認証ともにRSA)の組み合わせとなってしまい、ECDSAの恩恵を受けられません。

 

ところが、OpenSSL1.0.2では、一つのドメイン名(FQDN)に対して、複数の署名アルゴリズムを利用することもできます。

これをマルチアルゴリズム証明書と呼びます。

OpenSSL1.0.2とそれを使うApache Webサーバのインストール>>インストールするもの

この機能を使えば、RSAのサーバ証明書と、ECDSAのサーバ証明書を同時に利用することができます。

フィーチャーフォンには、Let's Encryptのルート証明書である、DST Root CA X3がインストールされている可能性は低いのですが、概念の説明と言うことで、Let's Encryptから、RSA対応サーバ証明書と、ECDSA対応サーバ証明書を取得して、同時にApache Webサーバで使用してみます。

異なる署名アルゴリズムのサーバ証明書の取得

今回は、1つのFQDNに対して、2枚の異なる署名アルゴリズムのサーバ証明書を取ります。

Let's Encrypt(ACMEプロトコル)を利用する都合なのですが、多くのACMEエージェントは、1つのドメイン名(FQDN)に対して、1つのアルゴリズムのサーバ証明書を取ってくる前提で設計されています。

当然、取得したサーバ証明書を配置するディレクトリも異なっていなければなりません。

そのためには、異なる2つのACMEエージェントを使って、片方はRSA、もう片方は、ECDSAを取得するために使うと、簡単に異なるディレクトリにサーバ証明書を配置できそうです。

今回は、letsencrypt-autoを使って、RSA対応のサーバ証明書を取得し、dehydratedを使って、ECDSA対応のサーバ証明書を取得します。

それぞれのインストールと使い方は、

RSA対応の証明書を取ってくるletsencrypt-autoのインストール>>Let's Encrypt(無償の証明書発行機関)から取得
ECDSA対応の証明書を取ってくるdehydratedコマンドのインストール>>dehydratedスクリプトの使い方やオプション

をご覧ください。上記リンクを参考に、それぞれ、サーバ証明書を取ってくるところまで、済ませてください。

letsencrypt-autoなら、以下のコマンドが成功すればOK。

# cd /usr/local/letsencrypt
# ./letsencrypt-auto certonly -t -d example.com  -a webroot --webroot-path=/var/http/example.com/htdocs/ --rsa-key-size 2048 --server https://acme-v01.api.letsencrypt.org/directory 
…(省略)…
-------------------------------------------------------------------------------
This is a PREVIEW RELEASE of a client application for the Let's Encrypt
certificate authority and other services using the ACME protocol. The Let's
Encrypt certificate authority is NOT YET ISSUING CERTIFICATES TO THE PUBLIC.

Until publicly-trusted certificates can be issued by Let's Encrypt, this
software CANNOT OBTAIN A PUBLICLY-TRUSTED CERTIFICATE FOR YOUR WEB SERVER.  You
should only use this program if you are a developer interested in experimenting
with the ACME protocol or in helping to improve this software.  If you want to
configure your web site with HTTPS in the meantime, please obtain a certificate
from a different authority.

For updates on the status of Let's Encrypt, please visit the Let's Encrypt home
page at https://letsencrypt.org/.
-------------------------------------------------------------------------------
(A)gree/(C)ancel:A	←良ければA+[ENTER]を入力

Enter email address (used for urgent notices and lost key recovery) (Enter 'c'to cancel):webmaster@example.com ←メールアドレスを入力
…(省略)…
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
   /etc/letsencrypt/live/example.com/fullchain.pem. Your cert
   will expire on 2016-XX-XX. To obtain a new version of the
   certificate in the future, simply run Let's Encrypt again.

dehydratedコマンドは以下のコマンドが成功すればOKです。

# cd /usr/local/dehydrated
# ./dehydrated -c -d example.com -a prime256v1
# INFO: Using main config file /usr/local/dehydrated/config.sh
+ Generating account key...
+ Registering account key with letsencrypt...
Processing example.com
+ Signing domains...
+ Generating private key...
+ Generating signing request...
+ Requesting challenge for example.com...
+ Responding to challenge for example.com...
+ Challenge is valid!
+ Requesting certificate...
+ Checking certificate...
+ Done!
+ Creating fullchain.pem...
+ Done!

です。

続いて、この2つの証明書をApacheの設定ファイルに追加します。

サーバの設定

さきほどの操作で、以下のファイルができていると思います。

 

RSAサーバ証明書ファイル(/etc/letsencrypt/live/example.com/cert.pem)

RSA秘密鍵ファイル(/etc/letsencrypt/live/example.com/privkey.pem)

RSA中間証明書ファイル(/etc/letsencrypt/live/example.com/chain.pem)

ECDSAサーバ証明書ファイル( /usr/local/dehydrated/certs/example.com/cert.pem)

ECDSAの中間証明書ファイル( /usr/local/dehydrated/certs/example.com/chain.pem)

ECDSAの秘密鍵ファイル( /usr/local/dehydrated/certs/example.com/privkey.pem)

 

二組もサーバ証明書と秘密鍵を登録して大丈夫?と思われると思いますが、前述の通り、OpenSSL1.0.2は証明書の出し分けに対応しています。

設定と言うほどの設定でも無いのですが、これをそのまま設定ファイルに追加すればOKです。

 

クライアントからの接続時のメッセージ(ClientHello)に、TLS extensionのservername(DNSのFQDN名)とsigalgs(RSA-SHA256とか,ECDSA-SHA256といったサーバ証明書のアルゴリズム)が指定されている場合、サーバ証明書のアルゴリズム別の出し分けが行われます。

指定されていない場合は、2つの内、RSAサーバ証明書がセッション確立の際に利用されます。

これによって、TLS extensionに対応していないフィーチャーフォンも、問題なくRSAサーバ証明書を利用することができます。

この動作については、次の、動作確認で見てみます。

 

ということで、httpd-ssl-vhosts.confに設定を追加します。

# vi /usr/local/apache2/conf/extra/httpd-ssl-vhosts.conf
/usr/local/apache2/conf/extra/httpd-ssl-vhosts.conf
<VirtualHost *:443>

	SSLEngine on

	SSLCertificateFile "/etc/letsencrypt/live/example.com/cert.pem"
	SSLCertificateKeyFile "/etc/letsencrypt/live/example.com/privkey.pem"
	SSLCertificateChainFile "/etc/letsencrypt/live/example.com/chain.pem"

	SSLCertificateFile "/usr/local/dehydrated/certs/example.com/cert.pem"
	SSLCertificateKeyFile "/usr/local/dehydrated/certs/example.com/privkey.pem"
	SSLCertificateChainFile "/usr/local/dehydrated/certs/example.com/chain.pem"

	DocumentRoot "/var/https/example.com/htdocs/"
	ServerName example.com:443
	ServerAdmin webmaster@example.com
    
	<Directory /var/https/example.com/htdocs>
		Options -Indexes
		AllowOverride All
		Require all granted
	</Directory>
	<FilesMatch "\.(cgi|shtml|phtml|php)$">
		SSLOptions +StdEnvVars
	</FilesMatch>
    
	ErrorLog "|/usr/local/apache2/bin/rotatelogs -l /var/log/https/example.com/error_log.%Y%m%d 86400"
	CustomLog "|/usr/local/apache2/bin/rotatelogs -l /var/log/https/example.com/access_log.%Y%m%d 86400" combined
	CustomLog "|/usr/local/apache2/bin/rotatelogs -l /var/log/https/example.com/ssl_request_log.%Y%m%d 86400" "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
    
    </VirtualHost>
  

さらにフィーチャーフォン用の暗号スイートを追加します。

今回は、DHE-RSA-AES128-SHA256と、AES128-SHAをフィーチャーフォン用と想定して追加しています。

# vi /usr/local/apache2/conf/extra/httpd-ssl.conf
/usr/local/apache2/conf/extra/httpd-ssl.confの一部
…(省略)…
SSLProtocol -All +TLSv1 +TLSv1.1 +TLSv1.2
SSLHonorCipherOrder on
SSLCipherSuite ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES128-SHA256:DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-SHA256:DHE-RSA-AES128-SHA256:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK
…(省略)…

設定の反映は、apachctl -tで、設定ファイルの間違いが無いこと(Syntax OKが表示されること)を確認の上、下記のように

# /usr/local/apache2/bin/apachctl -t
Syntax OK
# /usr/local/apache2/bin/apachctl stop
# /usr/local/apache2/bin/apachctl start

とします。

動作確認

証明書の署名アルゴリズムを選択する機能は、OpenSSL1.0.2以降が必要です。

インストールのところでも説明しましたが、自力でインストールしたOpenSSLを利用する場合、

$ source ~/.profile_ssl
Add /usr/local/ssl/lib.

として、OpenSSLのライブラリがインストールされている/usr/local/ssl/libを、ダイナミックリンクの対象とします。

 

まず、フィーチャーフォン(ガラケー)想定のコマンドから試します。

つまり、TLS extension無しで、接続します。

ガラケーが対応していると思われるTLSv1.0と、暗号スイート(ここではDHE-RSA-AES128-SHA)を指定してOpenSSLクライアントを動かします。

ターゲットの端末が、DHE-RSA-AES128-SHAに対応してねーよ、って場合は、たとえば、AES128-SHAをお使いください。

$ /usr/local/ssl/bin/openssl s_client -connect example.com:443 -tls1 -cipher DHE-RSA-AES128-SHA
CONNECTED(00000004)
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1
verify error:num=20:unable to get local issuer certificate
---
Certificate chain
 0 s:/CN=example.com
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
(…省略…)
-----END CERTIFICATE-----
subject=/CN=example.com
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
---
No client certificate CA names sent
Peer signing digest: SHA256
Server Temp Key: DH, 2048 bits
---
SSL handshake has read 3694 bytes and written 444 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES128-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES128-SHA
(…省略…)
    Timeout   : 300 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
---

Cipher is DHE-RSA-AES128-SHAと出れば、OKです。RSAの証明書が使われています。

続いて、TLS extensionのservername(DNSのFQDN名)とsigalgsを付けてみます。

sigalgs(署名アルゴリズム)には、 ECDSA+SHA256を、暗号スイートには、ECDHE-ECDSA-AES128-SHA256を設定します。

$ /usr/local/ssl/bin/openssl s_client -connect example.com:443 -servername example.com -tls1_2 -sigalgs ECDSA+SHA256 -cipher ECDHE-ECDSA-AES128-SHA256
CONNECTED(00000004)
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1
verify error:num=20:unable to get local issuer certificate
---
Certificate chain
 0 s:/CN=example.com
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
(…省略…)
-----END CERTIFICATE-----
subject=/CN=example.com
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
---
No client certificate CA names sent
Peer signing digest: SHA256
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 2862 bytes and written 308 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-ECDSA-AES128-SHA256
Server public key is 256 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-ECDSA-AES128-SHA256
(…省略…)
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
---

Cipher is ECDHE-ECDSA-AES128-SHA256と出ていればOKです。ちゃんと出し分けできています。

ちなみに、ECDHE-RSAについても試してみます。

sigalgs(署名アルゴリズム)には、 RSA+SHA256を、暗号スイートには、ECDHE-RSA-AES128-SHA256を設定します。

$ /usr/local/ssl/bin/openssl s_client -connect example.com:443 -servername example.com -tls1_2 -sigalgs RSA+SHA256 -cipher ECDHE-RSA-AES128-SHA256
CONNECTED(00000004)
depth=1 C = US, O = Let's Encrypt, CN = Let's Encrypt Authority X1
verify error:num=20:unable to get local issuer certificate
---
Certificate chain
 0 s:/CN=example.com
   i:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
 1 s:/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
   i:/O=Digital Signature Trust Co./CN=DST Root CA X3
---
Server certificate
-----BEGIN CERTIFICATE-----
(…省略…)
-----END CERTIFICATE-----
subject=/CN=example.com
issuer=/C=US/O=Let's Encrypt/CN=Let's Encrypt Authority X1
---
No client certificate CA names sent
Peer signing digest: SHA256
Server Temp Key: ECDH, P-256, 256 bits
---
SSL handshake has read 3268 bytes and written 308 bytes
---
New, TLSv1/SSLv3, Cipher is ECDHE-RSA-AES128-SHA256
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1.2
    Cipher    : ECDHE-RSA-AES128-SHA256
(…省略…)
    Timeout   : 7200 (sec)
    Verify return code: 20 (unable to get local issuer certificate)
---

Cipher is ECDHE-RSA-AES128-SHA256と出てますね。出し分けも問題なさそうです。

これで、フィーチャーフォン用のサーバ証明書と、スマートフォン・PC用の証明書を出し分けるマルチアルゴリズム証明書の運用ができます。

 

ちなみに、当サイトはECDSAとRSAの2種類の証明書に対応していますが、2016年度は以下のようなアクセスとなりました。

 

前述の通り、フィーチャーフォンには、Let's Encryptのルート証明書である、DST Root CA X3がインストールされている可能性は低いです。

そこで、スマートフォン・PC向けは、Let's Encryptから、ECDSAのサーバ証明書を取得して、フィーチャーフォン用のRSAのサーバ証明書は、有償の証明書発行機関から取得するというのが現実的です。

NEXT CASE:有償のサーバ証明書 >> 有償の証明書発行機関から取得

©Copyrights 2015-2023, non-standard programmer

このサイトは、あくまでも私の個人的体験を、綴ったものです。 軽く参考程度にご利用ください。