java—从cmssigneddatagenerator获取消息摘要,以便登录外部服务器

hs1rzwqc  于 2021-06-27  发布在  Java
关注(0)|答案(0)|浏览(337)

目前,我有一个类,我可以正确地生成一个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容器并将前一个类设置为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];
    }
}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题