java外码的增加,生成有效的CMS签名文件,并使用Java添加外部PKCS#1

I'm generating CMS signature files with external PKCS#1 based on this thread.

The first step is obtain the signed attributes from the original file to be signed in external application which is returning PKCS#1 byte array.

Then build standard org.bouncycastle.cms.SignerInfoGenerator with original file hash, signed data (PKCS#1) and certificate to add to CMS, and finally create the attached signature.

But when i'd tried to validate it using this code:

String originalFile = "aG9sYQ0KYXNkYXMNCg0KYWZzDQo=";

String cmsSignedFile = "MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBg...j2Dwytp6kzQNwtXGO8QbWty1lOo8oYm+6LR8EWba3ikO/m9ol/G808vit9gAAAAAAAA==";

byte[] signedByte = DatatypeConverter.parseBase64Binary(cmsSignedFile);

Security.addProvider(new BouncyCastleProvider());

CMSSignedData s = new CMSSignedData(new CMSProcessableByteArray(DatatypeConverter.parseBase64Binary(originalFile)), signedByte);

SignerInformationStore signers = s.getSignerInfos();

SignerInformation signerInfo = (SignerInformation)signers.getSigners().iterator().next();

FileInputStream fis = new FileInputStream("C:/myCertificate.cer");

CertificateFactory cf = CertificateFactory.getInstance("X.509");

X509Certificate cert = (X509Certificate)cf.generateCertificates(fis).iterator().next();

boolean result = signerInfo.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert.getPublicKey()));

System.out.println("Verified: "+result);

I get Verified: false

I'm adding Content Type, Signing time, Message digest and OCSP as signed attributes and TSP Token as unsigned attribute (I'm not sure if this is right).

I'm also trying to recover data from CMS signature, using the code below:

//load cms signed file with attached data

CMSSignedData cms = new CMSSignedData(FileUtils.readFileToByteArray(new File("C:/tmp/tempFile1864328163858309463.cms")));

System.out.println(cms.getSignerInfos().getSigners().iterator().next().getDigestAlgorithmID().getAlgorithm().getId());

System.out.println(Hex.encodeHexString(cms.getSignerInfos().getSigners().iterator().next().getSignature()));

//recover signer certificate info

Store certs = cms.getCertificates();

Collection col = certs.getMatches(null);

X509CertificateHolder []h1 = col.toArray(new X509CertificateHolder[col.size()]);

X509CertificateHolder firmante = h1[0];

System.out.println(firmante.getSubject());

System.out.println(h1[1].getSubject());

SignerInformation sinfo = cms.getSignerInfos().getSigners().iterator().next();

//recover OCSP information

//THIS FAILS :(

// Store infocspbasic = cms.getOtherRevocationInfo(OCSPObjectIdentifiers.id_pkix_ocsp_basic);

// Object basic = infocspbasic.getMatches(null).iterator().next();

//recover signing time

if (sinfo.getSignedAttributes() != null) {

Attribute timeStampAttr = sinfo.getSignedAttributes().get(PKCSObjectIdentifiers.pkcs_9_at_signingTime);

ASN1Encodable attrValue = timeStampAttr.getAttrValues().getObjectAt(0);

final Date signingDate;

if (attrValue instanceof ASN1UTCTime) {

ASN1UTCTime time = ASN1UTCTime.getInstance(attrValue);

Date d = time.getDate();

System.out.println("ASN1UTCTime:" + d);

} else if (attrValue instanceof Time) {

signingDate = ((Time) attrValue).getDate();

} else if (attrValue instanceof ASN1GeneralizedTime) {

System.out.println("ASN1GeneralizedTimeASN1GeneralizedTime");

} else {

signingDate = null;

}

}

//recover timestamp TOken

//unsigned attributes are null :(

if (sinfo.getUnsignedAttributes() != null) {

Attribute timeStampAttr = sinfo.getUnsignedAttributes().get(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken);

for (ASN1Encodable value : timeStampAttr.getAttrValues().toArray()) {

TimeStampToken token = new TimeStampToken(new CMSSignedData(value.toASN1Primitive().getEncoded()));

System.out.println(token.getTimeStampInfo().getGenTime());

}

}

But I can't retrieve OCSP response nor TSP Token information. Additionally I've downloaded this viewer software to help verify it:

oreqP.png

Any help would be very appreciated.

解决方案

I found a project named j4sign which implements CMS signature with external PKCS#1. The link goes to the project's forum where I posted the code sample using their classes and the final correction to make the validation works.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java 中,可以使用 Java 内置的 MessageDigest 类来计算报文的哈希值,具体方法如下: ```java import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SignatureException; public class PKCS1Hash { public static byte[] calculateHash(byte[] message, String algorithm) throws NoSuchAlgorithmException { MessageDigest messageDigest = MessageDigest.getInstance(algorithm); messageDigest.update(message); return messageDigest.digest(); } public static void main(String[] args) { String message = "Hello, world!"; try { byte[] hash = calculateHash(message.getBytes(), "SHA-256"); System.out.println("Hash value: " + bytesToHex(hash)); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray(); public static String bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for (int i = 0; i < bytes.length; i++) { int v = bytes[i] & 0xFF; hexChars[i * 2] = HEX_ARRAY[v >>> 4]; hexChars[i * 2 + 1] = HEX_ARRAY[v & 0x0F]; } return new String(hexChars); } } ``` 在上面的示例代码中,`calculateHash` 方法接收一个字节数组和一个哈希算法名称,返回一个字节数组表示该报文的哈希值。在 `main` 方法中,我们将字符串 "Hello, world!" 转换为字节数组,并计算 SHA-256 哈希值。最后,使用 `bytesToHex` 方法将哈希值转换为十六进制字符串输出。 需要注意的是,在 PKCS#1 数字签名过程中,计算哈希值所使用的哈希算法需要与签名算法匹配。例如,如果使用 RSA-SHA256 签名算法,那么计算哈希值时也需要使用 SHA-256 哈希算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值