如何解决从 CMSSignedDataGenerator 获取消息摘要以登录外部服务器
目前我有一个类,我可以在本地正确生成 CMS 签名(可以访问私钥)。 我需要调整它,以便签名操作在异步响应请求的外部服务器(我只能访问公共证书)上完成,因此我想找到一种方法来获取必须签名的摘要,将其发送到服务器并退出。
收到响应后,我将构建 CMS 容器并将其插入。
我知道我可以创建一个不对数据进行签名而是返回已签名数据的 ContentSigner。但是我怎样才能得到实际上必须签名的摘要?
我有这个执行签名的类
public class MyContentSigner implements ContentSigner {
private final Signature sign;
private final ByteArrayOutputStream byteArrayOutputStream;
private final AlgorithmIdentifier sha256withRSA;
public MyContentSigner(PrivateKey privateKey,AlgorithmIdentifier sha256withRSA) throws NoSuchAlgorithmException,InvalidKeyException {
this.sha256withRSA = sha256withRSA;
sign = Signature.getInstance("SHA256withRSA",new BouncyCastleProvider());
sign.initSign(privateKey);
byteArrayOutputStream = new ByteArrayOutputStream();
}
@Override
public AlgorithmIdentifier getAlgorithmIdentifier() {
return sha256withRSA;
}
@Override
public OutputStream getOutputStream() {
return byteArrayOutputStream;
}
@Override
public byte[] getSignature() {
try {
byte[] input = byteArrayOutputStream.toByteArray();
this.sign.update(input);
byteArrayOutputStream.reset();
return this.sign.sign();
} catch (SignatureException e) {
e.printStackTrace();
}
return null;
}
}
然后是这个创建 CMS Container 并将前一个类设置为 ContentSigner 的类。
public class SignServiceWithMyContentSigner {
private final PrivateKey privateKey;
private final X509Certificate certificate;
public static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
private final Certificate[] chain;
public SignServiceWithMyContentSigner(KeyStore ks) throws NoSuchAlgorithmException,KeyStoreException,UnrecoverableKeyException {
privateKey = (PrivateKey) ks.getKey("....","".toCharArray());
certificate = (X509Certificate) ks.getCertificate("....");
chain = ks.getCertificateChain(".....");
}
public byte[] signDocument(byte[] digestInfo) {
try {
List<Certificate> certificateList = Arrays.asList(chain);
JcaCertStore jcaCertStore = new JcaCertStore(certificateList);
CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
Attribute attribute = new Attribute(CMSAttributes.messageDigest,new DERSet(new DEROctetString(digestInfo)));
ASN1EncodableVector asn1EncodableVector = new ASN1EncodableVector();
asn1EncodableVector.add(attribute);
SignerInfoGeneratorBuilder builder =
new SignerInfoGeneratorBuilder(
new BcDigestCalculatorProvider()
).setSignedAttributeGenerator(
new DefaultSignedAttributeTableGenerator(
new AttributeTable(asn1EncodableVector)
)
);
AlgorithmIdentifier sha256withRSA = new DefaultSignatureAlgorithmIdentifierFinder().find(SIGNATURE_ALGORITHM);
generator.addSignerInfoGenerator(
builder.build(
// Here is the my previous class
new MyContentSigner(privateKey,sha256withRSA),new JcaX509CertificateHolder(certificate)
)
);
generator.addCertificates(jcaCertStore);
CMSSignedData generate = generator.generate(new CMSAbsentContent(),false);
return generate.getEncoded();
} catch (IOException | CertificateEncodingException | OperatorCreationException | CMSException | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) {
e.printStackTrace();
}
return new byte[0];
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。