自堕落な技術者の日記

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

HPKP(HTTP Public Key Pinning)公開鍵ピニングについて考える

もくじ
1. はじめに
2. HPKPが生まれた背景
3. HPKPの仕組み
4. ピンの設定の考察
 4.1. ピンの値の取得方法
 4.2. 証明書チェーンに一致するピンの選択
 4.3. 証明書更新とHPKPヘッダの設定変更の運用方法
 4.4. バックアップピンという名前のイケてなさ
 4.5. CA鍵のバックアップピンのオススメの値
 4.6. 証明書チェーン中で複数ピンをつけても意味はない
 4.7. 同じCA証明書にPinし続ける場合の課題
 4.8. 2つのCA証明書にPinする場合の課題
 4.9. max-ageのオススメ値を考える
5. HPKPはどの程度使われているのか
6. 今のHPKPの何がいけなかったのか
7. おわりに
8. (参考) HPKP関連の勉強になるリンク

1. はじめに

HPKPとはHTTP Public Key Pinningの略で、RFC 7469 Public Key Pinning Extension for HTTPで規定されており、 ウェブサイトのオーナーが、ニセのサイトで意図しない証明書チェーンが使われないように保護するための仕組みです。

日本語解説は少ないですが、敬愛する jovi0608さんの記事Jxckさんの記事などでも解説されています。

私も3年ちょい前、IPAのガイドを書いていた前あたりから、HPKPの運用上の課題について、何かブログ等で書きたいと思っていたのですが、なんか日頃のヘンなことに忙殺されて、これまでまとめて書くことができませんでした。(なんか書こうと思ってたらjoviさんのが出ちゃって、まぁいいかと思っちゃったっていうのもありますw) IPAのガイドの時も書かせてもらおうとしたんですが、なんだか大人の事情で追加させてもらうことができませんでした。とほほ。

今回は、HPKPとは何かといった基本的なことは、他の方のブログに譲るとして、HPKPの現状やHPKPの運用上の課題についてフォーカスして書きたいと思っています。長くなりそうですが、ごめんなさいね。

結論から言えば、本番サイトで安易にHPKPを使うのはやめた方がいいと考えています。それは、HPKPの仕様自体が運用をしっかり考えて設計されておらず、一般的なサイトでは大したセキュリティ上の効果が無い割に、長期の運用でサービスを提供できなくなる期間が発生するリスクが高すぎるし、証明書のコストも余計にかかるからです。

おそらく、HPKPの運用について深く突っ込んでかいた、世界では初めての解説資料かなと思います。ご笑納くださいw

2. HPKPが生まれた背景

2011年頃から、認証局を対象にしたサイバー攻撃や、認証局の運用上の不備などで、攻撃に利用しやすいGoogleやFacebookといった有名サイト向けのワイルドカード証明書(*.google.com等)を取得されてしまうという事件が増えてきました。Googleを怒らせちゃったのは2011年のオランダの認証局DigiNotarが不正侵入を受け、*.google.comのワイルドカード証明書を発行され、イランのプロバイダの盗聴や攻撃に使われたという事件がありました。
hpkp-digi
このような事件を防ぐためには、ウェブサイトに対して、サイトオーナーの意図しない証明書が使われた場合に、警告を発する仕組みが必要です。そこで開発されたのが、HPKPです。HPKPでは、証明書チェーンの証明書公開鍵のハッシュの一致を確認することにより、ウェブサイトオーナーの意図した証明書かどうか検証することができます。
hpkp-hpkp1
joviさんのブログの1章で背景と仕組みをわかりやすく解説されているので、そちらもご覧頂ければと思います。

3. HPKPの仕組み

HPKPの実装方法には2つの方法があります。

  • 1) Google、Facebook、Twitterなどの有名サイト向けの、ChromeFirefoxなどブラウザに組み込まれたピンのリスト(Preloaded Known Pinned Host List)と照合する方法
  • 2) HTTPSで通信する際に、サーバーからピン情報のHTTPヘッダを取得し、それをブラウザに保管しておき、以降の通信で照合に使う方法
1) の方法は、ブラウザを最新になっているならば何も設定しなくても、有名なサイトについてはHPKPを使って安全に接続することができます。今回の記事で議論したいのは2)のサイトオーナーが設定する場合についてなので、2)の仕組みについて説明します。
hpkp-sethead
ウェブサーバーに不正な証明書チェーンに接続させないためのHPKP HTTPヘッダを設定するのですが、これはウェブサーバーのHTTPS設定で使用するルート証明書からSSLサーバー証明書までの証明書チェーンを元に設定します。HTTPヘッダとその値の書式は以下のようになっています。
Public-Key-Pins: \   pin-sha256="チェーン中の公開鍵のどれかのSHA256ハッシュ値のBase64"; \   pin-sha256="チェーン中の公開鍵のどれにも一致しないSHA256ハッシュ値のBase64"; \   [pin-sha256="その他ハッシュ値1"; ...; ] \   max-age=ブラウザにこのHPKPヘッダが保管される秒数; \   [includeSubDomain;] \    サブドメイン(example.comならsub.example.com)もHPKPの対象にするか   [report-uri="JSON形式のエラーレポートがPOSTされるURL"; ] [...]はオプション
  • pin-sha256は証明書チェーンを元に設定しますが、その設定方法や考察については後で述べます。
  • max-ageの保存期間はRFCの4.1節で考察しており60日(=5184000秒)が良いのでは?としていますが、その考察も後で述べさせて下さい。
  • includeSubDmainは、サブドメインまで含めるか、例えば example.com にHPKPを設定したら、sub1.example.comも、www1.sub2.example.comもHPKPの対象にするというフラグです。現時点で持っていないなら安易に設定しない方が良いように思います。
  • HPKPは、CSPなどと同様ににブラウザ側で検証するので、サーバー側にはエラー原因が把握できず困ることがあります。report-uriを使えば、ブラウザでHPKPのエラーが発生した際に、指定したURLのウェブサーバーにJSON形式のエラーレポートをPOSTすることで送信しますので、設定上の問題を知るのに役立つかもしれません。Jxckさんのブログで設定を試してみたという詳しい報告がされているのでご覧になると良いでしょう。ブログでも書かれていますが、レポートが出力される条件がよくわからず、ブラウザやバージョンにも依存するようで、私もレポート生成がうまくできていません。
また、HTTPヘッダについて "Public-Key-Pins" ではなく、"Public-Key-Pins-Report-Only" と設定すれば、ブラウザではエラーを発生させることなく、エラーレポートの収集はできますので、テストの際にこれを使うと良いでしょう。

4. ピンの設定の考察

pin-sha256属性を使ってピンを設定することにより、サーバーオーナーが意図しない証明書が使われることを防ぐことができます。 ピンの値は、証明書チェーンの証明書の何れかの証明書に一致するものを最低一つ、 どれにも一致しないものを最低一つの計2つ以上により構成されます。
hpkp-intersect

4.1. ピンの値の取得方法

さて、一番簡単なハッシュ値の取得方法ですが、すでにウェブサーバーのHTTPS設定が完了しているならば、Scott Helme氏のHPKPハッシュの所得ページを利用するのが良いです。自分のでも他人のでもHTTPSサイトのURLを入力すれば、証明書チェーンの各証明書のピンのハッシュ値を計算してくれます。
index
SSLサーバー証明書から順にルート証明書まで、ピンのハッシュ値が

pin-sha256="hUIG87ch71EZQYhZBEkq2VKBLjhussUw7nR8wyuY7rY="
のように表示されますので、どのピンを使うのかを決めてHTTPヘッダに設定するだけです。

一つのピンのハッシュ値の計算ですが、証明書からでも、証明書発行要求(CSR/PKCS#10)でも、 秘密鍵と鍵アルゴリズムによっては鍵パラメーターから抽出されたPKCS#8公開鍵からでもハッシュ値を計算することができます。 ただ、いろんな人のブログでは、わざわざCSRを作ってからハッシュ値を計算しているようですが、特に証明書のまだ無いバックアップピンの場合には、 そんなことをしなくとも、公開鍵からハッシュ計算するのが良いように思います。 先ほどと同様に、Scott Helme氏のツールでPEM形式のPKCS#8公開鍵、CSR、X.509証明書を入力すれば、ピンのハッシュ値を計算してくれるページがあるので、これを使うのが簡単です。

手作業でピンを取得する場合には、以下を実施すれば公開鍵のSHA256ハッシュであるピンの値が取得できます。他の解説記事では、base64コマンドを使ったり、CSRをいちいち生成するのを強制させたりしているようですが、ここで紹介する方法はOpenSSLコマンドしか使わず、いろいろなケースに対応して、ピンの取得ができるように、例を示しておきました。

X.509証明書からsubjectPublicKeyInfoフィールドにあるPKCS#8公開鍵のピンの入手 % openssl x509 -in PEM証明書 -pubkey -noout | openssl rsa -pubin -outform DER | \ openssl dgst -sha256 -binary | openssl enc -base64 te4kc4F/5BhtIosKLOS9sy049x7a/LQHNRRG1WHfvyU= CSRからsubjectPKInfoフィールドにあるPKCS#8公開鍵のピンの入手 % openssl req -in PEMCSRファイル -pubkey -noout | openssl rsa -pubin -outform DER | \ openssl dgst -sha256 -binary | openssl enc -base64 te4kc4F/5BhtIosKLOS9sy049x7a/LQHNRRG1WHfvyU= PKCS#8秘密鍵からピンの入手 % openssl rsa -in PKCS#8秘密鍵 -pubout -outform DER | \ openssl dgst -sha256 -binary | openssl enc -base64 te4kc4F/5BhtIosKLOS9sy049x7a/LQHNRRG1WHfvyU= PKCS#8公開鍵からピンの入手 % openssl rsa -pubin -in PKCS#8公開鍵 -pubout -outform DER | \ openssl dgst -sha256 -binary | openssl enc -base64 te4kc4F/5BhtIosKLOS9sy049x7a/LQHNRRG1WHfvyU= 得られた値を pin-sha256="te4kc4F/5BhtIosKLOS9sy049x7a/LQHNRRG1WHfvyU=" のようにヘッダに設定する。
値を取得したら、ウェブサーバーのHTTPヘッダに設定します。例えば、Apache HTTP Serverの場合には、以下のように設定します。
<VirtualHost _default_:443> ... Header set Public-Key-Pins \ "pin-sha256=\"MRnxhYBVCMAxZHwalTJ7ZVl6P2005lll4ttWr+RN1Ro=\"; \ pin-sha256=\"633lt352PKRXbOwf4xSEa1M517scpD3l5f79xMD9r9Q=\"; \ max-age=2592000; \ report-uri=\"https://report.example.com\"" ... 読みやすさのためにバックスラッシュと改行を入れています。2592000秒は30日です。

4.2. 証明書チェーンに一致するピンの選択

HPKPでは、証明書チェーンに一致するピンを1つ以上設定する必要があります。本節では、次の2つに分けて考察してみたいと思います。

  • 1) 証明書チェーン中のどれか一つのみを選択する場合の比較検討
  • 2) 証明書チェーン中の2つ以上、または全部を選択する場合の考察

