Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何验证iText数字签名?_Java_Itext_Signature - Fatal编程技术网

Java 如何验证iText数字签名?

Java 如何验证iText数字签名?,java,itext,signature,Java,Itext,Signature,我正在研究数字签名验证,在写下我的问题之前,我必须说我发现了很多例子,我相信有些与旧的iText版本有关,因为这些方法似乎已经不存在了 我使用的是iText 5.8.8,我没有任何例外,但是当我检查验证状态时,它总是返回false,我不知道该怎么办,我开始认为签名过程中可能有问题,但仍然不知道是什么 这是我试图检查它的方式: public List<VerificationException> verifySignatures(byte[] assinado) throws Gene

我正在研究数字签名验证,在写下我的问题之前,我必须说我发现了很多例子,我相信有些与旧的iText版本有关,因为这些方法似乎已经不存在了

我使用的是iText 5.8.8,我没有任何例外,但是当我检查验证状态时,它总是返回false,我不知道该怎么办,我开始认为签名过程中可能有问题,但仍然不知道是什么

这是我试图检查它的方式:

public List<VerificationException> verifySignatures(byte[] assinado) throws GeneralSecurityException, IOException {
// Security.addProvider(pkcs11Provider);
List<VerificationException> errors = null;
PdfReader reader = new PdfReader(assinado);
AcroFields af = reader.getAcroFields();
ArrayList<String> names = af.getSignatureNames();
for (String name : names) {
    System.out.println("Signature name: " + name);
    System.out.println("Signature covers whole document: " + af.signatureCoversWholeDocument(name));
    System.out.println("Document revision: " + af.getRevision(name) + " of " + af.getTotalRevisions());
    PdfPKCS7 pk = af.verifySignature(name);

    if (!pk.verify()) {
    throw new GeneralSecurityException("some erros message... ");
    }
public List verifySignatures(byte[]assinado)抛出GeneralSecurityException,IOException{
//Security.addProvider(pkcs11Provider);
列表错误=null;
PdfReader读取器=新PdfReader(assinado);
AcroFields af=reader.getAcroFields();
ArrayList name=af.getSignatureNames();
for(字符串名称:名称){
System.out.println(“签名名称:”+名称);
System.out.println(“签名涵盖整个文档:+af.SignatureOverwholeDocument(名称));
System.out.println(“文档修订:“+af.getTotalRevisions()的+af.getRevision(名称)+”);
PdfPKCS7 pk=af.verifySignature(名称);
如果(!pk.verify()){
抛出新的GeneralSecurityException(“某些错误消息…”);
}
}

关键是每次我检查pk.verify()时,它都返回false JohnDoe:00000099999证书

以下是该协议的签署方式:

public byte[] signPdfFirstTime(PrivateKey pk, Certificate[] chain, String providerName, String conteudoBase64, X509Certificate cert, String alias) throws IOException, DocumentException, GeneralSecurityException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
Document document = new Document();

PdfWriter.getInstance(document, bos);
document.open();

document.addTitle("Dummy PDF");
document.addSubject("Dummy PDF");
document.addKeywords("dummy, test");
document.addAuthor("John Doe ");
document.addCreator("John Doe ");
document.newPage();

document.add(new Paragraph("Title2"));

document.close();
String name = alias;

byte[] bytes = bos.toByteArray();


PdfReader reader = new PdfReader(bytes);
PdfStamper stamper = PdfStamper.createSignature(reader, bos, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setReason("REASON");
appearance.setLocation("CITY");
appearance.setCertificate(cert);

Rectangle rectangle = new Rectangle(550, 50, 610, 500);

 //here it goes the name
appearance.setVisibleSignature(rectangle, 1, name);

// Creating the signature
ExternalSignature pks = new PrivateKeySignature(pk, DigestAlgorithms.SHA256, providerName);
ExternalDigest digest = new BouncyCastleDigest();
List<CrlClient> crlList = new ArrayList<CrlClient>();
crlList.add(new CrlClientOnline());

LtvVerification v = stamper.getLtvVerification();

OcspClient ocspClient = new OcspClientBouncyCastle();

String url = CertificateUtil.getCRLURL(cert);
CertificateFactory cf = CertificateFactory.getInstance("X.509");

X509CRL crl = (X509CRL) cf.generateCRL(new URL(url).openStream());
System.out.println("CRL valid until: " + crl.getNextUpdate());
System.out.println("Certificate revoked: " + crl.isRevoked(chain[0]));

if (crl.isRevoked(chain[0])) {

    throw new GeneralSecurityException("CERT REVOKED!");
}
else {
    MakeSignature.processCrl(cert, crlList);

    MakeSignature.signDetached(appearance, digest, pks, chain, null, null, null, 0, CryptoStandard.CMS);
    byte[] b = bos.toByteArray();
    bos.close();
    return b;


}
}
public byte[]signPdfFirstTime(私钥pk、证书[]链、字符串提供程序名称、字符串conteudoBase64、X509证书证书证书、字符串别名)引发IOException、DocumentException、GeneralSecurityException{
ByteArrayOutputStream bos=新建ByteArrayOutputStream();
文档=新文档();
getInstance(文档,bos);
document.open();
文件。添加标题(“虚拟PDF”);
文件。添加主题(“虚拟PDF”);
文件。添加关键词(“假人,试验”);
文件作者(以下简称“John Doe”);
文件。addCreator(“John Doe”);
document.newPage();
文件.添加(新的段落(“标题2”);
document.close();
字符串名称=别名;
byte[]bytes=bos.toByteArray();
PdfReader reader=新PdfReader(字节);
PdfStamper stamper=PdfStamper.createSignature(读卡器,bos,'\0');
PdfSignatureAppearance外观=母版。getSignatureAppearance();
外观。设置原因(“原因”);
外观。设置位置(“城市”);
外观.证书(cert);
矩形=新矩形(550、50、610、500);
//名字在这里
外观。setVisibleSignature(矩形,1,名称);
//创建签名
ExternalSignature pks=新的PrivateKeySignature(pk,DigestAlgorithms.SHA256,providerName);
ExternalDigest=新的BouncyCastleDigest();
List crlList=new ArrayList();
添加(新的CrlClientOnline());
LtvVerification v=母版。getLtvVerification();
OcspClient-OcspClient=new-OcspClientBouncyCastle();
字符串url=CertificateUtil.getCRLURL(证书);
CertificateFactory cf=CertificateFactory.getInstance(“X.509”);
X509CRL crl=(X509CRL)cf.generateCRL(新URL(URL).openStream());
System.out.println(“CRL有效期至:”+CRL.getNextUpdate());
System.out.println(“证书已吊销:+crl.isrelock(链[0]));
if(crl.isr(链[0])){
抛出新的GeneralSecurityException(“证书已吊销!”);
}
否则{
MakeSignature.processCrl(证书、crlList);
签名分离(外观、摘要、pks、链、null、null、null、null、0、CryptoStandard.CMS);
字节[]b=bos.toByteArray();
bos.close();
返回b;
}
}

签名正在根据上述方法返回的字节数组进行验证

iText 5.8.8不存在(尚未存在),也许您的意思是5.5.8?(这里是iText QA&Release Engineer,我应该知道)请共享一个签名的示例文档来重现该问题。我的错,正如您所说的,它实际上是5.5.8。没有可共享的示例文档,因为正在签名的是在signPdfFirstTime方法的第一行上创建的文档。我的主要目标是在服务器端验证签名,而我无法获得简单的字符串或其他内容比文档签名更简单,所以我认为在内存中创建一个文档,签名然后检查签名是个好主意。你认为这可能是一个不好的方法吗?谢谢你的注意。我刚刚在这里读了你的帖子,我可以说几乎是一样的,pk.verify总是返回false。我尝试了你的工作,但没有成功帮助,因为您建议通过反射获取的参数的值已为null。我尝试反编译PdfPKCS7以查看verify()内部发生的情况,其中有一些内容:AbscentencContDigestCompare=Arrays.equals(msgDigestBytes,this.digestAttr)..比较这两个数组的结果是不同的,因此缺席比较标志的结果始终为false,然后将一切都搞糟。现在我正在寻找一些原因,最后尝试修复导致两个不同数组的某个地方。