自堕落な技術者の日記

基本は喰ってるか飲んでるかですが、よく趣味でカラオケ・PKI・署名・認証・プログラミング・情報セキュリティをやっています。旅好き。テレビ好きで芸能通

DSA

世の中のDSAやECDSA公開鍵のサーバー証明書の利用状況

GoogleのCertificate Transparency (解説 [1] [2] [3]) のログデータベースはパブリックなHTTPSサイトに関する証明書のログデータベースなので、いろんな情報が取得できます。2015年3月27日時点で、6,949,166枚のSSLサーバー証明書に関する情報が格納されており、毎日1万枚以上増え続けています。これだけの枚数ですから、ここ数年有効な全世界のSSLサーバー証明書は網羅されているとして良いのかなと思います。以前紹介したgo.jpドメインのHTTPSサイトの調査もこの公開データをもとに調査しました。

本当は講演資料つくらないとマジでヤバイ感じなんですが、現実逃避して、ちょっと訳あってDSAやECDSA公開鍵のSSLサーバー証明書の利用、発行状況について調べてみたのでご報告を。そもそもはDSA公開鍵のSSLサーバー証明書を使っているDSSの暗号スイートなんて本当に使える公開サイトなんかあんのかって話を知りたかったわけです。

ほとんどの証明書はRSA公開鍵のSSLサーバー証明書であり、SSL Pulseの調査結果を見てもECDSAの証明書など割合からしてちょびっとな状況なわけですが、ログデータベースで見てみるとこんな感じです。(以下、2015年3月27日時点)

証明書枚数比率(%)
登録サーバー証明書(ログエントリ)の枚数6,949,166枚100%
うちECDSA公開鍵のSSLサーバー証明書の枚数398,841枚5.3%
うちDSA公開鍵のSSLサーバー証明書の枚数100枚0.0014%

念のため補足しとくと、DSA公開鍵のSSLサーバー証明書とはSubjectPublicKeyInfoフィールドにDSA公開鍵が格納された証明書の事を意味し、これを発行する認証局の鍵のアルゴリズムはRSAでもDSAでもECC(ECDSA)でも何でも構いません。SSLサーバー証明書のSubjectPublicKeyInfoのアルゴリズムにより、SSL/TLSで通信した場合の暗号スイートの認証や鍵交換が決まり、DSA公開鍵の場合にはDSSの暗号スイートが使用されます。ECC(ECDSA)証明書についても同じような感じです。

DSA公開鍵のSSLサーバー証明書

100枚の証明書のうち、さらに実際に接続してみて現在も利用可能なサイトを調べてみました。

証明書枚数比率(%)
登録サーバー証明書(ログエントリ)の枚数6,949,166枚100%
うちDSA公開鍵のSSLサーバー証明書の枚数100枚0.0014%
うち接続可能なDSA公開鍵のSSLサーバー証明書のサイト110.00016%
うちシマンテック以外のDSA公開鍵のSSLサーバー証明書のサイト30.00004%
いや〜、たった11サイトでしたよ。そのうち8サイトはドメイン名から シマンテックさんのテストサイトであることは明らかなので、一般のサイトは たった3つでした。DSA証明書を発行しているブランドは、 シマンテックさん以外は、Thawte、cacert.org、ips CAだけでした。 クライアントもサーバーもDSA公開鍵SSLサーバー証明書を使った DSS暗号スイートを使う可能性は殆ど無いと考えてよいんじゃないですかね。

ちなみに、Firefox 36、Chrome 41 でこのDSA証明書のサイトへアクセスしてみると、以下のように表示され、暗号スイートとしてそもそもサポートしていなかったり、信頼するルートに入っていなかったりで接続できません。OpenSSLのs_clientコマンドで接続するしかないわけです。
dsa-firefox2
dsa-chrome

ECDSA公開鍵のSSLサーバー証明書

ECDSA証明書については5%とそれなりに数はあるわけですが、 ちょっとドメインのリスト見てみると殆どcloudflaressl.comドメインばっかりなんですよ。