4.2. 証明書チェーンに一致するピンの選択

証明書チェーンで、SSLサーバー証明書、中間CA証明書、ルート証明書のような3段の証明書になっている場合、 不正な意図しない証明書チェーンになっていないかどうか検証するために、 どれか一つのピンを選ぶとすれば、どれを選べば良いでしょうか。 これら3つのケースで、それぞれ長所、短所があるので、考察してみたいと思います。 SSLサーバー証明書については、数年後証明書更新の際に使用する鍵ペアがあらかじめ決まっている場合(=鍵事前生成)、決まっていない場合(=鍵事前生成なし)のケースに分けて考察します。

証明書長所短所安全性運用負担
.襦璽CA証明書
  • 有効期間が長いためピン変更の頻度が少なくて済む。おそらく10年程度は変更不要
  • ブラウザ組み込みのプリロードピンではルート証明書を使用
  • 鍵更新後の公開鍵は事前にはわからずバックアップピンは使えない
  • 新しいSSLサーバー証明書を購入した場合に、同じルート認証局とは限らず、その際はピンの移行が必要
  • ルート証明書配下の証明書の数は非常に多く、その認証局が不正な証明書を発行された場合に、攻撃を防げないリスクは高い。例えば、シマンテック社がGoogleに許可なくGoogleの証明書を発行する事件があった。
  • 証明書更新でルートCAが変更になる可能性は低いが、変更になった場合には、max-ageに配慮した面倒な移行が必要で運用負荷が高い
中間CA証明書
  • 有効期間がやや長いためピン変更の頻度が若干少なくて済む。おそらく5年程度は変更不要
  • 安全性と運用負担の面でバランスが取れているか?
  • ピンする中間CAの公開鍵に変更がなかった場合のSSLサーバー証明書の更新は比較的楽
  • ピンしている中間CAの公開鍵が、次回のSSLサーバー証明書更新時に同じであるという保証はない。
  • SSLサーバー証明書の更新時に、中間CA証明書が変更になるリスクがあるが、それが事前 周知されないために、SSL接続不具合によるサービス停止リスクが高い
  • 中間CA証明書が変更になった場合の移行に係る運用負担は、回数も、作業負荷も 非常に高い
  • 同じ中間CAから、不正に同じドメインに対する証明書が発行された場合にも検証有効となってしまうリスクがある。,茲蠅魯螢好は低いが、い茲蠅蝋發
  • 証明書更新で中間CAが変更になる可能性はある程度あり、,茲蠅漏領┐高い。変更になった場合には、max-ageに配慮した面倒な移行が必要で運用負荷が高い
SSLサーバー証明書(鍵事前生成)
  • SSLサーバー証明書の更新時に、ピンした公開鍵のマッチング設定に失敗する可能性が低く、HPKP設定不備によるサービス停止のリスクは最も低い
  • HPKPのRFCでは、(さらっと簡単にできると取れるような記述がされており)推奨されているように取れる方法
  • 不正証明書チェーンが使われるリスクは、(秘密鍵漏洩のリスクを除けば)い汎営度に、´△茲蟾發
  • 証明書更新の前後で、変更されるピンがあらかじめわかっているので、(max-age内に再度証明書更新をすることをしなければ)max-ageをあまり気にせずに証明書の更新ができる
  • SSLサーバー証明書の更新時に、鍵ペアの事前生成が可能なのは、OpenSSL等により手作業で鍵ペア生成した場合のみであり、証明書の発行時に、CSRを自前で生成する必要がなく、ブラウザのコンポーネントで自動的に鍵ペア生成するような証明書発行サービスの場合には、本方式は使えない
  • Let's Encryptは使えず、SSLサーバー証明書自動更新に係る運用負担の軽減は見込めない
  • 鍵ペアは一般に、証明書の更新時に行われるものだが、それを2年程度前に実施することになる。事前生成しておくと、その分、SSLサーバー証明書の秘密鍵が漏洩するリスクは高く、機密保管の運用負担は大きい
  • 証明書の更新時には、それなりに設定変更に気を使う必要がある。また、その回数も2年弱程度おきであり、運用負担は比較的高い
