欲しいもの
切り離されたデジタル署名を標準形式(CMS / CAdES-EPES)で作成します。
今デジタル署名を作成する方法
ドキュメント(SHA-256)からハッシュを作成し、ハッシュアルゴリズムIDを取得して、すべてをメッセージに入れ、スマートカード(JavaCard)に送信します。このメッセージ(RSA-512)に対して分離された署名が生成され、返送されます。コードを使用して、純粋なJava(これまでのところBouncyCastleはありません)を使用してこの署名を検証できます。
RSAPublicKey pubK = (RSAPublicKey) cert.getPublicKey();
Signature sig = Signature.getInstance("SHA256withRSA", "BC");
sig.initVerify(pubK);
//load signed file and update sig
...
sig.verify(signedMessage)
問題
私の目標は、すでに署名されたデータからCMS(PKCS#7)署名を取得することです。ただし、ここで説明したように、証明書を持っている場合、PKCS#1をPKCS#7に変換するにはどうすればよいですか?-署名された属性があるため、CMSに「変換」するのはそれほど簡単ではありません。さて、とにかく試してみたいとしましょう(バックアップソリューションを用意するためだけに)。まず、BouncyCastleを使ってみました。ただし、すでに署名されたデータを使用し、主キーにアクセスできない場合(スマートカードにあるため、エクスポートできません)、それを行う方法を見つけることができませんでした。だから私はこのようなネイティブJavaライブラリでそれを試しました:
X500Name xName = X500Name.asX500Name(cert.getSubjectX500Principal());
BigInteger serial = cert.getSerialNumber();
AlgorithmId digestAlgorithmId = new AlgorithmId(AlgorithmId.SHA512_oid);
AlgorithmId signAlgorithmId = new AlgorithmId(AlgorithmId.RSAEncryption_oid);
//SignerInfo
SignerInfo sInfo = new SignerInfo(xName, serial, digestAlgorithmId, signAlgorithmId, signatureBytes);
//Create ContentInfo
ContentInfo cInfo = new ContentInfo(ContentInfo.DATA_OID, new DerValue(DerValue.tag_OctetString, dataToSign));
//create PKCS7 signature
PKCS7 p7 = new PKCS7(new AlgorithmId[] { digestAlgorithmId }, cInfo,
new java.security.cert.X509Certificate[] { cert },
new SignerInfo[] { sInfo });
//Write PKCS7 to bYteArray
ByteArrayOutputStream bOut = new DerOutputStream();
p7.encodeSignedData(bOut);
byte[] encodedPKCS7 = bOut.toByteArray();
このアプローチは正直なところ「正しくない」ように思われ、PKCS7.verify()メソッドを使用して検証することもできませんでした(nullが返され、検証に失敗し、例外はスローされません)。
だから私の質問は:
- JavaCardからCMS署名を直接取得する方法はありますか?
- (秘密鍵へのアクセスなしで)署名者証明書のみを使用して、すでに生成された署名からCMS署名を作成することは可能ですか?
- 上記の「変換」コードに問題がありますか?
- 切り離された署名を検証するために使用できるツールを知っていますか?(私の結果を確認できるようにするため)
Aは2週間前から答えを探していましたが、私は本当に必死です。あらゆる種類の情報/ヘルプをありがとう。