jsrsasignとは
2010年ごろ、スタンフォードの学生さんであるTom Wooさんという人のJavaScriptでRSA暗号化できるコードを見つけ、自分はPKIや電子署名を専門にしていたので「JavaScriptでRSA署名できたら面白いな」と思い、2010年6月に、ほんのRSA署名単機能のライブラリとして公開したのが jsrsasign です。当時のはしゃぎっぷりはブログでこんな感じ。 小躍りしてツイートしてたのはこんな感じ。
Kenji Urushima@kjurBigIntegers and RSA in JavaScript http://www-cs-students.stanford.edu/~tjw/jsbn/ マジか、JavaScriptでRSA暗号してるよ。
2010/05/24 07:17:03
Kenji Urushima@kjur秘密鍵フォーマットもPKCS#1/8があつかえるといいかもしんない。そのためにも簡易ASN.1だ BigIntegers and RSA in JavaScript http://www-cs-students.stanford.edu/~tjw/jsbn/
2010/05/24 07:22:46
Kenji Urushima@kjur実は昨日JavaScriptでRSASSA-PKCS1-v1_5 RSA署名できたのだ。 任意の文字列にSHA1withRSAで署名できると思う。DigestInfo生成は文字列連結なので簡易ASN.1を作りたいとこ♪コレ活用→ http://bit.ly/9dUYXP
2010/05/28 17:04:02
その後、ASN.1ライブラリ、X.509証明書、CRL、CMS SignedData、タイムスタンプ、CAdES-BES/EPES/T、OCSP、CSR、共通鍵暗号、楕円曲線暗号、RSA-PSS署名、DSA署名、JSONのJWS、JWT、JWKの対応など、自分が欲しいと思う機能を少しずつ建て増しをして10年になります。多くの個人のオープンソースプロジェクトは1年くらいで終わってしまうそうですが、まぁ、なんとか自分のために追加開発やメンテナンスを続けています。
このライブラリが特徴的なのは、
- なんでも入っている
- 一つライブラリに多くのPKI、暗号の機能がつめこんであります。 Swiss Army Knife(スイスの十徳ナイフ)スタイルというそうです。 自分がものぐさなので、これをロードしさえすれば何でも試せるように作りました。
- とにかく使い方が簡単
- どんな秘密鍵でも公開鍵でも自動判定してロードできるようになっていたり、ASN.1 DER構造の中身に簡単にアクセスできたり、面倒くさいことはなるべくライブラリに任せてできるようになっています。証明書やタイムスタンプなどはJSONのプロパティから簡単につくることもできます。共通鍵暗号も簡単です。APIの構成はJavaのBouncyCastleライブラリやIAIKライブラリなどのJCEアーキテクチャを参考にしているので、それを知っていればさらに使いやすいでしょう。自分がものぐさだから(二回目)、極力短いコードでいろんなことができるようになっています。
- ドキュメント、サンプルが非常に豊富
- ライブラリはあってもAPIドキュメントがなくてどんなAPIがあるのわからなかったり、BoucyCastleみたいにメソッドはわかるけど呼び出し方がわからないなどのことが無いようにAPIドキュメントの記述が充実しており、APIドキュメント中に例も入れています。また、Wikiなどの入門解説ページや、多数のオンラインでも試せるサンプルコード、テストコードがあり、自学習でもかなり何とかなると思います。APIが前提知識最小でも行けるように工夫してますので。
- 環境依存がほぼ無い、他のパッケージの依存がない
- JavaScriptが動く環境であればどこでも動作します。古いブラウザでもほとんどの機能は動作しますし、Node.jsでも動きます。npmパッケージでも公開されていますし、CloudFlareなどのCDNからも利用できます。必要なサードパーティの関数は含まれており、他のライブラリ、パッケージに全く依存しておらず単独で使えます。Nodeの中でOpenSSLに依存していることもありませんし、(ブラウザ互換性でいつも悩まされる、この先どうなるかもわからない)W3C Web Cryptography APIを使っているわけでもありません。
- いろんなツールがすぐ使える
- 自分でプログラミングしなくても、オンラインで公開しているツールで証明書を発行したり、鍵ペアを生成したり、デジタル署名の生成や検証したり、JWTを生成したり、いろんなことができます。Nodeで実装されたいろんな便利なPKI関連ツールもついています。
- 速いとは言えない
- 自分がPKI関連のいろんなことを少ないコードで簡単にテストするために作っていますので、高速に動作することを目的にしていません。数百万のトランザクションを処理したいといった目的なら他のライブラリを使う方がいいでしょう。
jsrsasignの歴史を振り返る
10年だもの、まぁ、いろいろありますよ。自分のためにちょっと歴史を振り返ってみます。
- 2010年6月:v1.0:jsrsasign初版公開。RSA署名だけ。
- 2012年4月:v1.2:公開リポジトリをGitHubに移行。
- 2013年4月:v2.0:PKCS#1 PEMなどの鍵のロード機能がつき始める。 JavaライクなSignature、MessageDigestクラス、ASN.1エンコーダー、X.509証明書エンコーダー、RSA-PSSサポートなど
- 2013年5月:v3.1:暗号化されたPKCS#5鍵のロードのサポート
- 2013年6月:v4.0:ECDSA署名サポート
- 2013年9月:v4.1:PKCS8など柔軟な鍵ロード用クラス KEYUTIL を追加
- 2013年10月:v4.2:DSA鍵、署名のサポート
- 2014年4月:v4.5:CMS SignedDataサポート
- 2014年5月:v4.6:RFC 3161 Timestampサポート
- 2014年7月:v4.7:RFC 5126 CAdES-BES/EPES/Tサポート
- 2015年6月:v4.8:NodeJS npm、JSON JWS、JWK、JWTサポート
- 2015年10月:v5.0:CSRサポート、便利なNode.JSスクリプトの追加
- 2016年9月:v6.0:OCSPサポート
- 2016年11月:v6.2:識別名のmulti valued RDN、RFC 2253 LDAP識別名文字列表現のサポート
- 2017年6月:v8.0:コードのスリム化、長期間非推奨(Deprecated)だった関数の削除
- その後、細かい機能追加や脆弱性指摘対応などが続き現在に至る
jsrsasignはどれだけ使われているか
自分の趣味でやってる調査のために開発したライブラリですが、Node.JSのパッケージ npm で公開した2015年あたりから利用者ダウンロードが増えています。github.comからのダウンロードや、勝手に行われている公開CDNからの利用もあると思いますが、npmパッケージのダウンロード数だけでいうとnpm-stat.comさんのダウンロード数グラフを見てみるに、2018年あたりからブリブリ増えてしまっており、2019年あたりからサチりはじめ、それでも最近の月間ダウンロードは60万件超、先月は70万を超えてしまいました。npmでは他のパッケージの依存関係を書けるのですが、2020年7月現在で379ものnpmパッケージのプロジェクトがjsrsasignに依存していることがわかります。とほほ。
jsrsasignは自由に使ってもらっていいですが、ライセンスは放棄はしていないので、ライセンス掲載の義務はあり、たまにエゴサーチでPDFで検索してみると、いろんな製品の中でも使われちゃってることがわかります。
- 独シーメンスのConnect X300というビル制御システムで使われていたり [OSS一覧]
- EUの公共向けシステムらしいCITADELで使われていたり [OSS一覧]
- セールスフォースのSalesforce DMPで使われていたり [OSS一覧]
- ソニーのビデオプロジェクターLSPX-A1、映像製作機材XDS-1000、PDW-HR1等で使われていたり [LSPXガイド] [XDS OSS一覧] [PDW OSS一覧]
- キヤノンの複合機 iR-ADV や 印刷機 imagePRESS C165 で使われていたり [iRADV8505 OSS一覧] iRADV4500 OSS一覧] [imagePRESSガイド]
- 横川電気のSMARTDAC+というデータ測定機器で使われていたり[マニュアル][英語]
- VERINTという通話記録機器など提供する会社の製品で使われていたり [OSS一覧]
- Oracle Blockchain Platformで使われていたり [ライセンス情報]
ユーザが増えた悩みの始まり
最初は、「自分の調査のために趣味で維持しているライブラリがみなさんの役にたって、使ってもらえてるなら良いことだなぁ。これからも趣味で自分の必要そうな機能は追加していこうかなぁ、、、」で済んでたんですが、最近ユーザーも増えてそうも言ってられなくなってきたんです。
そもそも、jsrsasignは MITライセンスの下で無償、無保証で配布されています。もし、セキュリティ脆弱性やバグがあっても、私には修正する義務はないし(とはいえ、指摘されたら直すわけですが)、オープンソースなので問題があれば好きに修正して使っていただいていいわけです。もちろん修正コードをもらえれば、それは反映してすぐに公開します。
そんな中おきたThe RegisterやUsenixの指摘
2020年5月にITセキュリティのニュースサイトであるThe Registerで 「What happens when the maintainer of a JS library downloaded 26m times a week goes to prison for killing someone with a motorbike? Core-js just found out」という記事が掲載されました。JavaScriptのバージョンの違いを吸収するためのCore-jsという有名なライブラリがあって、その開発者がバイクで交通事故を起こして被害者の方が亡くなり収監されて、ソフトウェアのアップデートが滞っており問題だというものでした。
この記事の中で、私のjsrsasignも、2018年4月から2020年まで更新されてないと指摘をされてしまいました。
(記事引用)指摘された問題は、Minervaと呼ばれるECDSA署名のタイミング攻撃により処理時間を大量監視していれば秘密鍵が復元できる可能性があるというもので、元々、楕円曲線暗号の部分はBitcoin-JSを使っており、自分のコードではないので、調査するにしてもかなり時間がかかる根の深い問題でした。また、自分は本業の方も忙しい時期だったのでなかなか調査もできず、誰からも修正コードの支援をしてもらえないままでいました。jsrsasignは大量のトランザクションで使われることもあまりないし、攻撃の実現はかなり低いと考えていました。他の簡単に回答できるものには回答していましたが、根が深いのでこの問題は手付かずにしていたのです。
Another JavaScript cryptographic library known as jsrsasign faces a similar challenge: its maintainer, Kenji Urushima, hasn't been active since April 2018. Programmers who use the software have expressed concern about the lack of communication and an unaddressed vulnerability, noting that 350 npm projects depend on the library, including some by Microsoft and Mozilla,
(抄訳)
jsrsasignとして知られている別のJavaScript暗号ライブラリも同様の課題に直面している。その管理者である Kenji Urushima は、2018年4月から活動していない。このソフトウェアを使用しているプログラマは、対話の欠如と対応されていないある脆弱性について関心を寄せている。注目すべきは、MicrosoftやMozillaを含む350のnpmプロジェクトがこのライブラリに依存しているという事である。
おそらくこの記事をうけて、USENIXという団体の機関紙のコラム「Who Will Pay the Piper for Open Source Software Maintenance? Can We Increase Reliability as We Increase Reliance?(誰がオープンソースソフトウェアの保守の費用を負担するのか?(オープンソースの)依存が増える中、信頼性を上げることできるのか?」の結論でも、jsrsasignを「(開発を)撤退したソフトウェア」として取り上げられてしまいました。
やっとMinerva脆弱性の修正
jsrsasignの根深い問題の調査まで手がまわらない状態が続いていたのですが、プライベートで慌ただしい時期がようやく終わりかかり落ち着きだした2020年4月、Node.JSのパッケージマネージャーを管理するnpmのセキュリティチームからもMinervaの脆弱性指摘が来てしまい、いよいよ直さざるをえない状況になりました。他の人が作ったコードを解析し、修正し、テストケースを作成して確認し、修正リリースを出しました。[勧告]
そしてまた別のMalleabilityに関する脆弱性指摘が3つも
2020年6月に Antonio de la Piedra さんから、3つのmalleability(展性)に関する脆弱性の指摘を受けてしまい、初めてUS-CERT、MITREの脆弱性データベースにCVE登録されてしまいました。3つのうちの1つは、npm のセキュリティチームからも対応依頼が来ました。「malleability(展性)」とは、金属を叩いて延ばしても破壊されずに広げることができる性質のことを言うのですが、ソフトウェアの世界では、同じ意味のデータを別の表現ができるという事をmalleabilityと呼んでます。例えば、10進数で数値の12345という値があったとして、先頭にゼロを幾つかつけて00012345としても値は同じであるといった事です。
暗号では、大きな数値を使って暗号文、署名値など表現することが多いですが、 指摘された3つの脆弱性は簡単には以下のようなものでした。
- CVE-2020-14966 ECDSA署名の署名値が、前述のようなゼロを先頭に足した値を使ったものでも正しい署名として受け入れてしまう等。(CVSS3.X 7.5, CVSS2.0 5.0)
- CVE-2020-14967 RSA暗号の暗号文が、前述のようなゼロを先頭に足した値を使ったものでも復号ができてしまう。(CVSS3.X 9.8, CVSS2.0 7.5)
- CVE-2020-14968 RSA-PSS署名の署名値が、前述のようなゼロを先頭に足した値を使ったものでも正しい署名として受け入れてしまう。(CVSS3.X 9.8, CVSS2.0 7.5)
6月頃は仕事もプライベートも落ち着いていたので、週末や夜に対応の時間を取ることができ、問題の調査をし、コードを修正し、Antonioさんにもらったテストコードで問題なくなった確認し、2週間くらいで修正リリースし、セキュリティアドバイザリを公開しました。 [勧告1] [勧告2] [勧告3] かなり短期に対応できたかと思います。ちなみに、RSA-PSSはDaveさんが提供してくれたコードで、自分で解析して修正しなければならないので厄介でした。ECDSAについては、署名値が厳密なASN.1 DER構造であることをチェックしていなかったために起きた問題で、その厳密なチェックをする機能を追加するのにテストケースが多すぎて骨が折れました。
というわけで、オープンソースのライセンスで、現状有姿、無保証で提供するという条件で利用してもらっているにもかかわらず、結局、義務的に直さざるを得ず、問合せ対応や、報告者への対応、セキュリティアドバイザリの作成などしなければならない状況になっているのです。ソフトウェアの開発や保守でお金をもらっているわけでもないのに、とてもモヤモヤします。もちろん、本当に攻撃の影響を容易に受けてしまうような深刻な脆弱性については、何とか時間を作って急いで修正します。でも、「自分のために作ったライブラリを他の人が喜んで使ってくれるなら開発にかかったコストも要求せず、無料で、現状有姿で提供しましょう。」と言っただけなのに、多くの土日や夜まで潰して手厚いサポートまでタダで求めてくるのは「それは善意の搾取です!!!」とガッキーのように叫びたくなります。
同じオープンソースの暗号ライブラリでも、OpenSSLのように多くのメンバーが開発に関わっていて、修正パッチの提供も有志がやってくれるような状況なら、脆弱性指摘を対応する体制も作れますが、私一人で開発しているような状況なので、仕事やプライベートの都合でタイムリーに脆弱性対応できないケースがあります。そんな手厚いサポートを求められても困るのです。
私は、製品のセキュリティインシデントレスポンスチームであるPSIRTの仕事もしていたので、外部から脆弱性を指摘された場合に、しかるべき機関と調整しながら脆弱性対応する必要があることもわかっています。ただ、こうしたライブラリの場合は厄介で、よく使われる機能も、そうでない機能も様々取り揃えてライブラリを構成しているので、問題への影響が大きいのか小さいのかという判断をつけにくいです。そのため、リスクが高かろうが低かろうが「直せ」と要望が来てしまいます。なんか、段々、オープンソースを公開するのが面倒くさくなってしまいました。
そして寄付金を募ることにしました
「お金もらってるわけでもないのに文句言うな」とモヤモヤした気持ちを抱えたまま、jsrsasignを維持し続けるのもモチベーションが持ちそうにないので、ふと「寄付金」を受け付けてみてはどうかなぁ、、、と思いました。寄付金制度を導入すれば、どれだけの人がこの一人プロジェクトを応援してくれてるのかわかるし、「こんなに応援してくれてるんだから、ちょっと頑張らなきゃなぁ」という気持ちになるかもと思ったわけです。調べてみると、
- (1) GitHubのスポンサー制度(毎月いくらとか設定して応援してもらえる。日本の口座もOK)
- (2) Bitcoin、Bitcoin Cashなどの仮想通貨による寄付(自分の口座が放置されてた)
- (3) Paypalによる寄付 (日本の金融機関ではできない)
- (4) Open Collective (日本ではかなり敷居が高そう)
- (5) Buy Me A Coffee (これも面倒くさそう。でも決済がGitHub Sponsorsと同じStripeだから可能性あるかな)
今後、そのうちどうするか
と、まぁ、サポートや脆弱性対応のモチベーションは何とか寄付金で自分をだましだましやろうと思うんですが、自分もいい歳なので、自分が開発、サポートができなくなった時にどうするかですよね〜〜。急遽、長期入院などして何もできないことがあるかもしれませんし。GitHubでは、後継者を指定して何かあったとき、その人に管理を譲ることができる機能があるんですが、こんなわけのわからないソフトのメンテと問合せサポートを他人に押し付けるわけにもいかないので、多分自分が開発できなくなったら一代限りで終わりなんでしょうねぇ。ソースは全てリポジトリにあるので、引き継いでくれる人が世界のどこかから出てくるのかもしれませんが、完全にお任せで好きにしてもらうのが良いんじゃないかと思ってます。
ただ、自分に何かあったとき、「このプロジェクトは今後一切、メインの開発者がサポートできなくなりました。」と伝えてあげる必要はあるなぁと思っています。娘か知り合いに託すしかないのかなぁ。そうしないと、また The Registerの記事のような騒ぎになってしまうので、、、なんか、デジタル遺品とか終活ノートみたいな話ですね。
趣味でちょっと、好きなものだけ好きなように開発したかっただけなのになぁ、、、なんでこんなことになっちゃったのかなぁ、、、
こんなこと書いちゃってますが、開発はぼちぼち続けていきますよ。本人はいい加減な人間なので、そんなに気に病んでるわけでもないので、どうかお気になさらずに。 なんか、愚痴っぽい話につきあってもらってすみません。今日はこの辺で。
私も知らない間に何らかの形で利用させていただいているかもしれませんね。
OSS, 本来なら「てめぇで直せよ!ソース公開してるだろ!文句あるなら fork でもして自分で直せ」でいいと思うんです…
ただ、ある程度利用者が多くなった repo であれば、New Organization をつくってそこに repo を移行させて共同メンテナーを何人か入れるか、collaborators を指名するのもありかと思います。