我正在用 Java 实现 C# SignedCms 功能。
我正在使用 bouncycastle 库。问题是我得到的 java 签名与使用 SignedCms 生成的签名不同。
C# 代码
X509Certificate2 certificate = new X509Certificate2("myCertPath", "myPass");
String text = "text";
ContentInfo contentInfo = new ContentInfo(System.Text.Encoding.UTF8.GetBytes(text));
SignedCms cms = new SignedCms(contentInfo, false);
CmsSigner signer = new CmsSigner(certificate);
signer.IncludeOption = X509IncludeOption.None;
signer.DigestAlgorithm = new Oid("SHA1");
cms.ComputeSignature(signer, false);
byte[] signature = cms.Encode();
print(signature);
Java 代码
Security.addProvider(new BouncyCastleProvider());
char[] password = "myPass".toCharArray();
String text = "text";
FileInputStream fis = new FileInputStream("myCertPath");
KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(fis, password);
String alias = ks.aliases().nextElement();
PrivateKey pKey = (PrivateKey)ks.getKey(alias, password);
X509Certificate cert = (X509Certificate)ks.getCertificate(alias);
java.util.List certList = new ArrayList();
Store certs = new JcaCertStore(certList);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
JcaSimpleSignerInfoGeneratorBuilder builder = new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setDirectSignature(true);
gen.addSignerInfoGenerator(builder.build("SHA1withRSA", pKey, cert));
gen.addCertificates(certs);
CMSTypedData msg = new CMSProcessableByteArray(text.getBytes());
CMSSignedData s = gen.generate(msg, false);
print(s.getEncoded());
它们都不包括 x509 证书。
C# 生成的签名
长度=434308201AE06092A864886F70D010702A082019F3082019B020101310B300906052B0E03021A0500301306092 A864886F70D010701A006040474657874318201723082016E0201013081CB3081B6310B3009060355040613 02555331173015060355040A130E566572695369676E2C20496E632E311F301D060355040B1316566572695 369676E205472757374204E6574776F726B313B3039060355040B13325465726D73206F6620757365206174 2068747470733A2F2F7777772E766572697369676E2E636F6D2F7270612028632930393130302E060355040 31327566572695369676E20436C617373203320436F6465205369676E696E6720323030392D322043410210 1763F9A88334A01FFB3B7BAB384A9B93300906052B0E03021A0500300D06092A864886F70D0101010500048 1800B866A9A7045E3C86E5DB69CDAD5CED211A4A2362BCC4DDB2742BF0CDB65BC88556C97A6C08D68F8070D 89CC78ACD84A636F15B40D166E461411C6A04D5EC379283988DA4258B684FFEF9F08B293A03A0B40900E245 874D8C0587BBD58BDD915A50D27456E6EEB883846CAC485853BA5E22E45D333C940A958E641A00C9602B9
Java 生成的签名
长度=428308006092A864886F70D010702A0803080020101310B300906052B0E03021A0500308006092A864886F70D0 107010000318201723082016E0201013081CB3081B6310B300906035504061302555331173015060355040A 130E566572695369676E2C20496E632E311F301D060355040B1316566572695369676E205472757374204E6 574776F726B313B3039060355040B13325465726D73206F66207573652061742068747470733A2F2F777777 2E766572697369676E2E636F6D2F7270612028632930393130302E06035504031327566572695369676E204 36C617373203320436F6465205369676E696E6720323030392D3220434102101763F9A88334A01FFB3B7BAB 384A9B93300906052B0E03021A0500300D06092A864886F70D01010105000481800B866A9A7045E3C86E5DB 69CDAD5CED211A4A2362BCC4DDB2742BF0CDB65BC88556C97A6C08D68F8070D89CC78ACD84A636F15B40D16 6E461411C6A04D5EC379283988DA4258B684FFEF9F08B293A03A0B40900E245874D8C0587BBD58BDD915A50 D27456E6EEB883846CAC485853BA5E22E45D333C940A958E641A00C9602B9000000000000
我被困在这个问题上。
更新
Java 输出经过 BER 编码。我需要 DER 编码签名。要将 BER 转换为 DER,我使用了
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
DEROutputStream dOut = new DEROutputStream(bOut);
dOut.writeObject(s.toASN1Structure().toASN1Primitive());
dOut.close();
bytep[ encoded = bOut.toByteArray();
现在输出是一样的。