为什么 CMSSignedData 总是包含不同的签名?

问题描述

我正在使用充气城堡生成 CMSSignedData。但是,在使用完全相同的输入运行生成过程后,生成的签名总是不同的:

byte[] signature = signedData.getSignerInfos().getSigners().iterator().next().getSignature(); <-- this is always different

我希望基于 SHA256withRSA 签名算法的签名始终相同,这是确定性的。 (每次执行时不包含任何 nonce 或随机数据)

这就是我生成 CMSSignedData 的方式:

String sigalg = "SHA256withRSA";
String base64data = "n4bQgYhMfWWaL+qgxVrQFaO/TxsrC4Is0V1sFbDwCgg";

CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
ContentSigner contentSigner = new JcaContentSignerBuilder(sigalg).setProvider(keystore.getProvider()).build(privateKey);
byte[] digestData = Base64.getDecoder().decode(base64data);

final DigestAlgorithmIdentifierFinder algFinder = new DefaultDigestAlgorithmIdentifierFinder();
AlgorithmIdentifier alg = algFinder.find("SHA-256");

final DigestCalculator digestCalculator = new DigestCalculator() {
@Override
public AlgorithmIdentifier getAlgorithmIdentifier() {
    return alg;
}

@Override
public OutputStream getoutputStream() {
    return new OutputStream() {
        @Override
        public void write(int b) throws IOException {
            // do nothing
        }
    };
}

@Override
public byte[] getDigest() {
    return digestData;
}

};

final DigestCalculatorProvider calcProv = new DigestCalculatorProvider() {
@Override
public DigestCalculator get(AlgorithmIdentifier digestAlgorithmIdentifier) throws OperatorCreationException {
    return digestCalculator;
}  
};

final JcaSignerInfoGeneratorBuilder siBuilder = new JcaSignerInfoGeneratorBuilder(calcProv);
final SignerInfoGenerator sig = siBuilder.build(contentSigner,cert);

generator.addSignerInfoGenerator(sig);
generator.addCertificates(new JcaCertStore(certs));

ASN1ObjectIdentifier default = CMSObjectIdentifiers.data;

// This is used to generate the signature
CMSSignedData signedData = generator.generate(new CMSProcessableByteArray(deafult,"test".getBytes()),true);

System.out.println("CMSSignedData: " + Base64.getEncoder().encodetoString(signedData.getEncoded()));
byte[] signature = signedData.getSignerInfos().getSigners().iterator().next().getSignature();
System.out.println("Signature: " + Base64.getEncoder().encodetoString(signature)); <--- always different

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...