ハードウェアセキュリティモジュールのPKCS#11 APIにPKCS#11 Java Wrapperを使用してDSAでSHA-256ハッシュに署名したいとします。この目的のために、メカニズムCKM_DSAを選択し、対応するDSAキーをトークンからロードし、データ(バイト配列として読み取られた)を署名させた。私がテストに使う鍵は、1024ビットの長さです。OpenSSLでPKCS#11によって生成されたDSA署名の確認
すべてが正常に動作するようです:キーがロードされ、Session.sign()は長さ40のバイト[]配列を生成する。これは、PKCS#11言う仕様に対応:
」をするためにこの機構の目的のために、DSA署名は、DSAの連結に対応する40バイトの文字列、 は、それぞれ最上位バイトを占め、rおよびsの値である。」は
が今は使用してこの署名を検証しますopenSSL、すなわち、使用する:
openssl dgst -d -sha256 -verify ${PUBLIC_KEY} -signature signature.der <raw input file>
このI
a)はOpenSSLの
Bを使用して署名を作成した場合に動作が)はBouncyCastleを使用して署名を作成し、ASN1符号化されたDER配列として結果をコード化します。
今、私はPKCS#11署名で同じことをしたいと思います。私の質問は:どのようにこの40バイト配列をフォーマットするのですか?私は、次のことを試してみました:
//sign data
byte[] signedData = this.pkcs11Session.sign(dataToSign);
//convert result
byte[] r = new byte[20];
byte[] s = new byte[20];
System.arraycopy(signedData, 0, r, 0, 20);
System.arraycopy(signedData, 19, s, 0, 20);
//encode result
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(new ASN1Integer(r));
v.add(new ASN1Integer(s));
return new DERSequence(v).getEncoded(ASN1Encoding.DER);
符号化部は、私はRを生成してはBouncyCastleと別のソフトウェアキーで直接sの場合、それは動作しますので、正しいと思われます。さらに、opensslは入力形式を受け入れますが、エラーが発生して検証が失敗することがあります。検証に失敗することもあります。
したがって、私はPKCS#11署名のrとsへの変換が間違っていると仮定します。誰かが間違いを見つけるのを助けることができますか?
完全なスタックトレースを要求したコメントを含むコメントが削除されました。完全なスタックトレースと、いくつかのテストデータとキーを提供してください。 –
2番目の配列のコピーは、19ではなく20番目の位置で開始してはいけませんか? rの最後のバイトが2回あり、sの最後のバイトを取得していないようです。 – bartonjs