mirror of
				https://github.com/Frooodle/Stirling-PDF.git
				synced 2025-11-01 01:21:18 +01:00 
			
		
		
		
	
							parent
							
								
									88f3594d80
								
							
						
					
					
						commit
						a7ed99084f
					
				@ -1,8 +1,11 @@
 | 
				
			|||||||
package stirling.software.SPDF.controller.api.security;
 | 
					package stirling.software.SPDF.controller.api.security;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.awt.Color;
 | 
				
			||||||
import java.io.ByteArrayInputStream;
 | 
					import java.io.ByteArrayInputStream;
 | 
				
			||||||
import java.io.ByteArrayOutputStream;
 | 
					import java.io.ByteArrayOutputStream;
 | 
				
			||||||
 | 
					import java.io.File;
 | 
				
			||||||
import java.io.IOException;
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.io.InputStream;
 | 
				
			||||||
import java.io.InputStreamReader;
 | 
					import java.io.InputStreamReader;
 | 
				
			||||||
import java.io.OutputStream;
 | 
					import java.io.OutputStream;
 | 
				
			||||||
import java.security.KeyStore;
 | 
					import java.security.KeyStore;
 | 
				
			||||||
@ -14,12 +17,38 @@ import java.security.UnrecoverableKeyException;
 | 
				
			|||||||
import java.security.cert.Certificate;
 | 
					import java.security.cert.Certificate;
 | 
				
			||||||
import java.security.cert.CertificateException;
 | 
					import java.security.cert.CertificateException;
 | 
				
			||||||
import java.security.cert.CertificateFactory;
 | 
					import java.security.cert.CertificateFactory;
 | 
				
			||||||
 | 
					import java.security.cert.X509Certificate;
 | 
				
			||||||
import java.util.Calendar;
 | 
					import java.util.Calendar;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.apache.pdfbox.examples.signature.CreateSignatureBase;
 | 
					import org.apache.pdfbox.examples.signature.CreateSignatureBase;
 | 
				
			||||||
import org.apache.pdfbox.pdmodel.PDDocument;
 | 
					import org.apache.pdfbox.pdmodel.PDDocument;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.PDPage;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.PDPageContentStream;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.PDResources;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.common.PDRectangle;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.common.PDStream;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.font.PDFont;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.font.PDType1Font;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.font.Standard14Fonts.FontName;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.graphics.blend.BlendMode;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.graphics.form.PDFormXObject;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.graphics.state.PDExtendedGraphicsState;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.interactive.annotation.PDAnnotationWidget;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceDictionary;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.interactive.annotation.PDAppearanceStream;
 | 
				
			||||||
import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
 | 
					import org.apache.pdfbox.pdmodel.interactive.digitalsignature.PDSignature;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.interactive.digitalsignature.SignatureOptions;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.interactive.form.PDAcroForm;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.interactive.form.PDField;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.pdmodel.interactive.form.PDSignatureField;
 | 
				
			||||||
 | 
					import org.apache.pdfbox.util.Matrix;
 | 
				
			||||||
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
 | 
					import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
 | 
				
			||||||
 | 
					import org.bouncycastle.asn1.x500.RDN;
 | 
				
			||||||
 | 
					import org.bouncycastle.asn1.x500.X500Name;
 | 
				
			||||||
 | 
					import org.bouncycastle.asn1.x500.style.BCStyle;
 | 
				
			||||||
 | 
					import org.bouncycastle.asn1.x500.style.IETFUtils;
 | 
				
			||||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
 | 
					import org.bouncycastle.jce.provider.BouncyCastleProvider;
 | 
				
			||||||
import org.bouncycastle.openssl.PEMDecryptorProvider;
 | 
					import org.bouncycastle.openssl.PEMDecryptorProvider;
 | 
				
			||||||
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
 | 
					import org.bouncycastle.openssl.PEMEncryptedKeyPair;
 | 
				
			||||||
@ -35,6 +64,7 @@ import org.bouncycastle.pkcs.PKCSException;
 | 
				
			|||||||
import org.slf4j.Logger;
 | 
					import org.slf4j.Logger;
 | 
				
			||||||
import org.slf4j.LoggerFactory;
 | 
					import org.slf4j.LoggerFactory;
 | 
				
			||||||
import org.springframework.beans.factory.annotation.Autowired;
 | 
					import org.springframework.beans.factory.annotation.Autowired;
 | 
				
			||||||
 | 
					import org.springframework.core.io.ClassPathResource;
 | 
				
			||||||
