2017-04-19 50 views
1

由於某些實現細節,我需要拆分哈希和簽名生成。我試圖用'NONEwithRSA'簽名算法來實現這一點。使用java安全提供程序進行單獨的摘要和簽名

這是一個基本工作示例:

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()方法拋出一個簽名異常:

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編碼結構,這不是由簽名者對象生成的。

有關如何使其發揮作用的任何建議?

回答

1

可疑的是,使用包含摘要值(包含散列oid)生成RSA簽名。使用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); 
    } 
} 
+1

參考:步驟2 [EMSA-PKCS1-v1_5中](https://tools.ietf.org/html/rfc3447#section-9.2)。請注意,在這種情況下,DER編碼相當於添加了一個固定的前綴,如第43頁注1中所示。 –

+0

@ dave_thompson_085感謝您的參考,我只是對其進行了反向設計! – Horst

相關問題