如何制作“MessageDigest SHA-1和Signature NONEwithRSA”相当于“签名SHA1withRSA” [英] How to make "MessageDigest SHA-1 and Signature NONEwithRSA" equivalent to "Signature SHA1withRSA "
问题描述
我有兴趣将SHA-1散列与RSA签名应用于某些数据,但我需要分两步执行 - 首先应用散列,然后签署数据。 Signature.sign()函数似乎创建了一个最终签名的更复杂(ASN.1?)数据结构(请参阅这个问题)。如何在没有使用像BouncyCastle这样的外部库的情况下创建这两个等价物?
使用签名的单步应用散列和签名:
PrivateKey privatekey =(PrivateKey)keyStore.getKey(alias,null);
...
sig = Signature.getInstance(SHA1withRSA,SunMSCAPI);
sig.initSign(privatekey);
sig.update(data_to_sign);
byte [] bSignedData_CAPISHA1_CAPIRSA = sig.sign();
通过MessageDigest应用哈希,然后签名签名:
PrivateKey privatekey =(PrivateKey)keyStore.getKey(alias,null);
...
MessageDigest sha1 = MessageDigest.getInstance(SHA-1);
byte [] data_to_sign = sha1.digest(bdataToSign);
签名sig = Signature.getInstance(NONEwithRSA,SunMSCAPI);
sig.initSign(privatekey);
sig.update(data_to_sign);
byte [] bSignedData_JAVASHA1_CAPIRSA = sig.sign();
...
我正在寻找以下等价物:
bSignedData_JAVASHA1_CAPIRSA == bSignedData_CAPISHA1_CAPIRSA
我的最终目标是创建散列,然后使用PKCS11标记进行签名,但为了验证目的,我需要签名数据与传统数据的格式相同。
>解决方案我可以通过执行以下操作来解决这个问题:
-
需要在
DigestInfo DER编码的字节数组中正确格式化。签名SHA1withRSA为您提供
的关注,但如果您想通过两步
过程完成此操作,则需要创建自己的DigestInfo。尽管我不希望使用第三个
派对库,但我最终从BouncyCastle中复制了
a非常少量的ASN.1类到我的
项目中来实现这一点。 -
如果您尝试使用密码API来加密DigestInfo,则
PKCS1填充将是随机的,并且不适用于数字
签名。
Signature.getInstance(NONEwithRSA,SunMSCAPI)拒绝
DER编码的DigestInfo格式,并且将会使用静态填充。 如果您尝试
来签署该数据,则会返回错误。但是,由于我最终希望使用PKCS11
API来生成签名,因此我最终使用PKCS11 C_SignInit和C_Sign函数对DER编码的
DigestInfo进行了签名。
总而言之,对我来说有效的是:
- 生成使用Java MessageDigest API
- 签署的数据的SHA-1散列会生成DigestInfo DER编码的ASN.1对象,其中嵌入了SHA-1散列和SHA-1 OID目的。
- 使用第三方库中的PKCS11 C_Sign函数对DigestInfo进行签名。 链接对解决我的问题最有帮助:
Oracle论坛:SHA1withRSA - 如何分两步进行操作?
.com / questions / 521101 / using-sha1-and-rsa-with-java-security-signature-vs-messagedigest-and-cipher> StackOverflow:将SHA1和RSA与java.security.Signature对比MessageDigest和CipherI am interested in applying a SHA-1 hash with RSA signature to some data, but I need to do it in two steps - apply hash first and then sign the data. The Signature.sign() function appears to create a more complex (ASN.1?) data structure that is ultimately signed (see this question). How can I make the two equivalent without using any external libraries like BouncyCastle?
Apply hash and sign in single step with Signature:
PrivateKey privatekey = (PrivateKey) keyStore.getKey(alias, null); ... sig = Signature.getInstance("SHA1withRSA", "SunMSCAPI"); sig.initSign(privatekey); sig.update(data_to_sign); byte[] bSignedData_CAPISHA1_CAPIRSA = sig.sign();
Apply hash via MessageDigest, then sign with Signature:
PrivateKey privatekey = (PrivateKey) keyStore.getKey(alias, null); ... MessageDigest sha1 = MessageDigest.getInstance("SHA-1"); byte[] data_to_sign = sha1.digest(bdataToSign); Signature sig = Signature.getInstance("NONEwithRSA", "SunMSCAPI"); sig.initSign(privatekey); sig.update(data_to_sign); byte[] bSignedData_JAVASHA1_CAPIRSA = sig.sign(); ...
I am looking for the following equivalency:
bSignedData_JAVASHA1_CAPIRSA == bSignedData_CAPISHA1_CAPIRSA
My ultimate goal is to create the hash and then sign with a PKCS11 token, but I require the signed data to be the same format as legacy data for verification purposes.
解决方案I was able to solve this by doing the following:
The data to be signed needed to be formatted correctly in a DigestInfo DER-encoded byte array. The Signature SHA1withRSA takes care of this for you, but if you want to accomplish it in a two-step process, you need to create your own DigestInfo. I ended up copying a very minimal amount of ASN.1 classes from BouncyCastle into my project to accomplish this, despite my desire not to use a third party lib.
If you try to use the Cipher API to encrypt the DigestInfo, the PKCS1 padding will be random and not appropriate for a digital signature. I needed static padding.
The Signature.getInstance("NONEwithRSA", "SunMSCAPI") rejects the DER-encoded DigestInfo format, and will return an error if you try to sign that data. But, since I ultimately wanted to use the PKCS11 API to generate the signature, I ended up signing the DER-encoded DigestInfo with the PKCS11 C_SignInit and C_Sign functions.
To summarize, what worked for me was:
- generate the SHA-1 hash of the data to sign using the Java MessageDigest API
- generated a DigestInfo DER-encoded ASN.1 object with the SHA-1 hash and SHA-1 OID embedded in the object.
- signed the DigestInfo using the PKCS11 C_Sign function from a third party library.
The following links were most helpful in solving my problem:
Oracle Forums: SHA1withRSA - how to do that in 2 steps?
StackOverflow: Using SHA1 and RSA with java.security.Signature vs. MessageDigest and Cipher
这篇关于如何制作“MessageDigest SHA-1和Signature NONEwithRSA”相当于“签名SHA1withRSA”的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!