証明書枚数比率(%)
ECDSA公開鍵のSSLサーバー証明書の枚数398,841枚100%
うちcloudflaressl.comのECDSA公開鍵のSSLサーバー証明書の枚数398,262枚99.85%
うちcloudflaressl.com以外のECDSA公開鍵のSSLサーバー証明書の枚数569枚0.15%
誰かが、「全世界で数パーセントもECDSA証明書が使われてて純増していて、ECDSA証明書は段々流行りつつあるんですよ」なんて教えてくれた人がいたような気もするんですが、cloudflare以外では全世界でたった569枚しか売れてないんじゃないですか!!!ECDSA証明書はcloudflareさんが支えてたんですねぇ。しみじみ。

あ、そうそうGoogleでは*.google.comとかECCの公開鍵のSSLサーバー証明書を使っていてSSL/TLSで接続するとECDHE_ECDSAの暗号スイートになるんですが、その証明書の発行する認証局の鍵はRSAでSHA1withRSAで署名してるんですよね。「ChromeでSHA2移行をせかせる割には、お前はSHA1なんかいっっつ!!」みたいな。

おわりに

というわけで、全世界でどれくらいDSA証明書、ECDSA証明書が使われているのかを見てみました。結構興味深い事実もわかって個人的にはよかったかなと思います。オレはまだ本気出してないだけ。明日から講演資料作成頑張りまっすorz Certificate Transparencyについてはいろいろ深く突っ込んで調査しており、どこかで吐き出したいんですが、雑務に追われなかなかチャンスが無いなぁ。

OpenSSLコマンド入力例集

OpenSSLのコマンドって、オプションの種類が多すぎて少し離れているとすぐ忘れてしまったりするので別館で地味〜〜〜にまとめてみました。

今後もぼちぼち追加していきますのでよかったらご利用下さい。

OpenSSLで鍵生成した秘密鍵をJavaで使う

OpenSSLで生成したRSA/DSA秘密鍵は

今までずっと暗号化しないPKCS#8だと勘違いしていたんですが

PKCS#1の秘密鍵だったんですね。

#常識でしたか、、、、、(T_T)

Javaの

PKCS8EncodedKeySpecで読んで使おうと思ったら

できないんで、おかしいなぁと思って調べちゃいました。

ちなみにOpenSSLで生成したDSA秘密鍵

% openssl dsaparam -out aaa.prm 1024

% openssl gendsa -out aaa.prvkey aaa.prm

当たり前ですが、こんなASN.1構造です。

SEQUENCE {

INTEGER 0 -- version

INTEGER -- P プライム

INTEGER -- Q サブプライム

INTEGER -- G ベース

INTEGER -- Y 公開鍵

INTEGER -- X 秘密鍵 }

さらにはOpenSSLで生成したPKCS#1 RSA秘密鍵

% openssl genrsa -out bbb.prvkey 1024

ASN.1構造はこんな感じ。

SEQUENCE {

INTEGER 0 -- version

INTEGER -- n モジュラス(modulus)

INTEGER -- e 公開指数(public exponent)

INTEGER -- d 秘密指数 (private exponent)

INTEGER -- p プライム1 nの素因数 (prime1)

INTEGER -- q プライム2 nの素因数 (prime2)

INTEGER -- プライム1指数 (exponent1 = d mod (p-1))

INTEGER -- プライム2指数 (exponent2 = d mod (q-1))

INTEGER -- 中国剰余定理係数 (coefficient = (inverse of q) mod p) }

以上のPKCS#1フォーマットのRSA/DSA鍵はそのままでは

Javaでは読み込むことができない(と思う)ので

PKCS#8にくるんでやる必要があります。

OpenSSLのPKCS#1 DSA秘密鍵をPKCS#8に変換

秘密鍵を共通鍵暗号で保護しない平文形式の鍵に

変換するには以下のようにします。

% openssl pkcs8 -in dsa.prvkey -out dsa.prvkey.p8 -topk8 -nocrypt

すると生成されたPKCS#8のDSA秘密鍵は

SEQUENCE {

INTEGER 0 -- version

SEQUENCE {

OBJECT IDENTIFIER dsa (1.2.840.10040.4.1)

SEQUENCE {

INTEGER -- P プライム

INTEGER -- Q サブプライム

INTEGER -- G ベース

}

}

OCTET STRING, encapsulates {

INTEGER -- X 秘密鍵

}

}

}

ありゃりゃ、Yが無くなり、秘密鍵XがOCTET STRINGで

