further sign stuff

This commit is contained in:
Anthony Stirling
2023-05-21 12:32:24 +01:00
parent 3cad43006a
commit 763aeb5fae
6 changed files with 280 additions and 38 deletions

View File

@@ -52,15 +52,15 @@ public class Beans implements WebMvcConfigurer {
return slr;
}
@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
//messageSource.setBasename("classpath:messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setUseCodeAsDefaultMessage(true);
messageSource.setDefaultLocale(Locale.UK); // setting default locale
return messageSource;
}
// @Bean
// public MessageSource messageSource() {
// ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
// //messageSource.setBasename("classpath:messages");
// messageSource.setDefaultEncoding("UTF-8");
// messageSource.setUseCodeAsDefaultMessage(true);
// messageSource.setDefaultLocale(Locale.UK); // setting default locale
// return messageSource;
// }
}

View File

@@ -44,6 +44,9 @@ import org.springframework.web.multipart.MultipartFile;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.signatures.*;
import stirling.software.SPDF.utils.PdfUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@@ -55,7 +58,7 @@ import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import com.itextpdf.kernel.geom.Rectangle;
@RestController
public class CertSignController {
@@ -66,39 +69,55 @@ public class CertSignController {
}
@PostMapping(consumes = "multipart/form-data", value = "/cert-sign")
public ResponseEntity<String> signPDF(
public ResponseEntity<byte[]> signPDF(
@RequestParam("pdf") MultipartFile pdf,
@RequestParam(value = "certType", required = false) String certType,
@RequestParam(value = "key", required = false) MultipartFile privateKeyFile,
@RequestParam(value = "cert", required = false) MultipartFile certFile,
@RequestParam(value = "p12", required = false) MultipartFile p12File,
@RequestParam(value = "password", required = false) String password) throws Exception {
@RequestParam(value = "password", required = false) String password,
@RequestParam(value = "showSignature", required = false) Boolean showSignature,
@RequestParam(value = "reason", required = false) String reason,
@RequestParam(value = "location", required = false) String location,
@RequestParam(value = "name", required = false) String name,
@RequestParam(value = "pageNumber", required = false) Integer pageNumber) throws Exception {
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
PrivateKey privateKey = null;
X509Certificate cert = null;
if (certType != null) {
switch (certType) {
case "PKCS12":
if (p12File != null) {
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new ByteArrayInputStream(p12File.getBytes()), password.toCharArray());
String alias = ks.aliases().nextElement();
privateKey = (PrivateKey) ks.getKey(alias, password.toCharArray());
cert = (X509Certificate) ks.getCertificate(alias);
}
break;
case "PEM":
if (privateKeyFile != null && certFile != null) {
// Load private key
KeyFactory keyFactory = KeyFactory.getInstance("RSA", provider);
if (isPEM(privateKeyFile.getBytes())) {
privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(parsePEM(privateKeyFile.getBytes())));
} else {
privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyFile.getBytes()));
}
if (p12File != null) {
KeyStore ks = KeyStore.getInstance("PKCS12");
ks.load(new ByteArrayInputStream(p12File.getBytes()), password.toCharArray());
String alias = ks.aliases().nextElement();
privateKey = (PrivateKey) ks.getKey(alias, password.toCharArray());
cert = (X509Certificate) ks.getCertificate(alias);
} else {
// Load private key
KeyFactory keyFactory = KeyFactory.getInstance("RSA", provider);
if (isPEM(privateKeyFile.getBytes())) {
privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(parsePEM(privateKeyFile.getBytes())));
} else {
privateKey = keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyFile.getBytes()));
}
// Load certificate
CertificateFactory certFactory = CertificateFactory.getInstance("X.509", provider);
if (isPEM(certFile.getBytes())) {
cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(parsePEM(certFile.getBytes())));
} else {
cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(certFile.getBytes()));
// Load certificate
CertificateFactory certFactory = CertificateFactory.getInstance("X.509", provider);
if (isPEM(certFile.getBytes())) {
cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(parsePEM(certFile.getBytes())));
} else {
cert = (X509Certificate) certFactory.generateCertificate(new ByteArrayInputStream(certFile.getBytes()));
}
}
break;
}
}
@@ -112,6 +131,42 @@ public class CertSignController {
.setReason("Test")
.setLocation("TestLocation");
if (showSignature != null && showSignature) {
// Get the page size
PdfPage page = signer.getDocument().getPage(1);
Rectangle pageSize = page.getPageSize();
// Define the size of the signature rectangle
float sigWidth = 200; // adjust this as needed
float sigHeight = 100; // adjust this as needed
// Define the margins from the page edges
float marginRight = 36; // adjust this as needed
float marginBottom = 36; // adjust this as needed
// Define the position and dimension of the signature field
Rectangle rect = new Rectangle(
pageSize.getRight() - sigWidth - marginRight,
pageSize.getBottom() + marginBottom,
sigWidth,
sigHeight
);
// Creating the appearance
appearance
.setPageRect(rect)
.setPageNumber(pageNumber)
.setReason(reason)
.setLocation(location)
.setLayer2Text(name) // Set the signer name to be displayed in the signature field
.setReuseAppearance(false);
signer.setFieldName("sig");
signer.setFieldName("sig");
} else {
appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.DESCRIPTION);
}
// Set up the signer
PrivateKeySignature pks = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA256, provider.getName());
IExternalSignature pss = new PrivateKeySignature(privateKey, DigestAlgorithms.SHA256, provider.getName());
@@ -120,13 +175,48 @@ public class CertSignController {
// Call iTex7 to sign the PDF
signer.signDetached(digest, pks, new Certificate[] {cert}, null, null, null, 0, PdfSigner.CryptoStandard.CMS);
// This is just an example, you might want to save this signed PDF into your system or send it back in the response.
// For simplicity, we will just print out the size of the signed PDF.
System.out.println("Signed PDF size: " + signedPdf.size());
return ResponseEntity.ok("Signed PDF successfully");
System.out.println("PDF signed = " + isPdfSigned(signedPdf.toByteArray()));
return PdfUtils.bytesToWebResponse(signedPdf.toByteArray(), "example.pdf");
}
public boolean isPdfSigned(byte[] pdfData) throws IOException {
InputStream pdfStream = new ByteArrayInputStream(pdfData);
PdfDocument pdfDoc = new PdfDocument(new PdfReader(pdfStream));
SignatureUtil signatureUtil = new SignatureUtil(pdfDoc);
List<String> names = signatureUtil.getSignatureNames();
boolean isSigned = false;
for (String name : names) {
PdfPKCS7 pkcs7 = signatureUtil.readSignatureData(name);
if (pkcs7 != null) {
System.out.println("Signature found.");
// Log certificate details
Certificate[] signChain = pkcs7.getSignCertificateChain();
for (Certificate cert : signChain) {
if (cert instanceof X509Certificate) {
X509Certificate x509 = (X509Certificate) cert;
System.out.println("Certificate Details:");
System.out.println("Subject: " + x509.getSubjectDN());
System.out.println("Issuer: " + x509.getIssuerDN());
System.out.println("Serial: " + x509.getSerialNumber());
System.out.println("Not Before: " + x509.getNotBefore());
System.out.println("Not After: " + x509.getNotAfter());
}
}
isSigned = true;
}
}
pdfDoc.close();
return isSigned;
}
private byte[] parsePEM(byte[] content) throws IOException {
PemReader pemReader = new PemReader(new InputStreamReader(new ByteArrayInputStream(content)));
return pemReader.readPemObject().getContent();

View File

@@ -34,4 +34,11 @@ public class SecurityWebController {
model.addAttribute("currentPage", "add-watermark");
return "security/add-watermark";
}
@GetMapping("/cert-sign")
@Hidden
public String certSignForm(Model model) {
model.addAttribute("currentPage", "cert-sign");
return "security/cert-sign";
}
}