我有方法来签署文件。
public static void sign(String src, String dest,
java.security.cert.Certificate[] chain, PrivateKey pk,
String digestAlgorithm, String provider, CryptoStandard subfilter,
String reason, String location) throws GeneralSecurityException,
IOException, DocumentException, com.itextpdf.text.DocumentException {
// Creating the reader and the stamper
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
// Creating the appearance
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setVisibleSignature(new Rectangle(0, 100, 50, 300), 1, "sig");
// Creating the signature
ExternalDigest digest = new BouncyCastleDigest();
ExternalSignature signature = new PrivateKeySignature(pk, digestAlgorithm, provider);
MakeSignature.signDetached(appearance, digest, signature, chain, null,null, null, 0, subfilter);
}
当我使用BouncyCastleProvider时,一切运作良好。
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(new FileInputStream(KEYSTORE), PASSWORD);
String alias = (String) ks.aliases().nextElement();
PrivateKey pk = (PrivateKey) ks.getKey(alias, PASSWORD);
java.security.cert.Certificate[] chain = ks.getCertificateChain(alias);
for (int i = 0; i < chain.length; i++) {
System.out.println(("Public Key"+chain[i].getPublicKey()));
}
System.out.println("Priate Key:"+ Arrays.toString(pk.getEncoded()));
System.out.println("Lengh of key is:"+ Arrays.toString(pk.getEncoded()).length());
sign(SRC, String.format(DEST, 1), chain, pk,DigestAlgorithms.SHA256, provider.getName(),CryptoStandard.CMS, "Test 1", "Ghent" );
它签好了,结果就是:
Public Key Sun RSA public key, 2048 bits. I have only Self Sign sertificate here. Created By Key tool.
modulus: 19757623340732442247234242 ... and etc
public exponent: 65537
Priate Key:[48, -126, 4, -66, 2, 1, ... and etc ]
Lengh of key is:5618
温我使用我的提供者。我有没有运行时错误或者优惠但是当我打开pdf文件时,我有单一错误。 adobe reader有“:至少有一个签名无效:。当我尝试查看证书,我有警报“签名验证过程中出错。验证时遇到错误。内部加密库错误。 错误代码:0x2726“”
A是根CA. B是A. C的儿童是签名证书。我还有T证书,A A的孩子
MyProvider provider= newMyProvider();
CallbackHandler console= new com.sun.security.auth.callback.TextCallbackHandler();
provider.setCallbackHandler(console);
Security.addProvider(provider);
KeyStore ks = KeyStore.getInstance("KeyStore");
ks.load(null, new char[] {});
List < java.security.cert.Certificate > chainList = new ArrayList< java.security.cert.Certificate>();
System.out.println("My Certificates in chain:");
Enumeration<String> aliases = ks.aliases();
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
if( alias.equalsIgnoreCase("T")
continue;
if (ks.isCertificateEntry(alias)) {
X509Certificate cert = (X509Certificate) ks.getCertificate(alias);
if(!chainList.contains(ks.getCertificate(alias))){
chainList.add(ks.getCertificate(alias));
}
System.out.println("Public Key"+(cert.getPublicKey()));
}
}
java.security.cert.Certificate[] chain = new java.security.cert.Certificate[chainList.size()];
chainList.toArray(chain);
enter code here
PrivateKey pk = (PrivateKey) ks.getKey("C", null);
System.out.println("Priate Key:"+ Arrays.toString(pk.getEncoded()));
System.out.println("Lengh of key is:"+ Arrays.toString(pk.getEncoded()).length());
sign(SRC, String.format(DEST, 1), chain, pk, DigestAlgorithms.SHA256, provider.getName(), CryptoStandard.CMS, "Test sign", "testing");
命令行的结果是:
My Certificates in chain. First is Main CA .
Public Key Sun RSA public key, 4096 bits
modulus: 7233349847339212226486269.... and etc
public exponent: 65537
Public Key Sun RSA public key, 4096 bits
modulus: 8191375554227623097382171... and etc
public exponent: 65537
Public Key Sun RSA public key, 4096 bits
modulus: 8221477538578824228200634... and etc
public exponent: 65537
Priate Key:[66, 69, 105, 106, 105, 192 ... and etc]
Lengh of key is:306
当我打开PDF文件时,如果我使用我的提供程序,则会出现单一错误。
:至少有一个签名无效:。
当我尝试查看证书时,我发出警告“签名验证时出错。验证时遇到错误。内部加密库错误。错误代码:0x2726”
答案 0 :(得分:0)
查看签名(使用ASN.1转储)显示:
查看代码,问题1表示您的密钥库内容与您的想法不同。一方面“GEO Authentication CA”至少出现一次,别名不等于“T”,另一方面,您的签名者证书似乎不包括在内(或者别名为“T”并被忽略因为那个)。但是,您的私钥包含在“C”中。
问题2是因为iText期望证书数组的第一个条目是签名者证书。由于“GEO Root CA”似乎是您的密钥存储区中的第一个证书,它是您chainList,
中的第一个证书,因此也是chain,
中的第一个证书,因此被iText认为是签名者证书。
要解决您的问题,您必须
chain
证书数组中的第一个。Certificate[] chain = ks.getCertificateChain("C");
检索证书链?这通常用于Digital Signatures for PDF documents ...