カプセル化されちゃったぞ。

OpenSSLのPKCS#1 RSA秘密鍵をPKCS#8に変換

同様にPKCS#1 RSA秘密鍵をPKCS#8に変換してみます。

% openssl pkcs8 -in rsa.prvkey -out rsa.prvkey.p8 -topk8 -nocrypt

すると生成されたPKCS#8 RSA秘密鍵のASN.1構造は

こんな感じ。

SEQUENCE {

INTEGER 0 -- version

SEQUENCE {

OBJECT IDENTIFIER rsaEncryption (1.2.840.113549.1.1.1)

NULL }

OCTET STRING, encapsulates {

SEQUENCE {

INTEGER 0

INTEGER -- n モジュラス

INTEGER -- e 公開指数

INTEGER -- d 秘密指数

INTEGER -- p プライム1

INTEGER -- q プライム2

INTEGER -- プライム1指数

INTEGER -- プライム2指数

INTEGER -- 中国剰余定理係数

}

}

}

AiCryptoのPKCS#8 DSA秘密鍵は?

Challenge PKI Test Suiteでは秘密鍵はどうなってるのか

ちゃんと見たことも無かったので見てみると保護されないPKCS#8になっていました。

この部分はOpenSSLと同じような暗号ライブラリAiCryptoの

PEM_write_p8()関数が使わています。

で、出力はこんな感じ。

SEQUENCE {

INTEGER 0 -- version

SEQUENCE {

OBJECT IDENTIFIER dsa (1.2.840.10040.4.1)

SEQUENCE {

INTEGER -- P プライム

INTEGER -- Q サブプライム

INTEGER -- G ベース

INTEGER -- Y 公開鍵

INTEGER -- X 秘密鍵

}

}

}

公開鍵Yがあったり、秘密鍵XがOCTETSTRINGでカプセル化

されていないところがOpenSSLとはちょっと違いますね。

AiCryptoのPKCS#8 RSA秘密鍵は?

同様にAiCryptoの生成したPKCS#8 RSA秘密鍵も見てみます。

SEQUENCE {

INTEGER 0 -- version

SEQUENCE {

OBJECT IDENTIFIER rsaEncryption (1.2.840.113549.1.1.1)

NULL }

OCTET STRING, encapsulates {

SEQUENCE {

INTEGER 0

INTEGER -- n モジュラス

INTEGER -- e 公開指数

INTEGER -- d 秘密指数

INTEGER -- p プライム1

INTEGER -- q プライム2

INTEGER -- プライム1指数

INTEGER -- プライム2指数

INTEGER -- 中国剰余定理係数

}

}

}

これは、OpenSSLの変換結果と全く同じ構造ですね。

PKCS#8ファイルをJavaで読み込む

読み込むのは以下のような感じになります。

byte[] p8 = PEMの内容を何らかの方法でbyte配列に

KeySpec keySpec = new PKCS8EncodedKeySpec(p8)

KeyFactory kf = null;

if (鍵がRSAなら)

kf = KeyFactory.getInstance("RSA");

else

kf = KeyFactory.getInstance("DSA");

PrivateKey pk = kf.generatePrivate(keySpec);

その鍵がRSAであるかDSAであるかはkeySpecからはわからないので

tryで適当にやってみるしか無いと思います。

OpenSSLやAiCryptoのPKCS#8がJavaで読めたか

実行結果をまとめたのが下表になります。

秘密鍵の生成方法Javaで読めるか?
DSA OpenSSL PKCS1→PKCS8読める
DSA AiCrypto PKCS8読める
RSA OpenSSL PKCS1→PKCS8読める
RSA AiCrypto PKCS8読める

なるほどなるほど、カプセル化の部分はきちんと吸収してくれるらしい。

しかしながら、DSAだろうが、RSAだろうが

PKCS#1だろうが、PKCS#8だろうが、PKCS#12だろうが

ファイル渡すとポッと秘密鍵が使えるものがあると有難いですね。

ううん、作っておこう、、、、

最新記事
Categories
Archives
Twitter
記事Google検索

本ブログ内をGoogle検索
Yahoo!アクセス解析
Travel Advisor
記事検索
QRコード
QRコード
  • ライブドアブログ