我創建了一個證書使用keytool:簽名與密鑰庫的Java
keytool -genkeypair -alias sara -keyalg RSA -keysize 2048 -keypass
password -keystore "\Sviluppo\JavaKeyStore\keystore.jks" -storepass
12345678 -validity 360 -dname "cn=Sara, ou=***, o=***, l=Padova,
s=Italia, c=IT"
然後我想簽署此證書的PDF版本,我使用Itextpdf簽署一份PDF格式。 首先,我加載私鑰和證書密鑰庫從:
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
File fileKeyStore = new File(pathKeyStore);
FileInputStream fis = new FileInputStream(fileKeyStore);
keyStore.load(fis, "12345678".toCharArray());
final PrivateKey privateKey = (PrivateKey) keyStore.getKey("sara", "password".toCharArray());
final Certificate certificate = keyStore.getCertificate(certID);
然後我打開文件的哈希計算簽名:
PdfReader reader = new PdfReader(new RandomAccessFileOrArray(pdfInputPath), null);
OutputStream pdfOutputStream = new FileOutputStream(pdfOutputPath);
PdfStamper stp = PdfStamper.createSignature(reader, pdfOutputStream, '\0', tempPathFile, true)
PdfSignatureAppearance sap = stp.getSignatureAppearance();
PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
dic.setDate(dateNow);
sap.setCryptoDictionary(dic);
sap.setCrypto(privateKey, keyStore.getCertificateChain("sara"), null, PdfSignatureAppearance.SELF_SIGNED);
HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
exc.put(PdfName.CONTENTS, (int) (6144 * 2 + 2));
sap.preClose(exc);
然後計算sap.getRangeStream(),從密鑰庫加載證書的哈希值:
BufferedInputStream bis = new BufferedInputStream(sap.getRangeStream());
MessageDigest digest = MessageDigest.getInstance("SHA-256");
DigestInputStream dis = new DigestInputStream(bis, digest);
byte[] buff = new byte[512];
while (dis.read(buff) != -1) {
;
}
dis.close();
dis = null;
byte[] hashToSign= digest.digest();
bis.close();
我從證書密鑰庫登錄:
java.security.Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update(hashToSign);
byte[] hashSigned = signature.sign();
末關閉PDF:
byte[] paddedSig = new byte[6144];
System.arraycopy(hashSigned, 0, paddedSig, 0, hashSigned.length);
PdfDictionary pdfDictionary = new PdfDictionary();
pdfDictionary.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true));
sap.close(pdfDictionary);
但簽署的PDF是無效的:「有包含在此簽名的格式或信息錯誤」
有什麼問題,證書或簽名? 感謝您的幫助 薩拉
爲什麼直接構建哈希以簽名和嵌入數字簽名而不是使用itext支持?有很多可能的失敗點。例如,你不包括認證鏈到pdf – pedrofb
如果我打電話給一個外部服務器(例如阿魯巴CA),我只發送散列,簽署pdf的代碼工作正常。但是,如果我使用keytool生成證書,pdf是不正確的。我還添加了證書鏈: sap.setCrypto((PrivateKey)keyStore.getKey(「sara」,「password」.toCharArray()),keyStore.getCertificate(「sara」)。getCertificateChain(),null,PdfSignatureAppearance.SELF_SIGNED ); 但存在同樣的問題。 – Sara
不要在評論中包含代碼,它很難閱讀。只需編輯你自己的問題。你應該包括所有相關的代碼,包括你如何計算'hashToSign'。但是,如果您的代碼與外部CA一起使用,而不是使用自簽名證書,那麼問題可能就在那裏。檢查您的證書是否正確生成 – pedrofb