微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将吊销数据添加到 CMS 容器

如何解决将吊销数据添加到 CMS 容器

我正在研究一种允许在远程服务器上使用 p12 证书进行签名的解决方案。

首先,我拥有在服务器上计算的文档摘要,然后将其发送到另一台服务器上进行签名。

我现在的目标是使用 crl 本地文件添加撤销数据,知道我正在使用以下命令在服务器部分签名:PadesCMSSignedDataBuilder

************************ 在服务器 A 上 ************************

 public class ServerA {
private static PAdESSignatureParameters signatureParameters;
private static DSSDocument documentToSign;
public static ExternalCMSPAdESService service;


public static void main(String[] args) throws Exception {
    documentToSign = new FileDocument(new File("file.pdf"));

    signatureParameters = new PAdESSignatureParameters();
    signatureParameters.setSignatureLevel(SignatureLevel.PAdES_BASELINE_B);
    signatureParameters.setLocation("Luxembourg");
    signatureParameters.setReason("DSS testing");
    signatureParameters.setContactInfo("Jira");
    signatureParameters.setGenerateTBSWithoutCertificate(true);

    service = new ExternalCMSPAdESService(getofflineCertificateVerifier());
    byte[] documentDigest = computeDocumentDigest(documentToSign,signatureParameters);

    // Embedded CAdES is generated by a third party
    byte[] cmsSignedData = ServerB.getSignedCMSignedData(documentDigest);

    service.setCmsSignedData(cmsSignedData);
    DSSDocument finalDoc = service.signDocument(documentToSign,signatureParameters,null);

    save(finalDoc);
}

private static void save(DSSDocument signedDocument) {
    try (FileOutputStream fos = new FileOutputStream("DSS.pdf")) {
        Utils.copy(signedDocument.openStream(),fos);
    } catch (Exception e) {
        Alert alert = new Alert(Alert.AlertType.ERROR,"Unable to save file : " + e.getMessage(),ButtonType.CLOSE);
        alert.showAndWait();
        return;
    }
}

public static CertificateVerifier getofflineCertificateVerifier() {
    CertificateVerifier cv = new CommonCertificateVerifier();
    cv.setDataLoader(new IgnoreDataLoader());
    return cv;
}

protected static byte[] computeDocumentDigest(final DSSDocument toSignDocument,final PAdESSignatureParameters parameters) {
    IPdfObjFactory pdfObjFactory = new ServiceLoaderPdfObjFactory();
    final PDFSignatureService pdfSignatureService = pdfObjFactory.newPAdESSignatureService();
    return pdfSignatureService.digest(toSignDocument,parameters);
}

private static class ExternalCMSPAdESService extends PAdESService {

    private static final long serialVersionUID = -2003453716888412577L;

    private byte[] cmsSignedData;

    public ExternalCMSPAdESService(CertificateVerifier certificateVerifier) {
        super(certificateVerifier);
    }

    @Override
    protected byte[] generateCMSSignedData(final DSSDocument toSignDocument,final PAdESSignatureParameters parameters,final SignatureValue signatureValue) {
        if (this.cmsSignedData == null) {
            throw new NullPointerException("A CMS signed data must be provided");
        }
        return this.cmsSignedData;
    }

    public void setCmsSignedData(final byte[] cmsSignedData) {
        this.cmsSignedData = cmsSignedData;
    }

}
}

并且能够对计算出的散列进行签名:

************************ 在服务器 B 上 ************************

