正如標題所示,我想知道給定的PDF文件是否已經數字簽名。驗證PDF是否使用iText進行數字簽名
我用iText對它進行簽名,但是我無法知道它是否已經簽名以最終辭職或執行其他操作。
有沒有辦法簡單地做(可能使用iText)?
正如標題所示,我想知道給定的PDF文件是否已經數字簽名。驗證PDF是否使用iText進行數字簽名
我用iText對它進行簽名,但是我無法知道它是否已經簽名以最終辭職或執行其他操作。
有沒有辦法簡單地做(可能使用iText)?
利用iText:
現在signatureNames
包括含有簽名所有可達簽名字段的名稱,參的JavaDoc:這裏
/**
* Gets the field names that have signatures and are signed.
*
* @return the field names that have signatures and are signed
*/
public ArrayList<String> getSignatureNames()
一個例子
public static final String verifSign(PdfReader pdfReader)
{
KeyStore kall = PdfPKCS7.loadCacertsKeyStore();
AcroFields acroFields = pdfReader.getAcroFields();
List<String> signatureNames = acroFields.getSignatureNames();
if (signatureNames.isEmpty())
{
return ("El documento no tiene ni una firma registrada");
}
for(String name : signatureNames)
{
if (!acroFields.signatureCoversWholeDocument(name))
{
return ("la firma: "+name+" does not covers the whole document.");
}
PdfPKCS7 pk = acroFields.verifySignature(name);
Certificate[] certificates = pk.getCertificates();
Calendar cal = pk.getSignDate();
//System.out.println("Document modified: " + !pk.verify());
Object fails[] = PdfPKCS7.verifyCertificates(certificates, kall, null, cal);
if (fails == null)
{
// Documento PDF firmado correctamente
}
else
{
return ("Firma no válida");
}
}
// Todo firmado correctamente
return null;
}
http://www.berthou.com/us/2009/07/01/verify-pdf-signature-with-itext/
如果您使用的iText新版本類似的5.5.x這裏是一個完整的工作示例,你怎麼能檢查數字簽名的PDF(從2.1.7版開始,iText已經完成了許多有用的開發和更改):
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.security.PdfPKCS7;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.Principal;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class DigitalSignatureCheck {
private static final Logger LOGGER = LoggerFactory.getLogger(DigitalSignatureCheck.class);
public static final boolean verifySignature(PdfReader pdfReader)
throws GeneralSecurityException, IOException {
boolean valid = false;
AcroFields acroFields = pdfReader.getAcroFields();
List<String> signatureNames = acroFields.getSignatureNames();
if (!signatureNames.isEmpty()) {
for (String name : signatureNames) {
if (acroFields.signatureCoversWholeDocument(name)) {
PdfPKCS7 pkcs7 = acroFields.verifySignature(name);
valid = pkcs7.verify();
String reason = pkcs7.getReason();
Calendar signedAt = pkcs7.getSignDate();
X509Certificate signingCertificate = pkcs7.getSigningCertificate();
Principal issuerDN = signingCertificate.getIssuerDN();
Principal subjectDN = signingCertificate.getSubjectDN();
LOGGER.info("valid = {}, date = {}, reason = '{}', issuer = '{}', subject = '{}'",
valid, signedAt.getTime(), reason, issuerDN, subjectDN);
break;
}
}
}
return valid;
}
private static void validate(String name)
throws IOException, GeneralSecurityException {
InputStream is = DigitalSignatureCheck.class.getClassLoader()
.getResourceAsStream(name);
PdfReader reader = new PdfReader(is);
boolean ok = verifySignature(reader);
LOGGER.info("'{}' is {}signed", name, ok ? "" : "NOT ");
}
public static void main(String[] args) throws Exception {
validate("any.pdf"); // if placed in resources' root
}
}
使用LOGGER僅用於顯示結果。
即使'ok'爲'false',文檔最有可能被簽名(只有沒有對文檔有效的簽名),簽名僅僅不涉及文檔ite被嵌入,可能是由於以後的更改。 – mkl
我的目的是舉一個最新的iText庫的例子(我也有一個當前的任務來探索已簽名的PDF文檔)當然你是對的,這也是爲什麼我也包含了一些額外的屬性。你可以檢查簽名的很多不同方面,你可以做出適合你的決定。這是一個簡單的協議,只需返回verify()方法的結果,並說是或否。 –
該op想要*知道給定的PDF文件是否已經數字簽名*,而不是現有的簽名是否有效或不管。所以雖然很高興提到可以使用當前iText版本檢索大量屬性,但對於這個問題的答案尤其應該在實際問題的背景下引起關注。 – mkl