2017-10-04 110 views
-1

例如我已经生成的签名:Openssl的rsault验证Java实现

$ openssl rsautl -sign -inkey private_key.pem -keyform PEM -in data > signature 

然后,如果我想验证它,我只是做:

$ openssl rsautl -verify -inkey public_key.pem -in signature -pubin

和输出将是我的数据编码在第一步。

所以问题是,如何用Java实现这种验证? 我可以以某种方式或以其他方式使用签名类吗?

P.S.还有一个问题:据我所知,公共密钥不能用于解密rsa签名,但无论如何,在我的例子中它是用于解决这个问题的。那么任何拥有公钥的人都可以解密我的信息?

由于

+0

您创建使用私钥(你签名的数据)与你的公钥的签名。因此,任何拥有公钥的人都可以解密我的消息 - 不,任何拥有公钥的人都可以验证签名。 – gusto2

+0

对于你的问题 - 你可以尝试为RSA签名验证稍微上网(https://bits.enigmabridge.com/articles/2016-10/rsa-signatures-in-java8-without-bouncy-castle.html)仍然 - questino仍然使用openssl使用的摘要(SHA256?)和填充(PKCS1.5?OAEP?) – gusto2

+0

@ gusto2:OAEP不适用于签名。 OpenSSL rsautl默认为PKCS1-v1_5,跳过了ASN.1 SEQUENCE步骤,但也支持none和x9.31,而RSA的pkeyutl可以正确执行PKCS1-v1_5并且还支持PSS,而基本Java(Suncle/OpenJDK)不支持但BouncyCastle呢。请参阅https://stackoverflow.com/q/38767660 –

回答

1

显然,rsaautl使用NONEwithRSA签名方案,其中输入数据被takend,因为它们是(假设为被散列或短(长度< < N))

签名验证的当量:

Signature signature = Signature.getInstance("NONEwithRSA"); 
signature.initVerify(pubKey); 
signature.update(data); 
boolean verified = signature.verify(signatureBytes); 

如果数据比较长(比常见的密钥/散列长度长),我建议使用散列签名,例如:

openssl dgst -sha256 -sign private.pem data.txt | base64 

,并确认在Java

Signature signature = Signature.getInstance("SHA256withRSA"); 
signature.initVerify(pubKey); 
signature.update(data); 
boolean verified = signature.verify(signatureBytes);