further sign stuff
This commit is contained in:
@@ -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;
|
||||
// }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user