2017-04-19 69 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

相关问题