public class ServerB {

private static PAdESSignatureParameters signatureParameters;
private static DSSDocument documentToSign;
public static ExternalCMSPAdESService service;

/**
 * Computes a CAdES with specific things for PAdES
 */
public static byte[] getSignedCMSignedData(byte[] documentDigest) throws Exception {
    signatureParameters = new PAdESSignatureParameters();
    signatureParameters.setSigningCertificate(getSigningCert());
    signatureParameters.setCertificateChain(getCertificateChain());
    signatureParameters.setSignatureLevel(SignatureLevel.PAdES_BASELINE_B);
    signatureParameters.setLocation("Luxembourg");
    signatureParameters.setReason("DSS testing");
    signatureParameters.setContactInfo("Jira");

    CMSProcessableByteArray content = new CMSProcessableByteArray(documentDigest);

    PadesCMSSignedDataBuilder padesCMSSignedDataBuilder = new PadesCMSSignedDataBuilder(getofflineCertificateVerifier());
    SignatureAlgorithm signatureAlgorithm = signatureParameters.getSignatureAlgorithm();

    CustomContentSigner customContentSigner = new CustomContentSigner(signatureAlgorithm.getJCEId());
    SignerInfoGeneratorBuilder signerInfoGeneratorBuilder = padesCMSSignedDataBuilder.getSignerInfoGeneratorBuilder(signatureParameters,documentDigest);

    CMSSignedDataGenerator generator = padesCMSSignedDataBuilder.createCMSSignedDataGenerator(signatureParameters,customContentSigner,signerInfoGeneratorBuilder,null);

    CMSUtils.generateDetachedCMSSignedData(generator,content);

    SignaturetokenConnection signingToken = new Pkcs12Signaturetoken("certificate.p12",new KeyStore.PasswordProtection("123456".tochararray()));
    DssprivateKeyEntry privateKey = getKey("certificate.p12","123456");

    SignatureValue signatureValue = signingToken.sign(new ToBeSigned(customContentSigner.getoutputStream().toByteArray()),signatureParameters.getDigestAlgorithm(),privateKey);

    customContentSigner = new CustomContentSigner(signatureAlgorithm.getJCEId(),signatureValue.getValue());
    generator = padesCMSSignedDataBuilder.createCMSSignedDataGenerator(signatureParameters,null);

    CMSSignedData cmsSignedData = CMSUtils.generateDetachedCMSSignedData(generator,content);
    return DSSASN1Utils.getDEREncoded(cmsSignedData);
}

public static CertificateVerifier getofflineCertificateVerifier() {
    CertificateVerifier cv = new CommonCertificateVerifier();
    cv.setDataLoader(new IgnoreDataLoader());
    return cv;
}

public static List<Certificatetoken> getCertificateChain() throws Exception {
    List<Certificatetoken> list = new ArrayList<>();
    Certificatetoken[] l = getKey("certificate.p12","123456").getCertificateChain();
    for (int i = 0; i < l.length; i++) {
        list.add(l[i]);
    }
    return list;
}

public static Certificatetoken getSigningCert() throws Exception {
    return getKey("certificate.p12","123456").getCertificate();
}

public static DssprivateKeyEntry getKey(String certificate,String pin) throws Exception {
    try (Pkcs12Signaturetoken signaturetoken = new Pkcs12Signaturetoken("certificate.p12",new KeyStore.PasswordProtection("123456".tochararray()))) {
        List<DssprivateKeyEntry> keys = signaturetoken.getKeys();
        KSPrivateKeyEntry dssprivateKeyEntry = (KSPrivateKeyEntry) keys.get(0);
        DssprivateKeyEntry entry = signaturetoken.getKey(dssprivateKeyEntry.getAlias(),new KeyStore.PasswordProtection("123456".tochararray()));
        return entry;
    }
}
private static class ExternalCMSPAdESService extends PAdESService {

    private static final long serialVersionUID = -2003453716888412577L;

    private byte[] cmsSignedData;

    public ExternalCMSPAdESService(CertificateVerifier certificateVerifier) {
        super(certificateVerifier);
    }

    @Override
    protected byte[] generateCMSSignedData(final DSSDocument toSignDocument,final SignatureValue signatureValue) {
        if (this.cmsSignedData == null) {
            throw new NullPointerException("A CMS signed data must be provided");
        }
        return this.cmsSignedData;
    }

    public void setCmsSignedData(final byte[] cmsSignedData) {
        this.cmsSignedData = cmsSignedData;
    }

}
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。