问题描述
我正在研究一种允许在远程服务器上使用 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 (将#修改为@)