import org.springframework.http.ResponseEntity;
 | 
					import org.springframework.http.ResponseEntity;
 | 
				
			||||||
import org.springframework.web.bind.annotation.ModelAttribute;
 | 
					import org.springframework.web.bind.annotation.ModelAttribute;
 | 
				
			||||||
import org.springframework.web.bind.annotation.PostMapping;
 | 
					import org.springframework.web.bind.annotation.PostMapping;
 | 
				
			||||||
@ -62,13 +92,103 @@ public class CertSignController {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class CreateSignature extends CreateSignatureBase {
 | 
					    class CreateSignature extends CreateSignatureBase {
 | 
				
			||||||
 | 
					        File imageFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public CreateSignature(KeyStore keystore, char[] pin)
 | 
					        public CreateSignature(KeyStore keystore, char[] pin)
 | 
				
			||||||
                throws KeyStoreException,
 | 
					                throws KeyStoreException,
 | 
				
			||||||
                        UnrecoverableKeyException,
 | 
					                UnrecoverableKeyException,
 | 
				
			||||||
                        NoSuchAlgorithmException,
 | 
					                NoSuchAlgorithmException,
 | 
				
			||||||
                        IOException,
 | 
					                IOException,
 | 
				
			||||||
                        CertificateException {
 | 
					                CertificateException {
 | 
				
			||||||
            super(keystore, pin);
 | 
					            super(keystore, pin);
 | 
				
			||||||
 | 
					            ClassPathResource resource = new ClassPathResource("static/images/signature.png");
 | 
				
			||||||
 | 
					            imageFile = resource.getFile();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public InputStream createVisibleSignature(PDDocument srcDoc, PDSignature signature, Integer pageNumber,
 | 
				
			||||||
 | 
					                Boolean showImage) throws IOException {
 | 
				
			||||||
 | 
					            // modified from org.apache.pdfbox.examples.signature.CreateVisibleSignature2
 | 
				
			||||||
 | 
					            try (PDDocument doc = new PDDocument()) {
 | 
				
			||||||
 | 
					                PDPage page = new PDPage(srcDoc.getPage(pageNumber).getMediaBox());
 | 
				
			||||||
 | 
					                doc.addPage(page);
 | 
				
			||||||
 | 
					                PDAcroForm acroForm = new PDAcroForm(doc);
 | 
				
			||||||
 | 
					                doc.getDocumentCatalog().setAcroForm(acroForm);
 | 
				
			||||||
 | 
					                PDSignatureField signatureField = new PDSignatureField(acroForm);
 | 
				
			||||||
 | 
					                PDAnnotationWidget widget = signatureField.getWidgets().get(0);
 | 
				
			||||||
 | 
					                List<PDField> acroFormFields = acroForm.getFields();
 | 
				
			||||||
 | 
					                acroForm.setSignaturesExist(true);
 | 
				
			||||||
 | 
					                acroForm.setAppendOnly(true);
 | 
				
			||||||
 | 
					                acroForm.getCOSObject().setDirect(true);
 | 
				
			||||||
 | 
					                acroFormFields.add(signatureField);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                PDRectangle rect = new PDRectangle(0, 0, 200, 50);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                widget.setRectangle(rect);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // from PDVisualSigBuilder.createHolderForm()
 | 
				
			||||||
 | 
					                PDStream stream = new PDStream(doc);
 | 
				
			||||||
 | 
					                PDFormXObject form = new PDFormXObject(stream);
 | 
				
			||||||
 | 
					                PDResources res = new PDResources();
 | 
				
			||||||
 | 
					                form.setResources(res);
 | 
				
			||||||
 | 
					                form.setFormType(1);
 | 
				
			||||||
 | 
					                PDRectangle bbox = new PDRectangle(rect.getWidth(), rect.getHeight());
 | 
				
			||||||
 | 
					                float height = bbox.getHeight();
 | 
				
			||||||
 | 
					                form.setBBox(bbox);
 | 
				
			||||||
 | 
					                PDFont font = new PDType1Font(FontName.TIMES_BOLD);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // from PDVisualSigBuilder.createAppearanceDictionary()
 | 
				
			||||||
 | 
					                PDAppearanceDictionary appearance = new PDAppearanceDictionary();
 | 
				
			||||||
 | 
					                appearance.getCOSObject().setDirect(true);
 | 
				
			||||||
 | 
					                PDAppearanceStream appearanceStream = new PDAppearanceStream(form.getCOSObject());
 | 
				
			||||||
 | 
					                appearance.setNormalAppearance(appearanceStream);
 | 
				
			||||||
 | 
					                widget.setAppearance(appearance);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                try (PDPageContentStream cs = new PDPageContentStream(doc, appearanceStream)) {
 | 
				
			||||||
 | 
					                    if (showImage) {
 | 
				
			||||||
 | 
					                        cs.saveGraphicsState();
 | 
				
			||||||
 | 
					                        PDExtendedGraphicsState extState = new PDExtendedGraphicsState();
 | 
				
			||||||
 | 
					                        extState.setBlendMode(BlendMode.MULTIPLY);
 | 
				
			||||||
 | 
					                        extState.setNonStrokingAlphaConstant(0.5f);
 | 
				
			||||||
 | 
					                        cs.setGraphicsStateParameters(extState);
 | 
				
			||||||
 | 
					                        cs.transform(Matrix.getScaleInstance(0.08f, 0.08f));
 | 
				
			||||||
 | 
					                        PDImageXObject img = PDImageXObject.createFromFileByExtension(imageFile,
 | 
				
			||||||
 | 
					                                doc);
 | 
				
			||||||
 | 
					                        cs.drawImage(img, 100, 0);
 | 
				
			||||||
 | 
					                        cs.restoreGraphicsState();
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // show text
 | 
				
			||||||
 | 
					                    float fontSize = 10;
 | 
				
			||||||
 | 
					                    float leading = fontSize * 1.5f;
 | 
				
			||||||
 | 
					                    cs.beginText();
 | 
				
			||||||
 | 
					                    cs.setFont(font, fontSize);
 | 
				
			||||||
 | 
					                    cs.setNonStrokingColor(Color.black);
 | 
				
			||||||
 | 
					                    cs.newLineAtOffset(fontSize, height - leading);
 | 
				
			||||||
 | 
					                    cs.setLeading(leading);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    X509Certificate cert = (X509Certificate) getCertificateChain()[0];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    // https://stackoverflow.com/questions/2914521/
 | 
				
			||||||
 | 
					                    X500Name x500Name = new X500Name(cert.getSubjectX500Principal().getName());
 | 
				
			||||||
 | 
					                    RDN cn = x500Name.getRDNs(BCStyle.CN)[0];
 | 
				
			||||||
 | 
					                    String name = IETFUtils.valueToString(cn.getFirst().getValue());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    String date = signature.getSignDate().getTime().toString();
 | 
				
			||||||
 | 
					                    String reason = signature.getReason();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    cs.showText("Signed by " + name);
 | 
				
			||||||
 | 
					                    cs.newLine();
 | 
				
			||||||
 | 
					                    cs.showText(date);
 | 
				
			||||||
 | 
					                    cs.newLine();
 | 
				
			||||||
 | 
					                    cs.showText(reason);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    cs.endText();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                ByteArrayOutputStream baos = new ByteArrayOutputStream();
 | 
				
			||||||
 | 
					                doc.save(baos);
 | 
				
			||||||
 | 
					                return new ByteArrayInputStream(baos.toByteArray());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -80,10 +200,7 @@ public class CertSignController {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @PostMapping(consumes = "multipart/form-data", value = "/cert-sign")
 | 
					    @PostMapping(consumes = "multipart/form-data", value = "/cert-sign")
 | 
				
			||||||
    @Operation(
 | 
					    @Operation(summary = "Sign PDF with a Digital Certificate", description = "This endpoint accepts a PDF file, a digital certificate and related information to sign the PDF. It then returns the digitally signed PDF file. Input:PDF Output:PDF Type:SISO")
 | 
				
			||||||
            summary = "Sign PDF with a Digital Certificate",
 | 
					 | 
				
			||||||
            description =
 | 
					 | 
				
			||||||
                    "This endpoint accepts a PDF file, a digital certificate and related information to sign the PDF. It then returns the digitally signed PDF file. Input:PDF Output:PDF Type:SISO")
 | 
					 | 
				
			||||||
    public ResponseEntity<byte[]> signPDFWithCert(@ModelAttribute SignPDFWithCertRequest request)
 | 
					    public ResponseEntity<byte[]> signPDFWithCert(@ModelAttribute SignPDFWithCertRequest request)
 | 
				
			||||||
            throws Exception {
 | 
					            throws Exception {
 | 
				
			||||||
        MultipartFile pdf = request.getFileInput();
 | 
					        MultipartFile pdf = request.getFileInput();
 | 
				
			||||||
@ -97,7 +214,7 @@ public class CertSignController {
 | 
				
			|||||||
        String reason = request.getReason();
 | 
					        String reason = request.getReason();
 | 
				
			||||||
        String location = request.getLocation();
 | 
					        String location = request.getLocation();
 | 
				
			||||||
        String name = request.getName();
 | 
					        String name = request.getName();
 | 
				
			||||||
        Integer pageNumber = request.getPageNumber();
 | 
					        Integer pageNumber = request.getPageNumber() - 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (certType == null) {
 | 
					        if (certType == null) {
 | 
				
			||||||
            throw new IllegalArgumentException("Cert type must be provided");
 | 
					            throw new IllegalArgumentException("Cert type must be provided");
 | 
				
			||||||
@ -112,7 +229,7 @@ public class CertSignController {
 | 
				
			|||||||
                PrivateKey privateKey = getPrivateKeyFromPEM(privateKeyFile.getBytes(), password);
 | 
					                PrivateKey privateKey = getPrivateKeyFromPEM(privateKeyFile.getBytes(), password);
 | 
				
			||||||
                Certificate cert = (Certificate) getCertificateFromPEM(certFile.getBytes());
 | 
					                Certificate cert = (Certificate) getCertificateFromPEM(certFile.getBytes());
 | 
				
			||||||
                ks.setKeyEntry(
 | 
					                ks.setKeyEntry(
 | 
				
			||||||
                        "alias", privateKey, password.toCharArray(), new Certificate[] {cert});
 | 
					                        "alias", privateKey, password.toCharArray(), new Certificate[] { cert });
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            case "PKCS12":
 | 
					            case "PKCS12":
 | 
				
			||||||
                ks = KeyStore.getInstance("PKCS12");
 | 
					                ks = KeyStore.getInstance("PKCS12");
 | 
				
			||||||
@ -126,11 +243,10 @@ public class CertSignController {
 | 
				
			|||||||
                throw new IllegalArgumentException("Invalid cert type: " + certType);
 | 
					                throw new IllegalArgumentException("Invalid cert type: " + certType);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // TODO: page number
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        CreateSignature createSignature = new CreateSignature(ks, password.toCharArray());
 | 
					        CreateSignature createSignature = new CreateSignature(ks, password.toCharArray());
 | 
				
			||||||
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
 | 
					        ByteArrayOutputStream baos = new ByteArrayOutputStream();
 | 
				
			||||||
        sign(pdfDocumentFactory, pdf.getBytes(), baos, createSignature, name, location, reason);
 | 
					        sign(pdfDocumentFactory, pdf.getBytes(), baos, createSignature, showSignature, pageNumber, name, location,
 | 
				
			||||||
 | 
					                reason);
 | 
				
			||||||
        return WebResponseUtils.boasToWebResponse(
 | 
					        return WebResponseUtils.boasToWebResponse(
 | 
				
			||||||
                baos,
 | 
					                baos,
 | 
				
			||||||
                Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
 | 
					                Filenames.toSimpleFileName(pdf.getOriginalFilename()).replaceFirst("[.][^.]+$", "")
 | 
				
			||||||
@ -142,6 +258,8 @@ public class CertSignController {
 | 
				
			|||||||
            byte[] input,
 | 
					            byte[] input,
 | 
				
			||||||
            OutputStream output,
 | 
					            OutputStream output,
 | 
				
			||||||
            CreateSignature instance,
 | 
					            CreateSignature instance,
 | 
				
			||||||
 | 
					            Boolean showSignature,
 | 
				
			||||||
 | 
					            Integer pageNumber,
 | 
				
			||||||
            String name,
 | 
					            String name,
 | 
				
			||||||
            String location,
 | 
					            String location,
 | 
				
			||||||
            String reason) {
 | 
					            String reason) {
 | 
				
			||||||
@ -154,7 +272,17 @@ public class CertSignController {
 | 
				
			|||||||
            signature.setReason(reason);
 | 
					            signature.setReason(reason);
 | 
				
			||||||
            signature.setSignDate(Calendar.getInstance());
 | 
					            signature.setSignDate(Calendar.getInstance());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            doc.addSignature(signature, instance);
 | 
					            if (showSignature) {
 | 
				
			||||||
 | 
					                SignatureOptions signatureOptions = new SignatureOptions();
 | 
				
			||||||
 | 
					                signatureOptions
 | 
				
			||||||
 | 
					                        .setVisualSignature(instance.createVisibleSignature(doc, signature, pageNumber, true));
 | 
				
			||||||
 | 
					                signatureOptions.setPage(pageNumber);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                doc.addSignature(signature, instance, signatureOptions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                doc.addSignature(signature, instance);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            doc.saveIncremental(output);
 | 
					            doc.saveIncremental(output);
 | 
				
			||||||
        } catch (Exception e) {
 | 
					        } catch (Exception e) {
 | 
				
			||||||
            logger.error("exception", e);
 | 
					            logger.error("exception", e);
 | 
				
			||||||
@ -163,22 +291,19 @@ public class CertSignController {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private PrivateKey getPrivateKeyFromPEM(byte[] pemBytes, String password)
 | 
					    private PrivateKey getPrivateKeyFromPEM(byte[] pemBytes, String password)
 | 
				
			||||||
            throws IOException, OperatorCreationException, PKCSException {
 | 
					            throws IOException, OperatorCreationException, PKCSException {
 | 
				
			||||||
        try (PEMParser pemParser =
 | 
					        try (PEMParser pemParser = new PEMParser(new InputStreamReader(new ByteArrayInputStream(pemBytes)))) {
 | 
				
			||||||
                new PEMParser(new InputStreamReader(new ByteArrayInputStream(pemBytes)))) {
 | 
					 | 
				
			||||||
            Object pemObject = pemParser.readObject();
 | 
					            Object pemObject = pemParser.readObject();
 | 
				
			||||||
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
 | 
					            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
 | 
				
			||||||
            PrivateKeyInfo pkInfo;
 | 
					            PrivateKeyInfo pkInfo;
 | 
				
			||||||
            if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo) {
 | 
					            if (pemObject instanceof PKCS8EncryptedPrivateKeyInfo) {
 | 
				
			||||||
                InputDecryptorProvider decProv =
 | 
					                InputDecryptorProvider decProv = new JceOpenSSLPKCS8DecryptorProviderBuilder()
 | 
				
			||||||
                        new JceOpenSSLPKCS8DecryptorProviderBuilder().build(password.toCharArray());
 | 
					                        .build(password.toCharArray());
 | 
				
			||||||
                pkInfo = ((PKCS8EncryptedPrivateKeyInfo) pemObject).decryptPrivateKeyInfo(decProv);
 | 
					                pkInfo = ((PKCS8EncryptedPrivateKeyInfo) pemObject).decryptPrivateKeyInfo(decProv);
 | 
				
			||||||
            } else if (pemObject instanceof PEMEncryptedKeyPair) {
 | 
					            } else if (pemObject instanceof PEMEncryptedKeyPair) {
 | 
				
			||||||
                PEMDecryptorProvider decProv =
 | 
					                PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password.toCharArray());
 | 
				
			||||||
                        new JcePEMDecryptorProviderBuilder().build(password.toCharArray());
 | 
					                pkInfo = ((PEMEncryptedKeyPair) pemObject)
 | 
				
			||||||
                pkInfo =
 | 
					                        .decryptKeyPair(decProv)
 | 
				
			||||||
                        ((PEMEncryptedKeyPair) pemObject)
 | 
					                        .getPrivateKeyInfo();
 | 
				
			||||||
                                .decryptKeyPair(decProv)
 | 
					 | 
				
			||||||
                                .getPrivateKeyInfo();
 | 
					 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                pkInfo = ((PEMKeyPair) pemObject).getPrivateKeyInfo();
 | 
					                pkInfo = ((PEMKeyPair) pemObject).getPrivateKeyInfo();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										
											BIN
										
									
								
								src/main/resources/static/images/signature.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								src/main/resources/static/images/signature.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 19 KiB  | 
@ -71,7 +71,7 @@
 | 
				
			|||||||
                    <label for="name" th:text="#{certSign.name}"></label> <input type="text" class="form-control" id="name" name="name">
 | 
					                    <label for="name" th:text="#{certSign.name}"></label> <input type="text" class="form-control" id="name" name="name">
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                  <div class="mb-3">
 | 
					                  <div class="mb-3">
 | 
				
			||||||
                    <label for="pageNumber" th:text="#{pageNum}"></label> <input type="number" class="form-control" id="pageNumber" name="pageNumber" min="1" disabled>
 | 
					                    <label for="pageNumber" th:text="#{pageNum}"></label> <input type="number" class="form-control" id="pageNumber" name="pageNumber" min="1">
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div class="mb-3 text-left">
 | 
					                <div class="mb-3 text-left">
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user