JNSA電子署名WG勉強会 2013.09.30 jsrsasignとjsjwsについて

7,671 views

Published on

日本ネットワークセキュリティ協会(JNSA)の電子署名WGの勉強会で拙作のpure JavaScript暗号ライブラリjsrsasign http://kjur.github.io/jsrsasign/ とOpenID Connect等で使われるJSONの署名データ形式のためのライブラリjsjws http://kjur.github.io/jsjws/ について解説させて頂きました。

Published in: Technology

JNSA電子署名WG勉強会 2013.09.30 jsrsasignとjsjwsについて

  1. 1. JavaScript実装の暗号ライブラリ、JWT/JWS jsrsasignとjsjwsJNSA電子署名WG スキルアップTF 講演資料(配布版) 2013年9月30日 @kjur / 漆嶌 賢二
  2. 2. 今日のアジェンダ 1. jsrsasign 暗号ライブラリ 2. jsjws JSON署名/認証トークンライブラリ
  3. 3. 自己紹介 セキュリティ、PKI、署名、SSL、認証好きな人 またの名を「証明書ハンター」 「自堕落な技術者の日記」のブログの人 Twitterでは @kjur な人 PKI、ID(SAML)関係ではかれこれ11年くらい Challenge PKI、アジアPKI相互接続実証実験、S/MIMEテスト、 ECOM長 期署名実験、ETSIプラグテスト、JIS、ISOなど 主にECOM、デ協、JNSAで活動 富士ゼロックスの中の人らしいが今日は個人として来ました blog.livedoor.jp/k_urushima
  4. 4. そもそものきっかけは? 1. Javaはやべーな orz 2. Perlは終わりだな orz 3. Rubyは既に 暗号ライブラリあるしな orz 4. いやー、今どきの若者はJavaScriptらしいですよ。Node.jsとかあるし。
  5. 5. きっかけはスタンフォード大Tom Wuさんの からあったらしい JavaScriptでRSA暗号化ができるページ 2006年4月 http://www-cs-students.stanford.edu/~tjw/jsbn/
  6. 6. 2010年、私のはしゃぎっぷり
  7. 7. じゃぁ、jsrsasignで 何ができるの? RSA署名ができるだけじゃないんです
  8. 8. jsrsasignの機能・特徴 RSA/RSAPSS/ECDSA署名の生成・検証ができる 秘密鍵、公開鍵、証明書の扱いが簡単 ハッシュ関数、HMACができる Java JCEみたいに使いやすい ASN.1の読込み、生成ができる 証明書の発行ができる Base64、HEX等の文字列変換 スマホブラウザでも動く
  9. 9. 酔ってスマホいじって 急にこんなこと よくあるよね? 「あ〜、楕円暗号で署名して〜」とか 「あ〜、ハッシュ計算して〜」とか 「あ〜、ASN.1つくりて〜」とか 「あ〜、JWT署名して〜」とか そんな時、jsrsasign、jsjws
  10. 10. 例えば、 スマホブラウザで JWT署名が できるんで す
  11. 11. jsrsasign,jsjwsの構成 こう書くと整然と作った見たいだけど・・・
  12. 12. 実際は「ハ○ルの動く城」orz 思いついたままに建て増ししただけorz
  13. 13. 使われてんの?
  14. 14. Mozilla Persona BrowserID Mozillaの認証サービスPersona, BrowserIDでは 暗号ライブラリとして Mozillaが開発した jwcryptoが使わ れているが、その中では jsrsasign が 使われている。 https://login.persona.org/ https://github.com/mozilla/jwcrypto/blob/master/libs/dependencies.txt
  15. 15. Named Data Networking 米国立科学財団(NSF)の4つの新 プロジェクトの一つで研究費8億 円、 のUCLAのLixia Zhang女史ら IETFの重鎮がリードする Named Data Networking(NDN)プロジェ クトの JavaScriptのセキュリティラ イブラリにjsrsasignが含まれてお り、 技術報告でも引用頂いている。 named-data.net Geekなページ:未来インターネットアーキテクチャ 含まれるjsrsasignのライセンス NDN技報:Development and Experimentation with NDN-JS, a JavaScript Library for Named Data Networking (参考文献[9])
  16. 16. The H: WikiLeaksなどの盗聴、情報漏えい対 策としてブラウザ上での暗号化、署名 が必要 ↓ そこでjsrsasign http://www.h-online.com/open/features/Lessons-from-WikiLeaks-decentralize- decentralize-decentralize-1153977.html?page=2
  17. 17. EGIZ オーストリアの電 子政府推進機関: クライアント側ウェブアプリのための JavaScript暗号に関する調査報告 ↓ そこでjsrsasign http://www.egiz.gv.at/files/download/Dokumentation.pdf
  18. 18. スペイン電子政府の開発 サイト スペイン政府(GOBIERNO DE ESPAÑA)の 通信技術センターの開発 のインシデント管理システム(Gestor de incidencias de la Forja del Centro de Transferencia de Tecnología)で 電子投票イニシアチブ のソースコード(Código del PFG Democracia Electrónica - Iniciativas Legislativas Populares) にjsrsasignが使われていたり。 Forja del CTT Mantisリポジトリへのリンク
  19. 19. ドイツの若者から強い支持を集めている政党、ドイツ海賊党のメンバ ーが3万人の党員電子投票にjsrsasignが使えるかというメール問合 せを頂いたり Hello Kenji, I'm contacting you because I am starting to work on a somewhat bigger project that could use your Library. I am a member of the german Pirate Party and responsible for the implementation of a provable internet-voting system we just decided to use. In a nutshell I need a way to generate RSA Private Keys, export them via PKCS#1 PEM, X509 Certs or similar methods, as well as signing, encrypting, and verifying signatures. There are a few questions I'd like to get answered, if you have the time. Do you deem your project ready for use in a central position for securing vote integrity for a party of 30.000 people? Do you have a way of exporting generated Keys via one of the above mentioned methods in mind for your library? I have had trouble trying to export a generated RSAKey, is there a way as of right now? Kind regards, 参考 NHK: 活躍!ドイツ海賊党 〜ネット世代の政治のゆくえ〜 http://www.dailymotion.com/video/xy5a70
  20. 20. 基本機能である デジタル署名 ハッシュ関数 メッセージ認証(MAC)
  21. 21. 概要 ・Java JCEと似てて覚えやすい ・署名:KJUR.crypto.Signature ・ハッシュ:KJUR.crypto.MessageDigest ・メッセージ認証:KJUR.crypto.Mac ・データ追加 update() に対応 ・署名の init() はとても便利で簡単
  22. 22. 対応するアルゴリズム 署名 *withRSA, *withRSAandMGF1, *withECDSA ハッシュ MD5,SHA1/224/256/384/512,RipeMD160 MAC HmacMD5/SHA1/224/256/384/512 楕円曲線 secp256r1(NIST P-256,P-256,prime256v1) secp256k1 secp384r1(NIST P-384,P-384)
  23. 23. 署名:Signature RSA, RSAPSS, ECDSAに対応しており、鍵を渡せば鍵データのフォーマット、 公開鍵/秘密鍵/証明書、生成/検証を自動判定 // 生成例 var sig = KJUR.crypto.Signature({alg: 'SHA1withECDSA'}); sig.init(PKCS#5/8秘密鍵PEM文字列など[, パスコード]); sig.updateString('aaa'); var sigValueHex = sig.sign(); // 検証例 var sig2 = KJUR.crypto.Signature({alg: 'RSAwithECDSA'}); sig2.init(PKCS#8公開鍵や証明書など); sig2.updateHex('616161'); var isValid = sig2.verify(sigValueHex2);
  24. 24. ハッシュ関数:MessageDigest データ入力の追加ができるので長いデータでも大丈夫。 var md = new KJUR.crypto.MessageDigest({alg: "sha256"}); md.updateString("aaa"); md.updateHex("1f3daa34"); var hashValue = md.digest(); // 一行でできるユーティリティーもある KJUR.crypto.Util.hashString("aaa", "sha1"); KJUR.crypto.Util.hashHex("471dfbdaaa30", "ripemd160");
  25. 25. メッセージ認証:Mac メッセージ認証も同様にパスワードをつけるだけ。 var mac = new KJUR.crypto.Mac({alg: "HmacSHA1",                             pass: "passwd"}); mac.updateString("aaa"); var macHex = mac.doFinal(); (注意) パスワードは16進数でなく文字列
  26. 26. 公開鍵暗号の鍵データ
  27. 27. 特徴 RSAとECC RSA/ECC鍵ペア生成 KEYUTIL.generateKeypair 公開鍵/秘密鍵のロード KEYUTIL.getKey PKCS#5 暗号化/平文 PEM秘密鍵 PKCS#8 暗号化/平文 PEM秘密鍵 PKCS#8 PEM公開鍵 PEM X.509公開鍵証明書 鍵スペック (例 {n: '1f3a76...', e: '010001'}) 鍵オブジェクトからPEMフォーマットの生成
  28. 28. 鍵ペア生成 // RSA var keypair = KEYUTIL.generateKeypair("RSA", 1024); // ECC var keypair = KEYUTIL.generateKeypair("EC", "secp256r1"); // で // keypair.prvKeyObjに秘密鍵のRSAKey/ECDSAオブジェクトが // keypair.pubKeyObjに公開鍵のRSAKey/ECDSAオブジェクトが // 設定されている
  29. 29. 秘密鍵、公開鍵の読込み 鍵の形式毎に読込むメソッドが別でとても面倒でしたよね? var key = KEYUTIL.getKey(鍵ファイルor証明書orデータ                   [, パスワード]                   [, HEXのデータタイプ]); PKCS#5でも8でも暗号化されててもECDSAでもRSAでも証明書でもHEXでも 鍵スペックのJSONでも何でも読込めます。 DROP HERE ファイル: アルゴリズム: 鍵タイプ:
  30. 30. 鍵オブジェクトから 鍵PEM文字列の生成 今のところRSA秘密鍵のPKCS#5しか作れない KEYUTIL.getEncryptedPKCS5PEMFromRSAKey(rsaKey                           , "password");         鍵保護する共通鍵暗号→  [, "AES-128-CBC"]);         そのソルト→          [, "3fa4dd..."]); DES-EBE3-CBC, AES-128-CBC, AES-192-CBC, AES-256-CBCに対応
  31. 31. ASN.1のおさらい
  32. 32. まずはASN.1のおさらい(1) 証明書、鍵、タイムスタンプ、署名データなど 多くの通信データはASN.1形式になっている事が多い。 特徴1:int、longに制限されないとても長いデータを表現可 特徴2:構造化データも表現できる
  33. 33. ASN.1のおさらい(2) 特徴2:構造化データも表現できる
  34. 34. 簡単なASN.1の読込み ASN1HEXクラス
  35. 35. ASN1HEXクラスの基本機能 16進数文字列のASN.1データに対して、指定位置のASN.1オブジェクトのタ グ、長さ、値情報が取れる。
  36. 36. ASN1HEXクラスの基本機能(2) 子要素のインデックスリストを得る。
  37. 37. ASN1HEXで子孫Objを扱う 構造型ASN.1の子孫を指定するには、各階層で何番目かを示す"nthList"を 使う。ASN.1構造の深い所、例えば証明書の発行者名などを場所指定して取 得する場合に重宝する。 getDecendantHexTLVByNthList(s,0,[0,0]) → "020104" getDecendantHexLByNthList(s,0,[0,0]) → "01" getDecendantHexVByNthList(s,0,[0,0]) → "04" getDecendantIndexByNthList(s,0,[0,0]) → 8 ※講演時にはnthList配列の表記に間違いがあり修正しました SEQUENCE idx=0 SET [0]idx=4 INTEGER4 [0,0]idx=8← 参照したい INTEGER31 [0,1]idx=14 SET [1] UTF8STRING"aaa" [1,0] IA5STRING"bbb" [1,1]
  38. 38. ASN.1オブジェクトの生成
  39. 39. ASN.1オブジェクトの生成(概要) 基本型、構造型、タグなど全てのASN.1オブジェクトを16進数文字列表現す るためのクラスが定義されており、 プロパティを渡すだけで簡単に生成できる。 var i1 = new KJUR.asn1.DERInteger({'int': 234}); var s1 = new KJUR.asn1.DERUTF8String({'str': 'テスト'}}); var seq = new KJUR.asn1.DERSequence({'array': [i1, s1]}); var hex = seq.getEncodedHex(); BouncyCastleやIAIKと大体同じ。 でも、もっと簡単な方法が→
  40. 40. ASN.1オブジェクトの生成(2) newObjectでJSONデータから一発生成 var hex = new KJUR.asn1.ASN1Util.newObject(   {seq: [              // SEQUENCE      {int: 234},          // INTEGER      {utf8str: 'テスト'}      // UTF8String      ]} ).getEncodedHex();
  41. 41. X.509証明書の ASN.1オブジェクトの生成
  42. 42. X.509証明書 ASN.1の生成は 大体、BouncyCastle、IAIKに似ています。 var o = new KJUR.asn1.x509.TBSCertificate(); o.setSerialNumberByParam({'int': 4}); o.setSignatureAlgByParam({'name': 'SHA1withRSA'}); o.setIssuerByParam({'str': '/C=US/O=a'}); o.setNotBeforeByParam({'str': '130504235959Z'}); o.setNotAfterByParam({'str': '140504235959Z'}); o.setSubjectByParam({'str': '/C=US/CN=b'}); o.setSubjectPublicKeyByParam({'rsakey': rsaKey}); // 拡張も足せます o.appendExtension(   new KJUR.asn1.x509.BasicConstraints({'cA':true})); o.appendExtension(   new KJUR.asn1.x509.KeyUsage({'bin':'11'})); // 署名してPEMにしましょう。
  43. 43. OpenID Connect, OAuth2で使われる JWT、JWSとjsjws
  44. 44. OpenID Connect、OAuth2などのWeb認証プロトコルではJSON形式({attr: 123})の認証情報が改ざんされないよう JWS(JSON Web Signature)や JWT(JSON Web Token)を規定 JSON Web Signature(JWS) JSON形式の何のアルゴリズムで署名したかとかいった署名属性に署名対象 をつけておこなう署名フォーマット。次で詳しく。 JSON Web Token(JWT) JSON形式のデジタル証明書のようなもの。JWSで署名したJWSデータの一 種。
  45. 45. JWSの作り方
  46. 46. JWSの署名アルゴリズム HS256,384,512 - HmacSHA256,384,512 RS256,384,512 - SHA256,384,512withRSA ES256,384,512 - SHA256,384,512withECDSA(NIST P-256,384,521) PS256,384,512 - SHA256,384,512withRSAandMGF1(RSAPSS) none - 署名なし
  47. 47. というわけで、jsrsasignには、 RSA/ECDSA/RSAPSS署名も HMACもあるし、鍵も簡単に使える し、Base64URLエンコーディングさ えあればJWSなんか簡単にできちゃ うぞと!
  48. 48. Base64エンコーディングとは バイナリデータを"A-Z","a-z","0-9","+","/"の印字可能文字にエンコードす る。任意の3バイトが4文字になる。 長さが4の倍数にならない時には末尾に"="をつけて揃える。 メールの添付ファイルや証明書のPEM形式などで使われる Base64URLエンコーディングとは URL表現おいては"+"や"/"は特別な意味を持つのでBase64では具合が 悪いため "+"を"-"、"/"を"_"に変換したもの。 "="は必ず省略する。 JWS,JWTで多用される。
  49. 49. Base64URLエンコーディング変換 ext/base64.js, base64x.js で様々な文字列変換関数を提供 関数:AtoB (例 utf8tob64u)、A、Bには例えば以下が使える s - ASCII文字列 utf8 - UTF8文字列 hex - 16進数文字列 b64 - Base64エンコード文字列 b64u - Base64URLエンコード文字列
  50. 50. で、jsjwsを作りました kjur.github.io/jsjws
  51. 51. jsjwsの特徴 RSA, RSAPSS, ECDSA署名をサポート サポート率では12/13で世界最多!(w) いろんな鍵フォーマットに対応しており簡単 pure JavaScript実装でスマホブラウザでも動く 並列署名JWS-JSもサポート(これも世界唯一?)
  52. 52. アルゴリズムのサポートは世界最多 jsjwsが12/13とサポートアルゴリズムが最も多い。JWS/JWTのJavaScript実 装ではjsrsasignを使うのがほぼデファクト kjur.github.io/jsjws/index_mat.html
  53. 53. jose4jの作者のスライドで引用頂いた Brian Campbellさん:Ping Identityの人、2011年Googleセキュリティ殿堂入り www.slideshare.net/briandavidcampbell/an-introduction-to-the-emerging-jsonbased- identity-and-security-protocols
  54. 54. JWSの生成と検証 jsjwsなら簡単、アルゴリズムを広範囲でサポート // JWS署名生成 JWS.sign(Alg, ヘッダ, ペイロード, 秘密鍵[, 鍵パスワード]); JWS.sign("RS256", '{cty: "JWT"}', '{iss:"aaa",sub:"tom"}',           "----BEGIN PRIV..."); // JWS署名検証 JWS.verify(JWS署名, 公開鍵情報); JWS.verify("eyBhb...", "---BEGIN X509 CERT..."); いろんな形式の鍵を扱えるのでとても便利なはず
  55. 55. で、JWTも作れます と、いってもほぼJWSと同じ。日時をUNIXオリジン時刻で表し面倒なので IntDateクラスを加えました。 IntDate.get('now') - 今のUNIX時刻 IntDate.get('now + 1day') - 24時間後 IntDate.get('now + 1year') - 365日後 IntDate.get('YYYYmmDDHHMMSSZ') - UTC時刻 IntDate.get(1377714748) - UNIX時間(そのまま)
  56. 56. RSAPSSのソルト、JWS、OpenSSLの細かい話 RSAPSS署名とは「ある仮定の下でその安全性が数学的に証明可能であ る」ような RSA署名 実装によるソルト長のデフォルトの違い BouncyCastle - SHA1で20バイト、それ以外は個別に指定 OpenSSL - 特別値(-2): 可能な限り長く(鍵長-ハッシュ長-2) JWSではソルト長=ハッシュ長を想定?でも記載なし 崎村さん、Mikeさんの調整で明記頂ける方向だそう 参考 Twitterでの会話twitter.com/search?q=rsa_pss_saltlen&src=typd tools.ietf.org/html/draft-ietf-jose-json-web-algorithms-16
  57. 57. 補足
  58. 58. Node.jsとjsrsasignとjsjws 最近とても流行っているServer Side JavaScript 私はNode.js対応していないが 海外のいろんな人がNode.js対応してnpmリポジトリに置いてる
  59. 59. 関連npmパッケージ で検索してみてください。 jsjws - 高速なバイナリRSAつきjsjws cryptico - RSAによる簡単な暗号化、署名 bignumber-jt - RSAによる簡単な暗号化、署名 node-bignumber - RSAによる簡単な暗号化、署名 burningpig-encryption - RSAによる簡単な暗号化、署名 使っているjsrsasign/jsjwsライブラリが古かったり、使いたいメソッドが公開さ れていない事が 多いので、自分でnpmを作った方がいいかなと思ってます。 npmjs.org
  60. 60. W3C Web Cryptography API 仕様としてはこんなのも作られつつあり、PKCS#11インタフェースや各種暗号 をサポートしそうだが 実装はいつになるか見通しが無さそう。 www.w3.org/TR/WebCryptoAPI
  61. 61. セキュリティ考察は必要 確かに秘密鍵を素で扱えているようなものなので、注意する必要はあるが、 今は他に手が無さそう。 www.matasano.com/articles/javascript-cryptography
  62. 62. 開発してみたくなったら サイトに来て下さい
  63. 63. サイトの歩き方 その他、gitリポジトリの"test"フォルダにあるQUnitのテストコードはサンプル として参考になるかと思います。 http://kjur.github.io/jsrsasign/ http://kjur.github.io/jsjws/
  64. 64. ちょっとデモなど
  65. 65. クロージング
  66. 66. 果てしない戦いは続く 今後、対応してみたい野望 PKCS#7/CMS 署名、暗号データに対応してみたい ということはS/MIME署名/暗号メールに対応してみたい SSHだってChrome JavaScriptからできる時代なので SMTPクライアント実 装してS/MIME署名暗号メールを ブラウザから送ってみたい DSA署名に対応したい(PGPのJavaScript実装が既にこれに対応) JCEライクなCipherクラスを実装し共通鍵暗号ラッパーに 対応したい XML署名/暗号に対応したい PDF署名に対応したい(JavaScript PDF生成は既にある) 当然の事ながらCAdES/XAdES長期署名に対応してみたい jsrsasign, jsjwsのNode.jsパッケージ作成
  67. 67. まとめ jsrsasignは最初、RSA署名だけだったけど今は違う 今は、BouncyCastleみたいな暗号ライブラリ 意外と世界中いろんなところで使われている 署名,ハッシュ,HMACがJava JCEみたいで使いやすい どんな秘密鍵、公開鍵でも簡単に扱える ASN.1関係も充実 OpenID Connect用のJWS, JWTにも対応(jsjws) JWTのJavaScript実装ではjsrsasignはデファクト JWTの署名アルゴリズム対応はかなり世界最強 スマホブラウザでも無問題で動く、遅いけど
  68. 68. おしまい ご清聴ありがとうございました
  69. 69. リンク集 jsrsasign - jsjws - http://kjur.github.io/jsrsasign/ http://kjur.github.io/jsrsasign/

×