現在、私は、PDFファイルを指定して(サーバ証明書を使用して)署名を付け、署名を元のファイルに添付してクライアントに戻すクライアント/サーバーアプリケーションを持っていますこれはPDFBoxで実現します)。
私はそれが正常に動作しますが、私は考えていた私の外部署名のサポートで署名ハンドラ、(内容はPDFファイルです)ファイルダイジェストからpkcs7シグネチャを作成する
public byte[] sign(InputStream content) throws IOException {
try {
System.out.println("Generating CMS signed data");
CMSSignedDataGenerator generator = new CMSSignedDataGenerator();
ContentSigner sha1Signer = new JcaContentSignerBuilder("Sha1WithRSA").build(privateKey);
generator.addSignerInfoGenerator(
new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().build())
.build(sha1Signer, new X509CertificateHolder(certificate.getEncoded())));
CMSTypedData cmsData = new CMSProcessableByteArray(IOUtils.toByteArray(content));
CMSSignedData signedData = generator.generate(cmsData, false);
return signedData.getEncoded();
} catch (GeneralSecurityException e) {
throw new IOException(e);
} catch (CMSException e) {
throw new IOException(e);
} catch (OperatorCreationException e) {
throw new IOException(e);
}
}
を持っている - PDFファイルをアップロードするには大きすぎる何場合? ex:100MB ...それは永遠にかかります! 私は、PDFファイルに署名するのではなく、そのファイルのハッシュ(ex SHA1)に署名するだけで、クライアントが最後にすべてをまとめているのではないかということを考えていますか?
アップデート:私はこれを理解しようとしている、そして今、私の署名方法がある
:
@Override
public byte[] sign(InputStream content) throws IOException {
// testSHA1WithRSAAndAttributeTable
try {
MessageDigest md = MessageDigest.getInstance("SHA1", "BC");
List<Certificate> certList = new ArrayList<Certificate>();
CMSTypedData msg = new CMSProcessableByteArray(IOUtils.toByteArray(content));
certList.add(certificate);
Store certs = new JcaCertStore(certList);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
Attribute attr = new Attribute(CMSAttributes.messageDigest,
new DERSet(new DEROctetString(md.digest(IOUtils.toByteArray(content)))));
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(attr);
SignerInfoGeneratorBuilder builder = new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider())
.setSignedAttributeGenerator(new DefaultSignedAttributeTableGenerator(new AttributeTable(v)));
AlgorithmIdentifier sha1withRSA = new DefaultSignatureAlgorithmIdentifierFinder().find("SHA1withRSA");
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
InputStream in = new ByteArrayInputStream(certificate.getEncoded());
X509Certificate cert = (X509Certificate) certFactory.generateCertificate(in);
gen.addSignerInfoGenerator(builder.build(
new BcRSAContentSignerBuilder(sha1withRSA,
new DefaultDigestAlgorithmIdentifierFinder().find(sha1withRSA))
.build(PrivateKeyFactory.createKey(privateKey.getEncoded())),
new JcaX509CertificateHolder(cert)));
gen.addCertificates(certs);
CMSSignedData s = gen.generate(new CMSAbsentContent(), false);
return new CMSSignedData(msg, s.getEncoded()).getEncoded();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
throw new IOException(e);
}
}
と私はpdfboxでPDFに署名をマージしています
ExternalSigningSupport externalSigning = document.saveIncrementalForExternalSigning(output);
byte[] cmsSignature = sign(externalSigning.getContent());
externalSigning.setSignature(cmsSignature);
問題は、「文書が署名されてから変更または破損している」ため、署名が無効であるということです。 誰も助けることができますか?
これは可能です(そして分かりやすい)。誰もすぐに答えなければ、来週これを調べます。 – mkl
@mkl大変ありがとうございます。それまでは私は自分の研究を続けるつもりです(現時点では可能です) – Snox
あなたの更新に関して:明らかに問題の1つは、あなたが 'InputStream'を2回読むことです。 2回目の試みは常に空の配列になります。私はまだこれを調べるつもりです。 ;) – mkl