実装の詳細により、ハッシュと署名の生成を分割する必要があります。「NONEwithRSA」署名アルゴリズムを使用してこれを達成しようとしました。
これは基本的な作業例です:
public void rsaSignatureIntegrityTest() {
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(2048, new SecureRandom());
KeyPair pair = gen.generateKeyPair();
byte[] digest = MessageDigest.getInstance("SHA-256").digest(MESSAGE);
Signature signer = Signature.getInstance("NONEwithRSA");
signer.initSign(pair.getPrivate());
signer.update(digest);
byte[] signed = signer.sign();
Signature verifier = Signature.getInstance("SHA256withRSA");
verifier.initVerify(pair.getPublic());
verifier.update(MESSAGE);
verifier.verify(signed);
}
これを実行すると、verifier.verify()
メソッドは Signature 例外をスローします。
java.security.SignatureException: Signature encoding error
at sun.security.rsa.RSASignature.engineVerify(RSASignature.java:204)
at java.security.Signature$Delegate.engineVerify(Signature.java:1219)
at java.security.Signature.verify(Signature.java:652)
at testing.rsaSignatureIntegrityTest(testing.java:38)
...
Caused by: java.io.IOException: Sequence tag error
at sun.security.util.DerInputStream.getSequence(DerInputStream.java:297)
at sun.security.rsa.RSASignature.decodeSignature(RSASignature.java:229)
at sun.security.rsa.RSASignature.engineVerify(RSASignature.java:195)
... 26 more
検証者オブジェクトは、署名者オブジェクトによって生成されていない何らかの DER エンコード構造を期待しているようです。
これを機能させる方法について何か提案はありますか?
疑われているように、RSA 署名は、ハッシュ oid を含むラップされたダイジェスト値で生成されます。bouncycastleを使用すると、これは非常に快適に実行できます。
例:
public void rsaSignatureIntegrityTest() {
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(2048, new SecureRandom());
KeyPair pair = gen.generateKeyPair();
byte[] digest = MessageDigest.getInstance("SHA-256").digest(MESSAGE);
Signature signer = Signature.getInstance("NONEwithRSA");
signer.initSign(pair.getPrivate());
signer.update(wrapForRsaSign(digest, "SHA-256"));
byte[] signed = signer.sign();
System.out.println(Base64.getEncoder().encodeToString(signed));
Signature verifier = Signature.getInstance("SHA256withRSA");
verifier.initVerify(pair.getPublic());
verifier.update(MESSAGE);
verifier.verify(signed);
}
private byte[] wrapForRsaSign(byte[] dig, String hashAlgo) {
ASN1ObjectIdentifier oid = new DefaultDigestAlgorithmIdentifierFinder().find(hashAlgo).getAlgorithm();
ASN1Sequence oidSeq = new DERSequence(new ASN1Encodable[] { oid, DERNull.INSTANCE });
ASN1Sequence seq = new DERSequence(new ASN1Encodable[] { oidSeq, new DEROctetString(dig) });
try {
return seq.getEncoded();
} catch (IOException e) {
throw new DigestException(e);
}
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加