Using iText and AWS KMS to digitally sign a PDF document: Part 4
This example was written for the article "Using iText and AWS KMS to digitally sign a PDF document" and demonstrates signing a PDF with iText using an AWS KMS Key Pair.
Assuming your AWS KMS signing key pair has the alias SigningExamples-ECC_NIST_P256 and is indeed an ECC_NIST_P256 key pair you can use the AwsKmsSignature
code from Part 3 to sign a PDF like this:
TestSignSimple
package com.itextpdf.signingexamples.aws.kms;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.List;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.StampingProperties;
import com.itextpdf.signatures.BouncyCastleDigest;
import com.itextpdf.signatures.IExternalDigest;
import com.itextpdf.signatures.PdfSigner;
import com.itextpdf.signatures.PdfSigner.CryptoStandard;
import software.amazon.awssdk.services.kms.model.SigningAlgorithmSpec;
/**
* @author mkl
*/
class TestSignSimple {
final static File RESULT_FOLDER = new File("target/test-outputs", "signature");
@BeforeAll
public static void setUpBeforeClass() throws Exception {
RESULT_FOLDER.mkdirs();
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
}
@Test
void testSignSimpleRsa() throws IOException, GeneralSecurityException {
String keyId = "alias/SigningExamples-RSA_2048";
AwsKmsSignature signature = new AwsKmsSignature(keyId);
Certificate certificate = CertificateUtils.generateSelfSignedCertificate(keyId, "CN=AWS KMS PDF Signing Test,OU=mkl tests,O=mkl");
try ( InputStream resource = getClass().getResourceAsStream("/circles.pdf");
PdfReader pdfReader = new PdfReader(resource);
OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "circles-aws-kms-signed-simple-RSA.pdf"))) {
PdfSigner pdfSigner = new PdfSigner(pdfReader, result, new StampingProperties().useAppendMode());
IExternalDigest externalDigest = new BouncyCastleDigest();
pdfSigner.signDetached(externalDigest, signature, new Certificate[] {certificate}, null, null, null, 0, CryptoStandard.CMS);
}
}
@Test
void testSignSimpleEcdsa() throws IOException, GeneralSecurityException {
String keyId = "alias/SigningExamples-ECC_NIST_P256";
AwsKmsSignature signature = new AwsKmsSignature(keyId);
Certificate certificate = CertificateUtils.generateSelfSignedCertificate(keyId, "CN=AWS KMS PDF Signing Test,OU=mkl tests,O=mkl");
try ( InputStream resource = getClass().getResourceAsStream("/circles.pdf");
PdfReader pdfReader = new PdfReader(resource);
OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "circles-aws-kms-signed-simple-ECDSA.pdf"))) {
PdfSigner pdfSigner = new PdfSigner(pdfReader, result, new StampingProperties().useAppendMode());
IExternalDigest externalDigest = new BouncyCastleDigest();
pdfSigner.signDetached(externalDigest, signature, new Certificate[] {certificate}, null, null, null, 0, CryptoStandard.CMS);
}
}
@Test
void testSignSimpleRsaSsaPss() throws IOException, GeneralSecurityException {
String keyId = "alias/SigningExamples-RSA_2048";
AwsKmsSignature signature = new AwsKmsSignature(keyId, TestSignSimple::selectRsaSsaPss);
Certificate certificate = CertificateUtils.generateSelfSignedCertificate(keyId, "CN=AWS KMS PDF Signing Test,OU=mkl tests,O=mkl");
try ( InputStream resource = getClass().getResourceAsStream("/circles.pdf");
PdfReader pdfReader = new PdfReader(resource);
OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "circles-aws-kms-signed-simple-RSASSA_PSS.pdf"))) {
PdfSigner pdfSigner = new PdfSigner(pdfReader, result, new StampingProperties().useAppendMode());
IExternalDigest externalDigest = new BouncyCastleDigest();
pdfSigner.signDetached(externalDigest, signature, new Certificate[] {certificate}, null, null, null, 0, CryptoStandard.CMS);
}
}
static SigningAlgorithmSpec selectRsaSsaPss (List<SigningAlgorithmSpec> specs) {
if (specs != null)
return specs.stream().filter(spec -> spec.toString().startsWith("RSASSA_PSS")).findFirst().orElse(null);
else
return null;
}
@Test
void testSignSimpleRsaSsaPssExternal() throws IOException, GeneralSecurityException {
String keyId = "alias/SigningExamples-RSA_2048";
X509Certificate certificate = CertificateUtils.generateSelfSignedCertificate(keyId, "CN=AWS KMS PDF Signing Test,OU=mkl tests,O=mkl", TestSignSimple::selectRsaSsaPss);
AwsKmsSignatureContainer signatureContainer = new AwsKmsSignatureContainer(certificate, keyId, TestSignSimple::selectRsaSsaPss);
try ( InputStream resource = getClass().getResourceAsStream("/circles.pdf");
PdfReader pdfReader = new PdfReader(resource);
OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "circles-aws-kms-signed-simple-RSASSA_PSS-External.pdf"))) {
PdfSigner pdfSigner = new PdfSigner(pdfReader, result, new StampingProperties().useAppendMode());
pdfSigner.signExternalContainer(signatureContainer, 8192);
}
}
@Test
void testSignSimpleEcdsaExternal() throws IOException, GeneralSecurityException {
String keyId = "alias/SigningExamples-ECC_NIST_P256";
X509Certificate certificate = CertificateUtils.generateSelfSignedCertificate(keyId, "CN=AWS KMS PDF Signing Test,OU=mkl tests,O=mkl");
AwsKmsSignatureContainer signatureContainer = new AwsKmsSignatureContainer(certificate, keyId);
try ( InputStream resource = getClass().getResourceAsStream("/circles.pdf");
PdfReader pdfReader = new PdfReader(resource);
OutputStream result = new FileOutputStream(new File(RESULT_FOLDER, "circles-aws-kms-signed-simple-ECDSA-External.pdf"))) {
PdfSigner pdfSigner = new PdfSigner(pdfReader, result, new StampingProperties().useAppendMode());
pdfSigner.signExternalContainer(signatureContainer, 8192);
}
}
}
TestSignSimple
using iText.Kernel.Pdf;
using iText.Signatures;
using NUnit.Framework;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.X509;
using System;
using System.IO;
using iText.Bouncycastle.Cert;
using iText.Bouncycastle.X509;
using iText.Commons.Bouncycastle.Cert;
using static iText.Signatures.PdfSigner;
namespace iText.SigningExamples.AwsKms
{
public class TestSignSimple
{
[Test]
public void TestSignSimpleRsa()
{
string testFileName = @"..\..\..\resources\circles.pdf";
string keyId = "alias/SigningExamples-RSA_2048";
Func<System.Collections.Generic.List<string>, string> selector = list => list.Find(name => name.StartsWith("RSASSA_PKCS1_V1_5"));
AwsKmsSignature signature = new AwsKmsSignature(keyId, selector);
System.Security.Cryptography.X509Certificates.X509Certificate2 certificate2 = CertificateUtils.GenerateSelfSignedCertificate(
keyId,
"CN=AWS KMS PDF Signing Test RSA,OU=signing tests,O=iText",
selector
);
X509Certificate certificate = new X509Certificate(X509CertificateStructure.GetInstance(certificate2.RawData));
using (PdfReader pdfReader = new PdfReader(testFileName))
using (FileStream result = File.Create("circles-aws-kms-signed-simple-RSA.pdf"))
{
PdfSigner pdfSigner = new PdfSigner(pdfReader, result, new StampingProperties().UseAppendMode());
pdfSigner.SignDetached(signature, new IX509Certificate[] { new X509CertificateBC(certificate) }, null, null, null, 0, CryptoStandard.CMS);
}
}
[Test]
public void TestSignSimpleEcdsa()
{
string testFileName = @"..\..\..\resources\circles.pdf";
string keyId = "alias/SigningExamples-ECC_NIST_P256";
Func<System.Collections.Generic.List<string>, string> selector = list => list.Find(name => name.StartsWith("ECDSA_SHA_256"));
AwsKmsSignature signature = new AwsKmsSignature(keyId, selector);
System.Security.Cryptography.X509Certificates.X509Certificate2 certificate2 = CertificateUtils.GenerateSelfSignedCertificate(
keyId,
"CN=AWS KMS PDF Signing Test ECDSA,OU=signing tests,O=iText",
selector
);
X509Certificate certificate = new X509Certificate(X509CertificateStructure.GetInstance(certificate2.RawData));
using (PdfReader pdfReader = new PdfReader(testFileName))
using (FileStream result = File.Create("circles-aws-kms-signed-simple-ECDSA.pdf"))
{
PdfSigner pdfSigner = new PdfSigner(pdfReader, result, new StampingProperties().UseAppendMode());
pdfSigner.SignDetached(signature, new IX509Certificate[] { new X509CertificateBC(certificate) }, null, null, null, 0, CryptoStandard.CMS);
}
}
[Test]
public void TestSignSimpleRsaSsaPss()
{
string testFileName = @"..\..\..\resources\circles.pdf";
string keyId = "alias/SigningExamples-RSA_2048";
Func<System.Collections.Generic.List<string>, string> selector = list => list.Find(name => name.StartsWith("RSASSA_PSS"));
AwsKmsSignature signature = new AwsKmsSignature(keyId, selector);
System.Security.Cryptography.X509Certificates.X509Certificate2 certificate2 = CertificateUtils.GenerateSelfSignedCertificate(
keyId,
"CN=AWS KMS PDF Signing Test RSAwithMGF1,OU=signing tests,O=iText",
selector
);
X509Certificate certificate = new X509Certificate(X509CertificateStructure.GetInstance(certificate2.RawData));
using (PdfReader pdfReader = new PdfReader(testFileName))
using (FileStream result = File.Create("circles-aws-kms-signed-simple-RSAwithMGF1.pdf"))
{
PdfSigner pdfSigner = new PdfSigner(pdfReader, result, new StampingProperties().UseAppendMode());
pdfSigner.SignDetached(signature, new IX509Certificate[] { new X509CertificateBC(certificate) }, null, null, null, 0, CryptoStandard.CMS);
}
}
[Test]
public void TestSignSimpleRsaSsaPssExternal()
{
string testFileName = @"..\..\..\resources\circles.pdf";
string keyId = "alias/SigningExamples-RSA_2048";
Func<System.Collections.Generic.List<string>, string> selector = list => list.Find(name => name.StartsWith("RSASSA_PSS"));
System.Security.Cryptography.X509Certificates.X509Certificate2 certificate2 = CertificateUtils.GenerateSelfSignedCertificate(
keyId,
"CN=AWS KMS PDF Signing Test RSAwithMGF1,OU=signing tests,O=iText",
selector
);
X509Certificate certificate = new X509Certificate(X509CertificateStructure.GetInstance(certificate2.RawData));
AwsKmsSignatureContainer signature = new AwsKmsSignatureContainer(certificate, keyId, selector);
using (PdfReader pdfReader = new PdfReader(testFileName))
using (FileStream result = File.Create("circles-aws-kms-signed-simple-RSAwithMGF1-external.pdf"))
{
PdfSigner pdfSigner = new PdfSigner(pdfReader, result, new StampingProperties().UseAppendMode());
pdfSigner.SignExternalContainer(signature, 8192);
}
}
[Test]
public void TestSignSimpleEcdsaExternal()
{
string testFileName = @"..\..\..\resources\circles.pdf";
string keyId = "alias/SigningExamples-ECC_NIST_P256";
Func<System.Collections.Generic.List<string>, string> selector = list => list.Find(name => name.StartsWith("ECDSA_SHA_256"));
System.Security.Cryptography.X509Certificates.X509Certificate2 certificate2 = CertificateUtils.GenerateSelfSignedCertificate(
keyId,
"CN=AWS KMS PDF Signing Test ECDSA,OU=signing tests,O=iText",
selector
);
X509Certificate certificate = new X509Certificate(X509CertificateStructure.GetInstance(certificate2.RawData));
AwsKmsSignatureContainer signature = new AwsKmsSignatureContainer(certificate, keyId, selector);
using (PdfReader pdfReader = new PdfReader(testFileName))
using (FileStream result = File.Create("circles-aws-kms-signed-simple-ECDSA-External.pdf"))
{
PdfSigner pdfSigner = new PdfSigner(pdfReader, result, new StampingProperties().UseAppendMode());
pdfSigner.SignExternalContainer(signature, 8192);
}
}
}
}
Note: The article assumes that you have stored your credentials in the default
section of your ~/.aws/credentials
file and your region in the default
section of your ~/.aws/config
file. Otherwise, you'll have to adapt the KmsClient
instantiation or initialization in the code examples written for this article.
For the other examples relating to this article, please see the following links: