Проверка PDF не прошлаJAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Проверка PDF не прошла

Сообщение Anonymous »

Я использую iText для цифровой подписи PDF-файлов, и мы используем не популярный во всем мире алгоритм под названием SM3WITHSM2. Однако сейчас невозможно проверить подписанный файл, и я не уверен, в чем проблема.

Код: Выделить всё

  public DeferredSignResult machineSign(MachineSignParam machineSignParam) throws Exception {
CipherMachineService provider = getProvider();
URL pdfUrl = machineSignParam.getPdfUrl();
URL sealUrl = machineSignParam.getSealUrl();
Rectangle rectangle = machineSignParam.getRectangle();
int page = machineSignParam.getPage();
int containerNum = machineSignParam.getContainerNum();
Certificate[] certificates = machineSignParam.getCertificates();

ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
PdfReader pdfReader = new PdfReader(pdfUrl);
PdfStamper pdfSigner = PdfStamper.createSignature(pdfReader, byteArrayOutputStream, '\0', null, true);
PdfSignatureAppearance pdfSignatureAppearance = pdfSigner.getSignatureAppearance();
Image imageData = Image.getInstance(sealUrl);
pdfSignatureAppearance.setReason("");
pdfSignatureAppearance.setLocation("");
pdfSignatureAppearance.setContact("");
pdfSignatureAppearance.setLayer2Text("");
pdfSignatureAppearance.setLayer4Text("");
pdfSignatureAppearance.setSignatureCreator("");
pdfSignatureAppearance.setOpacity(1F);
pdfSignatureAppearance.setCertificationLevel(PdfSignatureAppearance.NOT_CERTIFIED);
pdfSignatureAppearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.DESCRIPTION);
pdfSignatureAppearance.setImage(imageData);
pdfSignatureAppearance.setVisibleSignature(rectangle, page, IdUtil.fastSimpleUUID());

ExternalSignatureContainer externalSignatureContainer;
if (provider instanceof Fisherman) {
externalSignatureContainer = new FisherManSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED,
containerNum, certificates);
} else if (provider instanceof Sinocipher) {
externalSignatureContainer = new SinoChipherSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED,
containerNum, certificates);
} else {
throw new SystemException(1000, "未知的签章容器");
}
MakeSignature.signExternalContainer(pdfSignatureAppearance, externalSignatureContainer, 8192);
byte[] buffer = byteArrayOutputStream.toByteArray();

// 计算hash
InputStream inputStreamHash = pdfSignatureAppearance.getRangeStream();
BouncyCastleDigest bouncyCastleDigest = new BouncyCastleDigest();
byte[] hash = DigestAlgorithms.digest(inputStreamHash, bouncyCastleDigest.getMessageDigest(HASH_ALGORITHM));
PdfPKCS7 pkcs7 = new PdfPKCS7(null, certificates, HASH_ALGORITHM, null, bouncyCastleDigest, false);
pkcs7.setExternalDigest(hash, null, ENCRYPTION_ALGORITHM);

byte[] sh = pkcs7.getEncodedPKCS7(hash, pdfSignatureAppearance.getSignDate(), null, null, null, null, MakeSignature.CryptoStandard.CMS);
pdfReader.close();
DeferredSignResult deferredSignResult = new DeferredSignResult();
deferredSignResult.setDeferredPdfInputStream(new ByteArrayInputStream(buffer));
deferredSignResult.setPkcs1(hash);
deferredSignResult.setPkcs7(sh);
pdfReader.close();
return deferredSignResult;
}

public class FisherManSignatureContainer implements ExternalSignatureContainer {

/**
* 加密机容器号
*/
private final int containerNum;
private final Fisherman fisherman;
private final Certificate[] certChain;
/**
* hash算法
*/
private final String hashAlgorithm;
/**
* 加密算法
*/
private final String encryptAlgorithm;

private Calendar signingTime = Calendar.getInstance();

public FisherManSignatureContainer(PdfName filter, PdfName subFilter, int containerNum, Certificate[] certChain) {
PdfDictionary pdfDictionary = new PdfDictionary();
pdfDictionary.put(PdfName.FILTER, filter);
pdfDictionary.put(PdfName.SUBFILTER, subFilter);
this.containerNum = containerNum;
fisherman = new Fisherman();
this.certChain = certChain;
String algorithmGroup = CertUtils.getCertificateAlgorithmGroup(certChain[0]);
String[] parsedAlgorithmGroup = CertUtils.parseAlgorithmGroup(algorithmGroup);
hashAlgorithm = parsedAlgorithmGroup[0];
encryptAlgorithm = parsedAlgorithmGroup[1];
}

@Override
public byte[] sign(InputStream inputStream) throws GeneralSecurityException {
try {
BouncyCastleDigest digest = new BouncyCastleDigest();
byte[] hash = DigestAlgorithms.digest(inputStream,  digest.getMessageDigest(hashAlgorithm));
PdfPKCS7 pkcs7 = new PdfPKCS7(null, certChain, hashAlgorithm, null, new BouncyCastleDigest(), false);
byte[] sh = pkcs7.getAuthenticatedAttributeBytes(hash, signingTime, null, null, MakeSignature.CryptoStandard.CMS);
byte[] sign;
if ("SM3".equalsIgnoreCase(hashAlgorithm)) {
sign = fisherman.sign(sh, containerNum);
} else {
sign = fisherman.signRSA(sh, containerNum);
}
return getP7(hash,sign);
} catch (Exception e) {
log.error("渔翁加密机签章失败:{}", e.getMessage());
throw new SystemException(1000, "渔翁加密机签章失败!");
}
}

@Override
public void modifySigningDictionary(PdfDictionary pdfDictionary) {
pdfDictionary.putAll(pdfDictionary);
}

byte[] getP7(byte[] plaintext,byte[] signValue) throws Exception {
BouncyCastleDigest bouncyCastleDigest = new BouncyCastleDigest();
PdfPKCS7 pdfPKCS7 = new PdfPKCS7(null, certChain, hashAlgorithm, null, bouncyCastleDigest, false);
pdfPKCS7.setExternalDigest(signValue, null, encryptAlgorithm);
return pdfPKCS7.getEncodedPKCS7(plaintext, signingTime,null,"sinoCipher",null,null, MakeSignature.CryptoStandard.CMS);
}
}
Вот адрес моего подписанного PDF-файла
https://drive.google.com/file/d/ 1pCX6ikFxwyY-dPd4M6hm0JqTA4B04V8T/view?usp=sharing

Подробнее здесь: https://stackoverflow.com/questions/793 ... d-not-pass
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»