SSLサーバー証明書(鍵事前生成なし)
  • 全てを自己制御でき、設定不備によるサービス停止リスクはと同程度に高い
  • に比べてSSLサーバー証明書の秘密鍵が漏洩するリスクも低い
  • 不正証明書チェーンが使われるリスクは、(秘密鍵漏洩のリスクを除けば)い汎営度に、´△茲蟾發
  • SSLサーバー証明書を使える期間が、必ず (max-age + α)×2 分だけ減る。2年物証明書の場合、max-ageを2ヶ月とした場合、テストや余裕も含め4〜5ヶ月程度は短くなることになり、証明書の費用負担が増える
  • 証明書更新の前後で証明書の有効期間をmax-age+αでオーバーラップさせれば、必ずmax-ageに配慮しながらピンの変更を行うことになる。運用の負担はあるが、ピンが変更になるか認証局次第でどうなるかわからない´△鉾罎戮董必ずmax-ageに配慮した、証明書更新、HPKP設定変更のスケジュールが組めるので、定型運用にできるため運用の心理的負担は´△茲蠅麓禊馨ない
  • では、 銑い任蓮何を選択するかですが、ブラウザ組み込みのピンが使えない一般サイトの場合は、 ◆銑のいずれかが妥当だと思いますが、どれも運用の負担や、サービス提供不能になるリスクがあり、 個人がテスト目的で設定する場合は何でも良いとして、 自分が商用サイトの運用を任されているならば、もっとも懸念すべきは 長期間サービス提供不能になりクレームが起きることなので、 HPKPは使わないという判断をすると思います。

    4.3. 証明書更新とHPKPヘッダの設定変更の運用方法

    4.2節では、証明書チェーンのどこにピンを設定するかで、 どのような違いがあるのかについて考察しました。

    本節では、4.2節の考察を受けて、設定不具合によるサービス利用不能を 防ぎながら、HPKPを使ったサイトの証明書更新、HPKPヘッダの変更を、どのように運用すればよいのかについて 考察します。

    HPKPを使った場合の証明書更新の運用の仕方は4つのケースにわけることができます。

    • a)証明書更新のmax-ageより前に確認し、ピンを行っている鍵に変更がない場合
    • b)証明書更新のmax-ageより前に証明書更新の前後でピンを行う公開鍵が何に変更されるかわかっている場合
    • c)証明書更新のmax-ageより前に証明書更新の前後でピンを行う公開鍵が何に変更されるかわからない、もしくは変更が明らかだが、更新の前後の証明書の有効期間をmax-age + αオーバーラップできる場合
    • d)証明書更新のmax-ageより前に証明書更新の前後でピンを行う公開鍵が何に変更されるかわからない、もしくは変更が明らかだが、更新の前後の証明書の有効期間をmax-age + αオーバーラップできない場合
    このような説明では、具体的なイメージがわかないと思いますので、証明書チェーン中の証明書に分けて具体例を示してみましょう。
    • a-1) ルート証明書や中間CA証明書にピンを設定しており、顧客サポートに問合せたら、次回、max-age後の証明書更新では、使用するルート証明書、中間CA証明書には変更がないことがわかった場合。(顧客サポートに嘘をつかれたら、一部ユーザに2ヶ月(=max-age)サービス障害になるリスクあり。)
      hpkp-move1
    • b-1) ルート証明書や中間CA証明書にピンを設定しており、顧客サポートに問合せたら、次回、max-age後の証明書更新では、使用するルート証明書、中間CA証明書がどれに変更されるか教えてもらえた場合。もしくはサポートページなどで告知されている場合。証明書発行サービスの変更、EVへの変更なども同様。
      hpkp-move-b1
    • b-2) SSLサーバー証明書にピンを設定しており、OpenSSL等で次回の証明書更新で使用する鍵ペアがすでに事前生成され、保管されている場合
      hpkp-move-b2
    • c-1) ルート証明書や中間CA証明書にピンを設定しているが、次回証明書更新後のルート証明書、中間CA証明書の変更について、顧客サポートからの回答が得られず、変更されるかどうか判断がつかないため、仕方なく、証明書更新をmax-age + α前に実施して有効期間を重ねるよう事前証明書発行したら、やはりルート証明書、中間CA証明書は変更になっていた場合(変更がなければa-1のケースとなる。)
      hpkp-move-c1
    • c-2) SSLサーバー証明書にピンを設定しているが、OpenSSLを使わず、ブラウザの機能で鍵ペア生成するタイプの認証局であるため、事前に更新後の公開鍵はわからず、証明書更新をmax-age + α前に実施して有効期間を重ねるよう事前証明書発行できる場合
      hpkp-move-c2
    • c-3) SSLサーバー証明書にピンを設定しているが、HSM機能を使うSSLアクセラレーターを使っており、事前に更新後の公開鍵はわからず、証明書更新をmax-age + α前に実施して有効期間を重ねるよう事前証明書発行できる場合。移行の図はc-2と同じになります
    • d-1) SSLサーバー証明書にピンを設定しているが、Let's Encryptや一部の認証局のように、証明書更新後、前の証明書は即時に失効処理がされ、max-age + αの期間の有効期間のオーバーラップができない場合
      hpkp-move-d1
    自分の運用がどのケースにあてはまるか、上記の説明でわかったでしょうか。さて、a〜dのケースで、どのように対応するかを以下に示します。
    • aの対応) 証明書更新に際し、ウェブサーバーのHPKPヘッダの設定は変更しなくてよい
    • bの対応) max-ageをはあまり気にせず、証明書更新後の、ウェブサーバーの証明書設定、HPKPヘッダを設定変更してよい
    • cの対応) もっとも神経を遣う、max-ageに配慮した、証明書更新、HPKPヘッダ設定が必要。証明書の更新の前後で、有効期間のオーバーラップが必要
    • dの対応) このケースではHPKPは使えない。他の証明書、証明書発行サービスへのピン設定の変更を検討する必要がある。使っても、一部ユーザにサービス接続不能障害がmax-age程度発生する。
    どんな証明書更新、HPKPヘッダ設定の移行を行うにしても、証明書の有効期限、max-age、秘密鍵の保管など、様々なことに気を遣いながら、移行計画を立て、移行しないとならず、きちんと考えないと長期のサービス障害発生するという運用上の負担やリスクは大きいと思います。

    4.4. バックアップピンという命名のいけてなさ

    先に述べたように、何か一つ、証明書チェーンとはマッチしないピンを必ず含めなければいけません。SSLサーバー証明書にピンをする場合は、現在使っているSSLサーバー証明書の秘密鍵に対して、将来、証明書更新で使う予定の秘密鍵も事前に生成しておけるなら、その公開鍵をバックアップピンとして設定しておけば、まさしくバックアップとして使用でき、(後述の問題ありありですが)スムースな証明書とピンの移行が可能です。

    しかしながら、秘密鍵を移行先のバックアップとして事前生成しておき、これが利用できるというケースはレアケースです。例えば以下の一般に起こりうるケースでは、証明書更新の際に、その事前生成した秘密鍵を使用することはできません。

    CA証明書のバックアップPin
    認証局が行う証明書更新もしくは鍵更新において、事前に移行先の秘密鍵が存在するということもありませんし、移行先の公開鍵のPinをユーザに公開してくれる認証局もありません。
    HSMを使っている場合のバックアップ
    認証局やSSLアクセラレーターを使っているケースでは、秘密鍵を取り出し不可能なハードウェアセキュリティモジュール(HSM)で管理するのが一般的です。HSMを使用した鍵更新、証明書更新では、事前に秘密鍵を幾つか生成しておき、更新時にそれを指定して更新に使用するということができません。更新時には、新たに鍵ペアを生成して、これを使用します。このために、認証局ではバックアップPinを公開することができないのです。
    ウェブ画面で鍵ペア生成してSSLサーバー証明書発行する認証局の場合
    認証局によっては、ウェブブラウザの機能を使用して、ボタンを押せば自動で鍵ペア生成を行い、これを用いて証明書を発行し、新しい証明書を格納するものがあります。そのような認証局では、事前に生成しておいた鍵を発行時に使用するということができません。
    Let's Encryptを使う場合
    無料で世界一の発行数を誇る証明書発行サービスであるLet's Encryptでは、証明書の発行プロセスがスクリプトにより自動化されていますが、これも証明書の更新時には自動で鍵ペア生成されるので、事前に生成していた鍵ペアを使用することができません。
    本当の意味での「バックアップPin」が使えるのは、以下の場合にのみ可能であるということです。
    • SSLサーバー証明書に対してPinをする場合で、かつ、
    • OpenSSLなどのコマンドで鍵ペア生成し、マニュアルで証明書発行要求を生成して、証明書発行してもらえる認証局を使用する場合
    従って、証明書チェーンにマッチしないものを、「バックアップPin」と呼ぶのは、上述のほとんどのケースで適切でないので、名称には問題があると考えています。

    4.5. CA鍵のバックアップピンのオススメの値

    ルート証明書や中間CA証明書にピンを設定する場合、 一致しないピンは、将来の更新先がわからない場合には何でもよく、 さらには、本物の公開鍵のハッシュである必要もありません。 SHA256なので、単に32バイトの値であれば何でも良いわけです。

    ただ、HPKPヘッダで一見して一致しないピンだとわかったほうが、 誤って削除するなどの運用ミスを防ぐ意味でも良いと考えており、 そこで、オススメしたいのが、以下の値です。

    pin-sha256="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; これは、16進数で 0000000000000000000000000000000000000000000000000000000000000000 (32バイト)
    となります。流行るといいなと思っていますw

    4.6. 証明書チェーン中で複数ピンをつけても意味はない

    これまで、証明書チェーンと一致するピンの数は1つを前提に議論してきましたが、 これを複数、例えば、ルート証明書と、中間CA証明書と、SSLサーバー証明書のピンを一致させた場合には、 どうなるのかを考察したいと思います。

    まず、SSLサーバー証明書にピンを打って、次に中間CA証明書、次にルート証明書のピンを追加していく ことを考えてましょう。 同じ鍵ペアを複数の認証局からのサーバー証明書発行で使用しないという、当たり前の事を前提とします。 SSLサーバー証明書にピンを打つ事が最も、範囲が限定的でニセHTTPSに対する 最も強い対策であると、4.2節で述べました。

    そこに中間CA証明書の一致するピンを足してみたらどうでしょうか。ピンで特定する証明書の範囲は全く変わりませので、中間CA証明書のピンを足すことで、ニセHTTPSサイト作りが難しくなったりはせず、セキュリティの強度も上がりません。また、運用面では、ピンの一致の配慮がピン一つと比べて難しく、また、ウェブサイトオーナーだけで管理できない範囲となるので証明書やピンヘッダ変更の運用は格段に複雑で面倒になります。これに対し、ルート証明書のピンを加えた場合でも全く同じことです。セキュリティ強度は上がらず、移行の運用は複雑になるのです。
    hpkp-multipin

    従って、証明書チェーン中で複数のピンをつけても意味がなく、かえって運用が複雑になるだけなので、止めたほうがよいということが言えます。

    4.7. 同じCA証明書にPinし続ける場合の課題

    今後当面は、同じルート認証局、中間認証局から発行してもらう場合に、その認証局の証明書の公開鍵にPinすることができます。その場合には、バックアップPinは、認証局から移行先のPinを教えてもらえるわけではないので、なんでも適当な値で良いことになります。公開鍵のハッシュである必要もなく、32バイトの値のBase64表現であれば(衝突しなければ)何でも良いことになります。

    ただし、「当面は」と書きましたが、SSLサーバー証明書を発行する使用していた中間認証局が、次の証明書発行時にも同じ中間認証局、同じ公開鍵であるという保証がありません。以下の理由により、同じ中間CA証明書が使われない可能性があります。

    • 中間CA証明書の有効期限は、5年から10年程度です。その有効期限の半分程度から、最長でも2、3年を残して、その中間認証局からは証明書が発行されなくなり、利用者は別のCAから証明書を発行してもらうようになります。
    • 証明書の発行数枚数が多くなると、それだけ、証明書失効リスト(CRL)のサイズも大きくなりますので、一つの中間CAから発行枚数を制限して、以降の証明書発行は、新しい中間CAから発行させるケースがあります。
    • 近年、認証局の運用上の不備、サイバー攻撃などから証明書発行サービス全体や、特定の中間CAが運用停止、サービス終了になることがあります。
    このような場合には、同じ中間CAのPinを使うことができません。

    有効なPinを設定した同じルートCAもしくは中間CAから、新しい証明書が発行してもらえないとわかった際に、別の証明書の移行は、すぐにはできず、max-ageで指定した期間、一般には1ヶ月から1年程度は、証明書の入れ替えができません。最悪の場合、その期間、有効なHTTPS通信ができないという事もありえます。

    このような影響を、軽減する方法が無いわけではありません。証明書を更新すると判断し、同じ中間CAから証明書が発行できないとわかった時点Aで、そこからmax-age経過した時点Bを記録しておき、新しい証明書を取得します。(が使いません。)。バックアップPinとして、その新しい証明書の別の中間CA証明書の公開鍵のPinをウェブサーバーのヘッダに設定します。時点Bになって、初めて新しい証明書への入れ替えを実施します。この事から、max-ageを1年等、長くとれば偽サイトの防止には役立ちますが、今述べたような証明書更新のリスクもあり、半月から1ヶ月程度に設定するのが妥当なように思います。

    4.8. 2つのCA証明書にPinする場合の課題

    SSLサーバー証明書の更新の際に、2つの証明書発行サービス、例えばSymantecとGlobalSignを交互に乗り換えるとして、これら2つの中間CA証明書のPinをヘッダに設定し、使用してないない方をバックアップPinとするのは、なかなか賢い方法だと思います。
    hpkp-two

    しかしながら、前述の理由により、Symantecの次に発行してもらおうと予定していたGlobalSignの中間CA証明書のPinが使えないケースがあります。

    以上のように、CA証明書にPinを打つケースでは、証明書発行サービスの気まぐれにビクビクしながら、ウェブサーバーのHPKPを運用するのはとても面倒だと思いませんか? それなら、まだ、自分でコントロールできるSSLサーバー証明書にPinを打つ方が、面倒でも良いような気もしてきます。

    4.9. max-ageのオススメ値を考える

    RFC 7469 4.1節の セキュリティ考察において、max-ageの最大値について以下のように記載されており、 「60日がバランスの取れた値かもね」と言っています。

    RFC 7469 4.1. Maximum max-age より
    However, a value on the order of 60 days (5,184,000 seconds) may be considered a balance between the two competing security concerns.
    ただ、5章のScott Helme氏のHPKP対応ドメインリストに基づいた私の調査では、 まともな運用をしている設定の中では、 30日が26%、次いで60日が19%と多いです。

    max-ageの値が長すぎると、

    • 設定ミスによる障害発生時に長期間接続できないユーザが出てしまう
    • 有効期間のオーバーラップが必要な場合、実質的な証明書有効期間が目減りして運用コストに影響する
    というリスクについて、4.2節で説明させて頂きましたが、 逆に、max-ageが短すぎるとどうなるのでしょうか?

    簡単には、ニセのHTTPSサイトに乗っ取られる可能性が高くなるという事かと思います。 本物サイトのmax-ageが短くて、有効期限が切れたタイミングで、ドメイン乗取り等の被害にあって 偽サイトが作られ、そこで1年等長いmax-ageのHPKPヘッダ対応のニセサイトが作られたとすると、 一度そのようになれば、当面1年間は、ニセサイトにしか繋げないようなユーザが発生することがあります。
    hpkp-maxage
    max-ageが短いと、それだけ攻撃のチャンスは増えるため、max-ageはある程度長くしておく必要があります。

    様々な情報ソースから、 ニセサイトを作られていたと気づくまでに、それほど時間はかからないと思います。 数日から1週間もあれば問題に気づくと思います。 半月や1ヶ月も気づかないままいる事はないでしょう。 「ニセHTTPSサイト問題に気づくまでに遅くともどれくらいかかるか」によって max-ageの最小値を決めるのがよいと思います。

    従って、攻撃と可用性のリスクのトレードオフで、私はmax-ageを15日か30日程度に 設定するのが良いように思っています。

    5. HPKPはどの程度使われているのか

    2016年3月のNetcraft社のSSL利用調査によれば、世界でわずか0.09%の4100サイト以下ぐらいしか、HPKPを設定しておらず、設定の誤りも多いそうで、正しく設定できているのは、そのうち3000サイト程度なのだそうです。

    また、CSP(Content Security Policy)やHPKPに詳しく、HPKPの検証やレポート先サイトを運営しているScott Helme氏のブログによれば、Alexa上位100万のサイトのうちHPKPを設定しているのは、わずか375サイトであったという報告もあります。

    Scott Helme氏は、調査の際のデータも公開しており、2016年8月時点でのHPKP対応サイトのドメイン名リスト448件があったので、それをベースに2017年2月現在でもHPKPヘッダを返すサイト283件に対して少し調査してみました。

    hpkp-graph1
    まず、HPKPヘッダとして正しいフォーマットになっているか、また、仕様上PINのハッシュ値は2つ以上必要ですが、2つ以上あるかという観点で、ヘッダがどの程度正しいかを調べました。16%は設定が正しくないことがわかりました。間違っているものの中には、pin-sha256属性が無い、pin-sha256の値が不適切、pin-sha256属性が一つしかない、など様々です。例えばこんなものがありました。
    • ...
    • pin-sha256="base64+info1="; max-age=3
    hpkp-graph2
    次に、HPKPヘッダのPINのハッシュ値の個数です。一般にはPINのハッシュ値は2つで十分で、2つとなっているサイトが多く占めますが、1個しかない誤ったサイトや、3つ以上を設定しているサイトも相当数あります。15個設定しているという猛者もありました。
    hpkp-graph3
    HPKPで有効な公開鍵ハッシュの保存期間を定めているのが、max-ageの値です。RFCでは、60日を推奨しているようですが、実際には30日を設定するサイトが多いとわかります。また、テスト中なのか1日以下にしているサイトも相当数あります。短いとサイトを乗っ取られる可能性が高まりますし、長すぎると設定に失敗した場合その期間接続不能になってしまいます。1年などと設定すると、設定失敗していたら1年間接続できないユーザーが出てクレーム確実なのに恐ろしいですね。
    hpkp-graph4
    report-uriを設定すると、対応ブラウザならば、HPKPのエラーの際に指定したURLにレポートを送ることができます。Jxckさんのサイトでは設定されているそうですが、まだまだ設定しているサイトは少なそうです。
    hpkp-graph5
    HPKPヘッダの値には、includeSubDomainというプロパティをつけることができます。これをつけるとexample.comにHPKPを設定しておけば、sub1.example.comドメインに対しても適用されるようになります。
    hpkp-graph6
    HPKPヘッダとして、通常は"Public-Key-Pins"を使いますが、"Public-Key-Pins-Report-Only"を使えば、ブラウザはHPKPを検証せずに、エラーとなってもHTTPS接続は続けられるテスト用の機能があります。約10%のサイトがこのテスト用の設定を使っているとわかります。
    hpkp-graph7
    Scott Helme氏の2017年時点で接続可能なHPKP対応サイト283件のうちgTLD(com、org等)、ccTLD(de、ru、jp等)別に件数を調べてみると、comが多いのは当然でとして、実際の各TLDの登録件数に比較して顕著に多いTLDが見られました。comは1.3億、netとdeは1600万、ruは540万ドメインが登録されていますが、ドメイン登録数に比べて、比率的にru、org、deは突出して多くまた、グラフ上はその他としていますが、マイナーなccTLDの国についても、比較的HPKP設定が多い国があります。また、eduが異常に少ないのも気になりました。その他には、ar/br/cl/il/pt/nl/tn/skなど、マイナーなものが 50近くありました。

    6. 今のHPKPの何がいけなかったのか

    hpkpの発想自体は、不正発行された証明書を使った偽サイトを防ぐための仕組みとして有用であり、ChromeやFirefoxのブラウザ組み込みのプリロートピンは うまく機能しているように思えます。 その一方でHPKPヘッダを使った方式は、 かなり運用が複雑で難しく、失敗すると 2ヶ月といった、長期間、一部のユーザは接続できないという、障害が発生するリスクも高いことがわかりました。

    個人や中小のサイトで不正証明書を使ってまで偽サイトを作るメリットは見当たらず、攻撃を受ける可能性も極めて低いため、HPKPを使ってサービス障害のリスクを取ってまでHPKPを導入する必要はないと思います。

    では、一般サイト向けにHPKPの普及が進むためには、運用のしやすいサービス障害が起きにくい仕様の変更が必要だと思いますが、どうすればこれが可能になるでしょうか?

    max-ageを2ヶ月と仮定して、 HPKPヘッダで運用上の課題なのは、証明書更新の2ヶ月前に、ピンが変更になるなら設定を事前設定しなければならず、間違えに気づいてヘッダ設定を直しても、2ヶ月は通信障害が発生するということです。

    そこで、間違えに気づいた時には、すぐに設定変更が反映できたり、サーバー側で暫定的にブラウザのHPKP検証を無効化できるキルスイッチがあるとよいと思うのです。深く考察した訳ではありませんが、例えば、HPKP更新日をヘッダに記載するなどして、設定に更新があればmax-ageに関わらず更新し、無効化するなら、無効化するといった機能を提供すれば、運用はmax-ageや設定ミスの呪縛から解放されるように思います。

    他にもこの問題の解決方法はあるかもしれませんが、何らかの手当てをしない限り、HPKPは普及しそうにはありません。

    7. おわりに

    以上、HPKPについて、どこにピンを打つか、max-ageはどうするかなど運用面から、 いろいろ考察や整理をしてみました。 現時点では、HPKPを導入するのは時期尚早で、 運用に負担をかけ、サービス停止のリスクも高いということも ご理解いただけたのではと思います。

    これで、自分がHPKPについて前から書きたいと思っていたことを、 落ち着いて整理でき、3年越しぐらいに吐き出せました。 わかりにくかったり、理解が間違っていたらすみません。 個人的には、HPKPについては、これでわだかまりとかモヤモヤ感というは概ね 払拭されたように思います。 まぁ、「ブログなんてそんなモノよね」ってことで、、、w

    8. (参考) HPKP関連の勉強になるリンク

    Netcraft: Secure websites shun HTTP Public Key Pinning
    HPKPが流行っていないことの統計。なぜ流行らないかの解説。良記事。
    Netcraft: HTTP Public Key Pinning: You're doing it wrong!
    Netcraft社の、世の中のHPKP対応サイトの設定誤りに関する解説。良記事。
    Scott HelmeさんのHPKPブログ記事
    CSPやHSTSやHPKPなどSSL関連技術の専門家で、HPKPなどのレポート先サイト report-uri.io を 運営しているScott Helmeさんのブログ。HPKP対応サイトのドメインリストなどのデータもあります。
    Qualys Blog: Is HTTP Public Key Pinning Dead?
    Ivan Ristic氏の、「HPKPが終わっているか?」に関する議論。
    Raymii.org: HTTP Public Key Pinning Extension HPKP for Apache, NGINX and Lighttpd
    解説は充実。各サーバー毎のHPKPヘッダの設定例。
    MDN: Public Key Pinning
    MozillaによるHPKP解説。ChromeやFirefoxでのHPKP対応バージョンの記述。サーバー設定例 レポート機能は新しいChromeしか使えない事の言及など、参考になる。
    Public Key Pinningについて - Chris Palmer (原文)
    Chris PalmerによるHPKP解説。誤解もあるが、初めて証明書チェーンのどこにピンを設定するか、そのケース分けについて考察した記事。
    ぼちぼち日記:不正なSSL証明書を見破るPublic Key Pinningを試す
    joviさんによるHPKP(ドラフト)に関する詳細かつ広範な解説です。
    Jxckさんのブログ:Public Key Pinning for HTTP(HPKP) 対応と report-uri.io でのレポート収集
    Jxckさんの解説。特にreport-uriの機能を試してみた報告が貴重。
    公開鍵ピンニングによるユーザ追跡 HPKP Supercookies
    今回の記事とはあまり関係ないですが、 にしむねあさんのHPKPを使ったクッキーを使わないユーザー特定の面白い試みに関するスライド資料。
    OWASP: Certificate and Public Key Pinning
    OWASPの解説記事。無駄な情報も多い。

    X.509証明書の識別名などで使われるMulti-valued RDNとjsrsasignのサポートについて

    久々にちょっとPKI関連ネタです。いわゆるデジタル証明書(X.509証明書)には、主体者名(Subject Name)や発行者名(Issuer Name)に識別名(DN: Distinguished Name)を使います。例えば、

    CN=yourname@example.com,O=example,C=JP
    のようなものです。カンマで区切った一つ一つを相対識別名(RDN: Relative Distinguished Name)と呼んでいます。
    O=example
    一般的には相対識別名(RDN)は、「一つの」属性タイプと属性値のペア(AttributeTypeAndValue) より構成されます。
    属性タイプ=属性値
    O=example
    ただ、「一般的には」と書いた通り、RDNについて複数のAttributeTypeAndValueを持つことも可能です。これをMulti-valued RDNと呼んでおり、プラス"+"記号でつないで以下のように表現します。
    属性タイプ1=属性値1+属性タイプ2=属性値2...
    CN=User1+serialNumber=123
    Googleとかで「Multi-valued RDN」で検索するとわかると思うんですが、英語では結構あるのに、日本語で触れている記事って、自分のブログ以外みつからないみたいなんですよね。 今日は、拙作の暗号ライブラリ jsrsasign や OpenSSL を使いながら、証明書識別名のMulti-valued RDNや、識別名について掘り下げてみたいます。

    エントリと識別名

    LDAPや、その元となっているX.500ディレクトリサービスでは「エントリ」のツリー構造により情報を管理し、例えば会社、部門、社員は以下のように管理することができます。
    図1
    LDAPでは、あるエントリを特定するために「○×商事」の「総務部」の「佐藤二朗」さんという特定の仕方をします。エントリの名前、「総務部」や「佐藤二朗」という値は、属性タイプという型をつけることができ、組織名(O: Organization Name)、部署名(OU: Organizational Unit Name)、一般名(CN: Common Name)などのタイプがあります。
    図2
    例えば、営業の鈴木さんを特定するときに一番上までのエントリを辿って、以下のように表現します。これを「識別名(DN: Distinguished Name)」と呼びます。これにより他の部署のSuzukiさんとも区別できます。

    CN=Suzuki,OU=Sales,O=MaruBatsu
    識別名のうち、「OU=Sales」のようにエントリの丸の中を相対識別名(RDN: Relative Distinguished Name)と呼びます。

    また、このエントリのツリー構造をDIT(Directory Information Tree)と呼びます。

    Muti-valued RDNとは?なぜ必要か?

    上記で説明した識別名(DN)で、同じ営業部に鈴木花子さんが二人いたらどうしましょう。一般名に区別するための数字を追加したり、追加の値として、社員番号やメールアドレスで区別することもでき、エントリを追加しても良いのですが、どれもイマイチ。
    図3
    そこで、一つのエントリに複数の値をつけて識別することもできます。これを Multi-valued RDNと呼んでいます。
    図4
    同性同名の人は多分いるでしょうから、社員番号やメールアドレスなど他の一意なものと組み合わせて管理するのはスマートな管理方法だと思いますし、一部の商用のディレクトリサーバー製品では、利用者数ベースでライセンス課金するために、エントリ数を使うものもありますので、Multi-valued RDNを使うことによってコスト削減を狙うこともできます。ただ、Multi-valued RDNは、すべての製品で使えるというものでもないので(例えば、とある製品のスマートカードとか802.1X認証とかで後になって問題になったことがありましたよね、、、)本当に使ってしまってよいかどうかは、アプリケーションと相談して決める必要があるでしょう。

    識別名の文字列表現

    識別名の文字列表現にはざっくり2つの表現があります。

    CN=Matsuda Kenji,OU=Sales,O=MaruBatsu
    /O=MaruBatsu/OU=Sales/CN=Matsuda Kenji
    DITのツリー構造の下から順にカンマ","でつないだ方法と、上から順にスラッシュ"/"でつなぐ方法です。

    カンマで逆順につなぐ方法はRFC 2253 Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Namesや後継の4514で規定されています。LDAPのアプリケーションソフトウェアでは一般的に使われている方法です。

    もう一方の、先頭にスラッシュを付け、スラッシュで正順でつなぐ方法はOpenSSL onelineフォーマットと呼ばれ、OpenSSLで標準的に使われるとともに、OpenSSL系のウェブサーバーであるApache HTTP Server、nginx、lighttpdなどの設定などで使われる方法です。

    Multi-valued RDNの場合には、どちらの形式でも値をプラス"+"記号でつないで表現します。

    CN=Matsuda Kenji+emailAddress=matsu@mb.com,OU=Sales,O=MaruBatsu
    /O=MaruBatsu/OU=Sales/CN=Matsuda Kenji+emailAddress=matsu@mb.com
    プラスで繋がれた値の表示順序については、特に決まりは無いと認識しており、以下のMulti-valued RDNでCNとemailAddressのどちらを先にしても良いはずです。これがどのようにASN.1でエンコードされるかは後で述べます。
    CN=Matsuda Kenji+emailAddress=matsu@mb.com
    emailAddress=matsu@mb.com+CN=Matsuda Kenji

    次にCNやOUなどの属性タイプの文字列表現ですが、どのように表記しなければならいといった厳格な標準はなく、実装もバラバラであることがわかっています。8年前にXAdES長期署名に関連して、識別名の中の属性タイプの表記の実装状況について調査しており、その時にまとめた表を再掲します。
    RFC2253テスト1属性タイプ名のテスト
    X.509証明書プロファイルを定めたRFC 5280の4.1.2.4節 発行者名(Issuer)では、識別名の属性タイプとして対応しなければならない(MUST)リストと、対応すべき(SHOULD)属性タイプのリストが掲載されており、表中ではMUSTを黄緑、SHOULDを黄色、その他、証明書で実際に使われることのある属性タイプのリストを白とし、.NETや各種Javaベースの暗号ライブラリでどのように属性タイプが表記されるかをテストしました。表を見ればわかるとおり、結果はかなりバラバラです。また、S/MIMEのために使用される事があり、実際の証明書でもかなり含まれているemailAddressの属性タイプも、標準では実装を求めていないために対応にばらつきが出ているように思います。

    今、見直してみると当時はなかったEV証明書用の以下の属性タイプも、今ならテストすべきだったかなぁと思います。

    • jurisdictionOfIncorporationL - 法人登録管轄地(市町村)
    • jurisdictionOfIncorporationSP - 法人登録管轄地(都道府県)
    • jurisdictionOfIncorporationC - 法人登録管轄地(国)

    また、 カンマつなぎの識別名表記であるRFC 2253とその後継のRFC 4584の違いについて8年前の記事 でまとめており、仕様の改定によって、より識別名表記が一意になる方向に修正されていますが、 仕様の中で「RFC 4514は識別名文字列は一意にならない(=正規化しない)」という 事が明記されており、識別名文字列は、様々な表現が許されており、 単純な文字列比較では同じであるかどうかを判断できない事に注意しなければなりません。

    識別名のASN.1定義と構造

    次に、識別名が、ASN.1 DERエンコーディングにより、どのようにバイト列にエンコードされるのかを、 説明したいと思います。まず最初に、識別名のASN.1定義を紹介しましょう。 RFC 5280 4.1.2.4 Issuerより

    // X.500名、識別名(DN)はRDNの並び(SEQUENCE) Name ::= CHOICE { rdnSequence RDNSequence } RDNSequence ::= SEQUENCE OF RelativeDistinguishedName // RDNは、AttributeTypeAndValue 1つ以上のSET // つまり、複数AttributeTypeAndValueがあってもよい。 // これが複数あれば Multi-valued RDN RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue // 属性タイプと属性値のペア AttributeTypeAndValue ::= SEQUENCE { type AttributeType, value AttributeValue } AttributeType ::= OBJECT IDENTIFIER AttributeValue ::= ANY // 属性値はANYと定義していながらも、DirectoryStringで // 定義されたいずれかの文字タイプを使用する DirectoryString ::= CHOICE { teletexString TeletexString (SIZE (1..MAX)), printableString PrintableString (SIZE (1..MAX)), universalString UniversalString (SIZE (1..MAX)), utf8String UTF8String (SIZE (1..MAX)), bmpString BMPString (SIZE (1..MAX)) }
    つまり、
    • 識別名(DN)は、相対識別名(RDN)の並び(SEQUENCE OF)であり
    • 相対識別名(RDN)は、属性タイプと値(AttributeTypeAndValue)の集合(SET OF)であり
    • 属性タイプと値(AttributeTypeAndValue)は、属性タイプと値の並び(SEQUENCE)である
    という事です。SEQUENCEとSETは構造型と呼ばれるASN.1プリミティブですが、
    • SEQUENCEは配列のようなもので、順序関係のある並びを表す際に使います。
    • SETは集合のようなもので、構成要素の中には特に順序関係はない場合に使います。
    ついでに、SEQUENCEやSETと、SEQUENCE OF 〜、SET OF 〜の違いですが、
    • 単にSEQUENCEやSETとなっている場合には、構成要素のASN.1クラスが異なる場合に 使います。上の例ではAttributeTypeAndValueがそれに当たります。
    • SEQUENCE OF、SET OFとした場合、構成要素のASN.1クラスが同じ型の場合に 使います。上の例では、NameやRDNがそれに当たります。

    それでは、例として以下の識別名をASN.1 DERエンコーディングしてみましょう。

    CN=aaa,O=TEST,C=JP
    RFC 2253の場合には、逆順でRDNが並ぶので、以下のようにエンコードされます。
    302A SEQUENCE(30) OF -- DN 310B SET(31) OF -- RDN[1] 3009 SEQUENCE(30) -- AttributeTypeAndValue 0603550406 ObjectIdentifier(06) countryName 13024A50 PrintableString(13) "JP" 310D SET(31) OF -- RDN[2] 300B SEQUENCE(30) -- AttributeTypeAndValue 060355040A ObjectIdentifier(06) organizationName 0C0454455354 UTF8String(0C) "TEST" 310C SET(31) OF -- RDN[3] 300A SEQUENCE(30) -- AttributeTypeAndValue 0603550403 ObjectIdentifier(06) commonName 0C03616161 UTF8String(0C) "aaa"
    ASN.1データはデータ型を表すタグ、バイト長、値データより構成され、上の例の最後の行では、0CがUTF8String型、03がバイト長(=3)、616161(=aaa)が値を表しています。

    さて、次にMulti-valued RDNの場合にはどのようにエンコードされるのか、下の例を元に見てみましょう。ここでは、CN=aaaとCN=aの2つのAttributeTypeAndValueが使用されています。

    CN=aaa+CN=a,O=TEST,C=JP
    これをASN.1 DERエンコーディングすると以下のようになります。最後のRDNに注目してください。CN=aとCN=aaaと二つのAttributeTypeAndValuesがあることが確認できます。また、また、CN=aとCN=aaaでは、必ずCN=aが先に来ることにも注目です。
    3034 DN 310B RDN[1] C=JP 3009 0603550406 13024A50 310D RDN[2] O=TEST 300B 060355040A 0C0454455354 3116 RDN[3] CN=aaa+CN=a SEQUENCE(30)が2つある 3008 ATV[1] CN=a CN=aの方が先に来ている 0603550403 0C0161 300A ATV[2] CN=aaa 0603550403 0C03616161
    このRDN中のCN=a、CN=aaaの順序関係にはASN.1 DERとBERのちょっとした違いが関係があります。DERはBERのサブセットでなんですが、BERでは複数の表現が許されるのに対し、DERでは必ず一意な表現になります。その違いを表にまとめました。
    ASN.1 DERASN.1 BER
    概要ASN.1の一意なエンコード規則ASN.1のエンコード規則。DERのスーパーセットでDERであればBER
    共通の特徴通信の世界では長い歴史のある、CPUや整数型のサイズに制限されない、巨大なデータも扱える、任意の構造化データを扱えるデータ表現。XML, JSONに比べコンパクト。
    用途証明書、CRL、OCSP、RFC3161タイムスタンプS/MIMEデータ、CMS署名・暗号化データ、PKCS#12
    比較必ず表現は一意。超巨大なデータでも長さが予めわかっていないといけないので、ストリーム処理など不向き複数の表現がある。超大きなデータでも取り扱い可能
    SET要素のバイト列で昇順ソートするソートしなくて良い
    BOOLEANTRUEのみ使え、FALSEは省略するようクラス定義TRUE、FALSEが使える
    不定長表現長さ表現は一意で、予めデータサイズがわかっていないといけない。長さ表現で不定長表現が使え、長さを8000とした場合それは開始記号で0000が続くまで一つの要素であり、大きなデータも扱いやすい。
    以上のような違いがあり、SETの違いによりMulti-valued RDNのSET OFの順序が決まっているわけです。

    SETの要素は、各要素をASN.1エンコードしたときの昇順の辞書順でソートされ、ざっくり言えば、

    • 要素の短い物程先
    • 同じ長さなら属性タイプの長さが短い方が先
    ということになります。例でみてみましょう。
    3008 0603550403 0C0161 CN=a 300A 0603550403 0C03616161 CN=aaa ^^ 全体の長さLが08, 0Aの順になるので同じ属性タイプ長なら属性値の短い方が先 C,O,OU,CNなど主要な属性タイプはOIDの値が2.5.4.xになるので同一属性タイプ長
    全体の長さが同じ時、
    ^^ 全体の長さは同じなら 3011 0603550403 0C0A6162636465666768696A CN=abcdefghij 3011 060B2B0601040182373C020103 0C024A50 jurisdictionOfIncorporateC=JP ^^ 属性タイプの値の短い方が先

    OpenSSLのMulti-valued RDN対応

    OpenSSLはMULTI-valued RDNに対応しており、"-multivalue-rdn"をつけるだけです。 例えば、既存の秘密鍵でワンライナーでMulti-valued RDNの自己署名証明書を作りたい時

    openssl genrsa 2048 > a.prv
    openssl req -new -key a.prv -x509 -subj /C=JP/O=Test/OU=b+CN=a -out c.cer -multivalue-rdn
    Multi-valued RDNの証明書発行要求を作りたいとき
    openssl req -new -key a.prv -subj /C=JP/O=Test/OU=b+CN=a -out c.csr -multivalue-rdn
    となります。

    jsrsasignのMulti-valued RDN対応

    jsrsasignは、私が趣味で作ったPure JavaScriptによる暗号ライブラリでして、2010年ぐらいからボチボチ暇を見つけては昨日を追加しており、最初はRSA署名だけだったものが、ASN.1や証明書やタイムスタンプやJOSEなんか、自分が「欲しいな」と思った時に増築を繰り返しており、PKIやASN.1やJOSE(JWS,JWT,JWK)関係でちょっと試したいなと思った時に重宝しています。

    ウェブブラウザ上でも、Nodeでも使え、APIドキュメントやサンプルも充実させているので、結構ユーザは世界中にいたり、最近はSONYや横河(や勝手にうちの会社(^^;)のハードウェア商品でも使われていることが発覚したり、Nodeのnpmパッケージは月間10万弱のダウンロードがあるようで、ホントありがたい話です。

    JavaScriptの暗号ライブラリのAPIとしては、W3C Web Crypto APIなどあるんですが、モバイルブラウザでサポートしていないケースがあったり、古い暗号が使えなかったり、ちょっと書こうと思っても何行も書かなければいけなかったり、面倒くさいんですよね。そこで、jsrsasignでは、「なるべく少ない行数でやりたい事ができる」っていうのを目標にしていて、例えば鍵なんかは秘密鍵でも公開鍵でもPKCS#5でもPKCS#8でもJSON Web KeyでもなんでもKEYUTIL.getKeyに渡してしまえば適当に処理します。また、PCでもスマホでもNodeでも、多少古い環境でもJavaScriptさえ動けば使えるようになっています。また、APIドキュメントやチュートリアルの資料もできる限り潤沢に用意したつもりです。

    割と最新の話まで入っている英語の入門スライドがあったり、
    slidee
    またちょっと古いですが、2013年にJNSAのWGでお話したjsrsasignとjsjwsが別の開発ラインだった時の入門スライド があるのでよかったら参考にしてください。
    slidej

    ドキュメント類は拙い英語のものしかなくて申し訳ないですが、問題とかあれば、Issueには日本語で入れて頂いて構わないので入れて頂ければと思います。

    で、jsrsasignをMulti-valued RDN対応させたり、カンマ繋ぎDN対応したいなと思っていて、ようやく6.2.2をリリースした最近になってから対応させました。 例えば、Multi-valued RDNの識別名がどのようにASN.1 DERエンコードされるのかなんて話は、次のように確認できます。

    % node > var X509Name = require("jsrsasign").KJUR.asn1.x509.X500Name; > new X509Name({str: "/C=JP/O=T1+CN=kjur"}).getEncodedHex(); '3027310b3009060355040613024a5031183009060355040a0c025431300b06035504030c046b6a7572'
    あとは、証明書発行要求(CSR)を作ったり、
    var rs = require("jsrsasign"); var kp = rs.KEYUTIL.generateKeypair("RSA", 2048); pem = rs.KJUR.asn1.csr.CSRUtil.newCSRPEM({ subject: {ldapstr: 'OU=T1+CN=example.com,O=Test,C=US'}, ext: [ {subjectAltName: {array: [{dns: 'example.net'}]} ], sbjpubkey: pubKeyPEM, sigalg: "SHA256withRSA", sbjprvkey: prvKeyPEM });
    証明書を発行したりする時にもMulti-valued RDNが使えます。
    var pem = KJUR.asn1.x509.X509Util.newCertPEM({ serial: {int: 4}, sigalg: {name: 'SHA1withRSA', paramempty: true}, issuer: {str: '/C=US/O=a'}, notbefore: {str: '130504235959Z'}, notafter: {str: '140504235959Z'}, subject: {ldapstr: 'OU=kjur+CN=kjur,O=b,C=US'}, sbjpubkey: kp.pubKeyObj, ext: [ {basicConstraints: {cA: true, critical: true}}, {keyUsage: {bin: '11'}}, ], cakey: kp.pubKeyObj });
    割と融通が利くので、よかったら使ってやってください。

    おわりに

    というわけで長々、Multi-valued RDNや識別名(DN)のことでダラダラ書いてしまいました。ごめんなさい。誰かの参考になれば良いかな、と思います。

    追記(2016.12.19)

    あっ、誤解されないように書いておきますと、私としては、Multi-valued RDNを広めたいとか、使うべきだとか言うつもりは毛頭ありません。相互運用性が高い方向でインフラ設計するのが原則であり、使わなくて済むなら使わない方がいいでしょう。ただ、受け取ったとしても、びっくりしないでね、と、、、、w

    関連記事

    バルセロナでプリペイドSIMの購入(2016年11月版)

    バルセロナでプリペイドSIMを購入された、先人の方のありがたい情報を参考に、私も使ってみましたので、記録として残しておきます。よかったら参考にしてください。

    土曜夜着だったので空港で購入

    今回は家族でバルセロナに旅行に行きましたが、旅行中の連絡用にプリペイドSIMを2枚買おうと思っていました。土曜の午前発で夜の19:30頃空港着でしたので、街に出て探してSIMを買うというのも疲れそうで、バルセロナでは翌日の日曜は、ショッピングモール以外ほとんどの店が閉まっているらしく、空港でvodafoneのSIMを買ってしまうことにしました。


    vodafone-es
    (vodafone esサイトより)

    いろんな記事でも紹介しているように、ルフトハンザでバルセロナ・エルプラット国際空港のターミナル1に到着し、税関を抜けるとすぐ左手にCRYSTALの看板が見えますのでそこで売っています。(ピンクの店全景, エリアマップ) 混んでいることがあるように書いていましたが、私が行った土曜の20:30頃には誰もいませんでした。紹介されていた、店に並んでるSIMを指差して「これください」ってな感じでvodafoneのプリペイドSIMを2枚を購入しました。
    image

    • 60分の通話料
    • 1GBのデータ通信
    • SMSも通話料の範囲で無制限で利用可能(だけどなぜか使えなかった(後述))
    • こみこみで15ユーロ
    ぶっきらぼうにSIMを渡して終わりにしようとされましたが、あらかじめiPhone SEとAndroidスマホを英語表示にしておいたので、「設定してください」とお願いし、動作確認もなくただSIMを挿すまではしてくれました。iPhone SE用のnano SIMだと追加料金を5ユーロ取られるような情報もありましたが、特に追加はありませんでした。 店の前で、自分で起動と通話の確認だけはして、2台の間で通話ができることは確認しました。

    他のプリペイドSIMも幾つかあるようですが、空港ですぐ使えるという気軽さと、初期費用も少ないという事から、1週間以内の滞在ならvodafoneでいいのでは?と思います。

    • vodafone (60分通話、1GBデータ利用料込で15ユーロ) 料金は若干高めだそう
    • Movistar (10ユーロ分の利用料込で15ユーロ)
    • Orange (通話0.18ユーロ/分、1GBデータ利用料込で10ユーロ)
    • Orange Tu Mundo (14ユーロ分の利用料込で28ユーロ)

    とりあえずパッケージとSIMとメモっておく事


    q1small
    パッケージの表面はこんなの。
    q2
    縦横比がおかしいですが、裏面の「N. Tel.」の所にSIMの電話番号が書いてあります。スペインでは61で始まる9桁の番号(61xxxxxxx)です。下で拡大しましょう。
    q3
    SIMカードのサイズは、通常SIM、Micro SIM、Nano SIMのサイズに切り取って使えます。古い情報サイトにはnano SIMだと追加料金を取るようなことを書いているところもありましたが、特に追加料金は必要ありませんでした。ここで、「PIN」の4桁の数字はSIMロックの解除PINコードで、ケータイ再起動のたびに入力が必要ですので書き取っておきます。また、「PUK」はSIMロック解除コードを4回以上間違えた場合の解除コードですので、これも書き取っておきます。
    q5
    メモを取っておくべき数字をまとめておくと

    • Tel. - 電話番号(61xxxxxxx 9桁)
    • PIN - SIMロック解除PIN(xxxx 4桁)
    • PUK(Personal Unblocking Key) - PINロック解除コード(xxxxxxxx 8桁) 通常は不要
    購入したvodafoneのSIMは多分、帰りに経由するドイツでも(日本でも?)使えるように思いますが、SIMロック解除PINを記録するのを忘れてしまったために、ドイツで試すことができなかったです。写メにも取っておくとさらに良いように思います。中には別のカードも入っています。Google大先生に聞いて調べてみて、ざっくり意訳するとこんな感じ:
    q4

    Esta tarjeta va protegida con dos codigos que encontraras impresos en tu tarjeta: Codigo PIN, que debes marcar una vez introducida en tu dispositivo y cada vez que lo enciendas. Y un codigo de desbloqueo PUK, que deberas marcar, unicamente, en caso de bloqueo del codigo PIN. En caso de perdida, puedes consultarlos en vodafone.es/pin o llamando gratis al 1150 desde cualquier operador nacional. Para tu seguridad, te recomendamos cambiar el codigo PIN por uno nuevo que te sea mas facil de recordar.

    このSIMカードはここに印刷されている2つのコードで保護されています。 PINコード、これは、一度使用したデバイスで電源を入れる度にコード入力する必要があります。 PUKロック解除コードはPINコード(の入力誤りで)ロックされた場合に入力する必要があります。 失敗した場合には、フリーダイアルで1150により いずれかの国のオペレータに問い合わせるか、 vodafone.es/pinで確認することができます。 セキュリティ向上のため、覚えやすい新しいPINに変更することをお勧めします。

    iPhone SEのデータ通信で早速ハマる

    今回の旅行では、SIMフリーで接続する用に次の2台を持ってきました。(iPhone SEの選定については別の機会に)

    • iPhone SE (SIMフリー)
    • Polaroid Pigu 3G (SIMフリー)
    Polaroid Piguについては難なくデータ通信でき、Google Mapも使えたのですが、iPhone SEの方がどうもデータ通信ができません。また、SMSも両方送ることができません。ホテルまでの移動のタクシーでいろいろ設定を見てみましたが、途中であきらめホテルでWifi繋いでゆっくり調べることにしました。

    iPhone SEのデータ通信

    落ち着いてAPN設定など見てみると日本で設定確認のためにインストールしたiijmio用の「IIJmio モバイルサービス APN設定プロファイル」が悪さをしていたようで、iijmioのAPN設定が使われているようでした。手動でvodafone ESのものに変更し無事データ通信もできるようになりました。APN設定はiPhoneSEとPiguとで、ネットで探した別の設定をしていたようですが、どちらも問題なく繋げていたようです。[参考1][参考2]

    iPhoneSEPigu
    オペレータvodafone ESvodafone ES
    APNap.vodafone.esairtelwap.es
    Uservodafonewap@wap
    Passvodafonewap125

    どちらもSMSはできず

    データ通信には成功し、とりあえずの旅行での連絡や調べ物やメールは無事できるようになったんですが、結局、iPhone SEでもPiguでもSMSができるようにはなりませんでした。SMSは通話に含まれるとかいてあったので問題無いはずなのですが、結局できるようにならなかったのは謎のままです。ご存知の方は、教えていただけるとうれしいです。送信失敗したエラーメッセージとして次のSMSが送られてきました。

    El Mensaje Multimedia no se ha enviado a todos los destinatarios porque no dispone de suficiente saldo en su tarjeta. Recargue e intentelo de nuevo mas tarde

    彼らはあなたのカードに充分な残高を持っていないため、マルチメディアメッセージがすべての受信者に送信されませんでした。リロードした後に再度お試しください。

    現在の使用量も確認できず

    現在の使用量はMi Vodafoneで確認するそうなのですが、結局アカウントがうまく作れず、使用量の確認までは辿りつけませんでした。また、iOS版のMi Vodafoneアプリは、日本に設定されたiTunesアカウントからはダウンロードできません。Android版は試し損ないました。

    ドイツ(ミュンヘン)での利用も確認できず

    このプリペイドSIMはドイツでもローミングで使えるはずなのですが、ミュンヘンで乗り換えの際使おうと思ったら、SIMロックのPINコードを書いた紙がスーツケースに入ってしまっており、また、コードの写メも取っておらず、SIMを使うことができませんでした。とほほ。

    日本からのプリペイドSIMの利用

    このSIMカードは普通にローミングでつなぐことができそうな雰囲気でアンテナも立ちます。日本でつなぐと以下のようなSMSが送られてきました。

    VF info: Bienvenido a Japon. Llama a Espana y recibe llamadas por 3,03E/min + 1,69E de establecimiento. Envia SMS a 1,21E. MMS a 3,03E y recibelos por 2,42E. Precios con IVA.+info: vodafone.es

    ボーダフォンより:日本へようこそ。スペインには、通話3.03ユーロ/分+接続1.69ユーロが必要です。1.21ユーロでSMSが送信できます。MMS送信は3.03ユーロ、受信は2.42ユーロかかります。費用には付加価値税が含まれます。: vodafone.es

    その他のSMSメッセージ

    その他、ちょいちょいSMSメッセージが(送ることはできないのに)送られてきており、旅行中は忙しいし、パソコンも持っていかなかったので、いちいち調べる気もしなかったんですが、日本に戻って落ち着いたので、参考まで意訳してみました。

    VFInfo:!Bienvenido a Vodafone!Gracias por confiar en nosotros,estamos a tu disposicion en www.vodafone.es,marcando gratis *123# tecla llamada y tienda Vodafone.

    ボーダフォンへようこそ!ご利用ありがとうございます、無料のダイヤル* 123#や、ボーダフォンストア www.vodafone.es でご自由にお使いいただけます???

    VF Info Tarifa: Ya tienes 1,5GB y 60min llamadas a Espana o Internacionales a paises dentro de beneficio hasta 10/12/2016. +info: m.vodafone.es o *565#

    すでにスペインで2016年12月10日まで対象国の国際電話に60分とデータ通信1.5ギガバイトがご利用になれます。m.vodafone.esまたは* 565#にお問い合わせください。

    VF Info: Personaliza el mensaje de bienvenida de tu contestador gratis en el 2211xx. Tu clave de acceso es 8xxx, si quieres cambiarla llama gratis al 2211xx

    留守番電話のウェルカムメッセージを変更したい場合、無料通話で2211xxにおかけください。あなたのパスワードは8xxxです。

    61712xxxx ha hecho 1 llamada el dia 12/11/2016 a las 22:55 h. Pulsa para devolver la llamada.

    電話番号61712xxxxより、2016年11月12日 22:55にお電話がありました。おかけになる場合には<呼出>ボタンを押してください。

    参考にした記事

    以下の記事を参考にしてSIMを購入できました。ありがとうございました。

    ヨーロッパでPokemon Goに最適?なSIMフリースマホ

    いろいろな訳あって、バルセロナに家族旅行したのですが、家族内での連絡用にプリペイドSIMを使ってみたいなと思いました。ついでにPokemon GOでヨーロッパでしか捕まらないというバリヤードをゲットしたいな、、、と。

    家にはSIMフリーとして、

    • Nexus 7 2003 (LTE)
    • Polaroid Pigu (3G)
    があったんですが、NexusはPokemon GOがインストールすらできないし、持ち運ぶにはデカイので、何か安い Android スマホを買うかなと安易に思っていました。

    欧州でLTE使いたければ対応バンドに注意

    欧州のキャリアのLTEのバンドは3、7、20が多く、これら3つをサポートしている予備機のSIMフリースマホ(でPokemon GOができるもの(^^;)が欲しいわけで、国内では別途メインで使っているやつがあるのでなるべく値段は抑えたいわけです。

    ところが、格安SIMフリースマホはこの記事をよく読むとPokemon GOには向いてなさそうで、黙ってiPhoneを使っとけみたいな話になっています。また、格安SIMフリースマホは欧州の3、7、20の3つに対応しているものは少なく、Androidでは7万以上の高級機でないとサポートしていないようです。

    そう考えると、iPhone SEはお得度が高く、SIMフリーで、欧州LTEバンドにも対応して、Pokemon GOの使用も問題がなく、コンパクトで旅行用のスマホとしては最適という気がして結局コレを買ってしまいました。2016年9月にiPhone SEは1万円ぐらい値下げされ、16GBモデル44,800円、64GBモデル49,800円ととてもお得になっています。大した価格差じゃないので64GBが良さそうですね。日本で販売されるモデルはA1723ですが、LTE対応バンドが非常に多いので海外利用で安心感あります。

    欧州LTEバンドの対応状況を関係しそうなものだけざっと調べてみました。

    製品モデル概算価格対応バンド数B3B7B20
    iPhone SE A1723(北米日本) 64GB49,80019
    Nexus 7 2013 LTE北米日本版7××
    Nexus 7 2013 LTE欧州版7×
    Nexus 5X5万
    Nexus 6P 64GB8万
    Xperia XZ7.6万20
    ZenFone 2 Laser ZE601KL13××
    ZenFone 2 Laser ZE500KL9××
    ZenFone Max 16GB2.6万9××
    ZenFone Zoom 64GB5.5万16×
    FREETEL Priori 3S 16GB1.6万5×
    FREETEL SAMURAI REI 32GB2.1万6

    というわけで、予定よりもちょっと高くつきましたが、無事バリヤードも3匹ゲットできてiPhone SEにして非常に満足しています(^^;
    image

    バルセロナのプリペイドSIM購入については、近々なんか書きます。

    SSL Pulseの統計情報でみるSSL/TLSの引越しについて

    2014年11月頃から、SSLに関する統計情報を公開しているサイトSSL Pulseのデータから推移情報をブログで公開してきました。隔月で更新するようなことを言ってて、2015年12月から更新が無い状態になっており、「コラ〜〜!サボってんじゃね〜〜」的なことを思われたかたもいらっしゃるかもしれません。すみません。すみません。すみません。

    新しいサイト

    SSL Pulse Trends(SSL Pulseデータの推移) https://kjur.github.io/www/sslpulsetrend/index_j.htmlというサイトを作りました。今後の毎月の更新はこちらでやっていきます。

    サイトを移行した経緯など、、、

    前は、エクセルなど駆使してグラフ描いてたんですが、そりゃもう、結構手間がかってたんですよ。自分も興味があって毎月すぐ知りたいんだけど、とても、毎月はできないなと、、、ざっくりとした流れはこんな感じ:

    • 今月のデータファイル(JSON)をwgetでダウンロードする
    • データの推移をTSV形式になるように変換するツールを実行する。グラフに必要なデータ列もこの時作る。
    • TSVファイルをUTF-16にする(Mac Excel対策)
    • Excelで読み込み
    • データを細かい整形(日付フォーマットや表ヘッダなど)
    • 必要なグラフを作る
    • グラフをEMF(拡張メタファイル)でエクスポートする
    • PowerPointに吹き出し等を貼り付け(位置調整)
    • PowerPointの画面を画像キャプチャし、ブログへ
    まず、第一の鬼門なんですが、自分は自宅ではMac Book Airを使ってまして、Mac用のExcel(前の2011も今のやつも)は、文字化けしないようにCSVやTSVファイルを読み込むのが骨が折れるんですよ。一応ファイルの入力候補としては普通のUTF-8でも大丈夫そうに見えるんだけど、うまくいかず。結局うまくいったのはメモ帳アプリでUTF-16に変換してから読み込ませるという方法です。Googleとかで"Mac Excel TSV 文字化け"みたいなキーワードで検索すれば、方法が出てくるでしょう。
    07

    そして、一つ一つグラフを作っていくわけです。
    01
    で、Excelのグラフの凡例ではちょっと見づらいのでパワポで吹き出しをつけます。
    39
    どうです?結構面倒くさそうでしょう?

    で、新しいサイトでは

    とにかくExcelでグラフをつくるのはやめにしたく、JavaScriptベースでグラフを描けないもんかと、調べてみました。最初は、ccchartなんかがデザインも良いかなぁと考えていたんですが、思っていたデザインにするのは、至難の技であると知り、D3.jsという有名なライブラリも見たんですが、一つのフツーのグラフ書くのに多くのコードを書かねばならず断念。D3.jsを簡単に使うためのラッパーがあるそうで、それを幾つか見て、rickshawで何とか許せるグラフが描けたのでそれを使うことにしました。

    本当は、SSL Pulseに置いてあるJSON形式のデータファイルをそのまま、表示の度に取り込んで加工してからグラフ表示しようとしたんですが、諸々CORSの壁に阻まれ断念。動的にダウンロードする必要もなくなり、スタティックな解析データをNodeで作って、SOURCEタグで普通にデータ取り込むことになりました。

    ブログでたまたまSSL Pulseについて書くだけなら、特別な断りをいれなくてもいいかと思ったんですが、定常的に今後は英語でもページを公開するとなると、SSL Pulseの作者のIvan Ristićさんに仁義というか確認取っといたほうがいいかなと思いました。IvanさんはSSL/TLSの技術解説書の中では最高に良いと思うBulletproof SSL and TLSの著者であり、SSLの設定評価サイトであるssllabsの開発などもしています。

    Bulletproof SSL and TLS
    Ivan Ristic
    Lightning Source Inc
    2014-08

    最初は、TwitterのDMで連絡取ろうとしたんですが、当然ながら私のフォローして頂いてるわけではないのでDMが送れず、メールアドレスもどこにも記載されていなので、連絡がつきませんでした。そこで、いつもJavaScriptの暗号/PKIライブラリでは情報交換などさせて頂き大変お世話になっているRyan Hurstさんに頼み込み、連絡とってくれないかと伝えました。Ryanさんは「Kenjiを紹介するよ。彼は、すげーJavaScriptの暗号/JWT/X.509ライブラリの作者だ。」と私からのお願い事項のメールを転送してくれました。2日ぐらい待ってて、「う〜〜ん」こりゃレス無しかなぁとも思ってたんですが、返事が来まして「SSL Labsは自由なコンテンツライセンスになってて、君の場合でも全く問題ないとわかると思うよ。同じようなこと(=データ推移情報)をやりたいと思ってたんだけど、時間がなくてね〜〜。」との事でした。よかった、よかった。これで安心して定常的に公開できそうです。

    Rickshawの使い方は概ねこんな感じです。

    <div id="chart_container"><div id="grade_chart"></div></div> <script> var graph = new Rickshaw.Graph({ element: グラフを描くキャンバスが挿入されるDIVのDOM, width: グラフ幅, height: グラフ高, renderer: グラフ形式(棒グラフとか折れ線グラフとか), series: [{"color": グラフデータ色, "name": データ名(TLS1.2とかSHA256withRSAとかデータ名), "data": [{x: 値, y: 値}, {x: 値, y: 値} ...]}, : (複数のデータがあれば続く) ] }); graph.render(); </script>
    同じ形式のグラフ描くのに、同じようなコード書くのも面倒なので、さらにラッパーを作りました。
    RickshawUtilGraph(グラフ描くDOM IDの共通ヘッド(グラフや凡例、XY軸など), グラフの共通テンプレート, データ(グラフデータ、データ名) [,オプションでグラフ形式を変えたい場合のパラメータ] [,オプションでグラフ色変えたい場合のパラメータ]);
    これでようやく、SSL Pulseの更新があっても、make 一発でグラフデータを作れるので、毎月の更新も負担にならなくなりました。

    というわけで、まだ素っ気ないページですが日本語ページ公開にこぎつけました。今までなかった評価グレード(A-F)の分布推移のグラフはNPNのHTTP/2サポートプロトコルの推移のグラフも付け加わっています。
    42
    しばらくしたら英語ページの作成にとりかかりたいと思います。

    今後とも、よろしくお願いします。

    関連記事

    最新記事
    Categories
    Archives
    記事Google検索

    本ブログ内をGoogle検索
    Twitter
    Yahoo!アクセス解析
    Travel Advisor
    QRコード
    QRコード

    • ライブドアブログ