自堕落な技術者の日記

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

SUN

Java SignatureクラスのinitVerifyの問題(その2)

自堕落な技術者の日記 : Java SignatureクラスのinitVerifyの問題 - livedoor Blog(ブログ)
どうもdigitalSignatureのkeyUsageビットが立っていないとエラーになるようなんです。


今日はinitVerify問題の続きを書きます。

X.509公開鍵証明書にはkeyUsage拡張というものがあって、署名用、暗号用、証明書の発行用など鍵をどんな目的で使ってよいのかを目的のビットを立てることにより定めることができます。

RFC 3280 4.2.1.3 Key Usage より
KeyUsage ::= BIT STRING {
digitalSignature (0),
nonRepudiation (1),
keyEncipherment (2),
dataEncipherment (3),
keyAgreement (4),
keyCertSign (5),
cRLSign (6),
encipherOnly (7),
decipherOnly (8) }


証明書やCRL発行以外のデータへのデジタル署名用としては digitalSignatureとnonRepudiationを両方か片一方か使うことができるのですがざっくりとした使い分けはこんな感じ。


  • digitalSignature(デジタル署名)ビット

    署名や認証など広い意味での署名のために使われます。ドキュメント、データ、プログラム(コードサイニング)への署名はもちろん、SSLサーバー証明書、SSLクライアント認証など幅広く使われます。証明書やCRLの発行のための署名には別のビット(keyCertSign,cRLSign)を使います。

  • nonRepudiation(否認防止)ビット

    電子文書による契約や申請など、一般に自然人が意思をもって署名を行い、後になって私は「こんな文書に署名などしていない。身に覚えがありません。」などと言い逃れできないようにする(=否認防止)ための署名のために使われます。自分に成りすまさて悪いことされないように鍵の管理は厳重にしなければなりません。鍵を使う前にはICカードを挿す、PINコードを打つなど操作確認のための能動的な行為がある方が良いですし、自動的に行われる署名にはできれば使わない方がいいかもしれません。



Java JCEを使って署名検証を行うためのコードはJythonで書くとざっくりこんな感じ。

cert = CertificateFactory.getInstance("X.509").\
generateCertificate(FileInputStream("aaa.cer"))

sig = Signature.getInstance("SHA1withRSA", "SunRsaSign")
sig.initVerify(cert)
sig.update(署名対象byte配列)
print "署名検証結果:", sig.verify(署名値byte配列)


今回問題が起きたのは、JavaのSignatureクラスで署名検証のためにnonRepudiationビットのみしか立っていない証明書を使って初期化(initVerify)した場合に"Wrong key usage"という例外により初期化エラーになるというものです。

JCEプロバイダによる違いはあるのか?



initVerify(Certificate)でエラーが起きるのが、デフォルトで使われがちなSunRsaSign、SunJSSEなどのJCEプロバイダに固有の問題なのかプロバイダに共通の話なのか、ちょっと調べてみました。















JCEプロバイダアルゴリズム結果
SunRsaSign 1.5SHA1withRSA×
SunJSSE 1.6SHA1withRSA×
SunMSCAPI 1.6SHA1withRSA×
BC 1.36SHA1withRSA×
BC 1.36SHA1WithRSA/ISO9796-2×
BC 1.36SHA1withRSA/PSS×
IAIK 3.142SHA/RSA×
IAIK 3.142SHA/RSA-ISO9796-2×
IAIK 3.142SHA1withRSAandMGF1×
Entrust 7.2SHA/RSA×
Entrust 7.2RSA-PSS×
IBMJCE 1.2SHA1withRSA×


全部きれいに「×」でdigitalSignatureビットが無くnonRepudiationビットしか立っていないような署名署名者証明書の場合には Signature.initVerify(Certificate) で初期化した場合に必ずエラーになることがわかりました。

実装側での問題回避策


まぁ、当たり前ですが回避策として初期化には証明書を使わずに証明書から公開鍵を取り出して使うという方法があります。

sig = Signature.getInstance("SHA1withRSA")
sig.initVerify(cert.getPublicKey())
sig.update(署名対象byte配列)
print "署名検証結果:", sig.verify(署名値byte配列)


証明書プロファイル



RFC 3280では一般的な署名やメールの署名などでは digitalSignature and/or nonRepudiationのビットを立てると書いてあるんですが、少なくともJavaではnonRepudiationビットだけであると検証エラーになってしまうので証明書プロファイルを決める際に注意しなければいけません。

RFC 3280 4.2.1.3 Key Usage
For example, when an RSA key should be used only to verify signatures on objects other than public key certificates and CRLs, the digitalSignature and/or nonRepudiation bits would be asserted.


相互運用性のためにはnonRepudiationビットだけを立てた証明書を発行するのは止め、digitalSignatureとnonRepudiationビットの双方を立てることで否認防止用証明書と解釈した方が良いかもしれません。

今日の教訓



結局のところnonRepudiationしか立っていない証明書もらっちゃったら「気をつけましょ、、、」ってことで、、、、(^^;




Java SignatureクラスのinitVerifyの問題

スペインからCAdES-BES署名が送られてきたので検証してみました。すると、ウムム、エラーです。

調べてみると

・署名に使った署名者の証明書のkeyUsageにはdigitalSignatureは無く
 nonRepudiationしかない

Signature.initVerify(cert)で上記の検証用証明書を設定すると
 「Wrong key usage」のメッセージと共に例外が発生

てなところのようです。使われているJCEプロバイダはSunJSSEでした。
どうもdigitalSignatureのkeyUsageビットが立っていないと
エラーになるようなんです。
今回は仕方ないのでSignature.initVerify(pubkey)で公開鍵を設定
することにより初期化するようにしました。

時間があるときに他のJCEプロバイダならどうなのか
調べてみようと思います。

署名に使った証明書はスペインの国民IDのスマートカードによるものだそうで適格証明書(Qualified Certificate)みたいです。実物で本物のbiometricInfo拡張のある証明書をゲットできてかなりうれしい、、、、、スペイン独自のpersonalDataInfo. (2.16.724.1.2.2.4.1)拡張なんかもあったりします。

Debian UbuntuのSun Javaパッケージ

元々DebianやUbuntu使いではないので知らなくて仕方なくずっとGNU Java???を使っていたんですが、ちゃんとsun-java5、sun-java6なるパッケージがあるんじゃないですか〜〜〜〜っ。すみません、、、無知で、、、、

<リンク>

http://packages.qa.debian.org/s/

http://packages.qa.debian.org/s/sun-java5.html

http://packages.qa.debian.org/s/sun-java6.html

Ubuntu、Sun Sparc Fireサポートへ - Debian向けJava SE 5パッケージ配布も

http://journal.mycom.co.jp/news/2006/05/31/342.html

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

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