使用Java我希望使用RSA对给定的byte[] hash
进行加密签名,并以Cryptographic Message Syntax (CMS)格式返回byte[] signature
。
我正在使用Bouncycastle Java API (BC)来实现此目的,并面临不存在NONEwithRSA
签名类型的问题。 (java.lang.IllegalArgumentException: Unknown signature type requested: NONEWITHRSA
)。
NONEwithRSA
而不是所有其他现有(例如{{1} }})。我该怎么做呢?我没有在BC文档中找到任何示例。
SHA256withRSA
byte[] doSigningCMS(byte[] data, X509Certificate cert, PrivateKey key) throws Exception {
CMSSignedDataGenerator signGen = new CMSSignedDataGenerator();
CMSTypedData content = new CMSProcessableByteArray(data);
ContentSigner signer = new JcaContentSignerBuilder("NONEwithRSA").build(key);
DigestCalculatorProvider dcp = new JcaDigestCalculatorProviderBuilder().build();
signGen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(dcp).build(signer, cert));
return signGen.generate(content, false).getEncoded();
}
基本上返回SHA256withRSA
而不是NoneDigest
。但这似乎是非常错误的。SHA256Digest
的BC,这似乎不起作用(找不到算法)我希望得到一些建议和指导(如果可能的话)"正确的方式" 。感谢。
答案 0 :(得分:1)
“NoneWithRSA”是RSA数字签名,不添加摘要算法的OID。加密提供程序也不进行摘要。基本上它是带有私钥的PKCS#1_v15加密。
您可以在此OpenJDK测试https://github.com/ddopson/openjdk-test/blob/master/java/security/Signature/NONEwithRSA.java
中查看其工作原理由于Bouncycastle似乎不支持它,我认为您可以使用默认提供商提供自己的ContentSigner实施,而不是使用JcaContentSignerBuilder
假设输入数据已经被散列,所以如果你正在进行PKCS#1签名,我认为你需要提供签名算法。查看RFC3477它取决于使用的哈希算法。
A.2.4 RSASSA-PKCS1-v1_5
RSASSA-PKCS1-v1_5的对象标识符应为其中之一 以下。 OID的选择取决于散列的选择 算法:MD2,MD5,SHA-1,SHA-256,SHA-384或SHA-512。
String sigAlgo = "SHA256WithRSAEncryption"; // "SHA256WithRSAEncryption" for SHA256, "SHA1WithRSAEncryption" for SHA1, etc.
ContentSigner signer = new CustomContentSigner(key, sigAlgo );
public class CustomContentSigner implements ContentSigner {
private AlgorithmIdentifier algorithmIdentifier;
private Signature signature;
private ByteArrayOutputStream outputStream;
public CustomContentSigner(PrivateKey privateKey, String sigAlgo) {
//Utils.throwIfNull(privateKey, sigAlgo);
this.algorithmIdentifier = new DefaultSignatureAlgorithmIdentifierFinder().find(sigAlgo);
try {
this.outputStream = new ByteArrayOutputStream();
this.signature = Signature.getInstance("NONEwithRSA");
this.signature.initSign(privateKey);
} catch (GeneralSecurityException gse) {
throw new IllegalArgumentException(gse.getMessage());
}
}
@Override
public AlgorithmIdentifier getAlgorithmIdentifier() {
return algorithmIdentifier;
}
@Override
public OutputStream getOutputStream() {
return outputStream;
}
@Override
public byte[] getSignature() {
try {
signature.update(outputStream.toByteArray());
return signature.sign();
} catch (GeneralSecurityException gse) {
gse.printStackTrace();
return null;
}
}
}
免责声明:我不知道它是否有效,但您可以试试