Browse Source

测试p7签名方法

syh 5 years ago
parent
commit
a21c0b79f1

+ 3 - 3
jeecg-boot-base-common/src/main/java/org/jeecg/common/system/util/JeecgDataAutorUtils.java

@@ -29,7 +29,7 @@ public class JeecgDataAutorUtils {
 	 * 往链接请求里面,传入数据查询条件
 	 * 
 	 * @param request
-	 * @param MENU_DATA_AUTHOR_RULES
+     * @param dataRules
 	 */
 	public static synchronized void installDataSearchConditon(HttpServletRequest request, List<SysPermissionDataRule> dataRules) {
 		@SuppressWarnings("unchecked")
@@ -60,7 +60,7 @@ public class JeecgDataAutorUtils {
      *
 	 * @return
 	 */
-	public static synchronized String loadDataSearchConditonSQLString() {
+    public static synchronized String loadDataSearchConditonSqlString() {
 		return (String) SpringContextUtils.getHttpServletRequest().getAttribute(MENU_DATA_AUTHOR_RULE_SQL);
 	}
 
@@ -70,7 +70,7 @@ public class JeecgDataAutorUtils {
 	 * @param request
 	 */
 	public static synchronized void installDataSearchConditon(HttpServletRequest request, String sql) {
-		String ruleSql = (String)loadDataSearchConditonSQLString();
+        String ruleSql = (String) loadDataSearchConditonSqlString();
 		if (!StringUtils.hasText(ruleSql)) {
 			request.setAttribute(MENU_DATA_AUTHOR_RULE_SQL,sql);
 		}

+ 10 - 6
jeecg-boot-module-system/pom.xml

@@ -28,6 +28,11 @@
                 <enabled>false</enabled>
             </snapshots>
         </repository>
+        <repository>
+            <id>com.e-iceblue</id>
+            <name>e-iceblue</name>
+            <url>http://repo.e-iceblue.com/nexus/content/groups/public/</url>
+        </repository>
     </repositories>
 
     <dependencies>
@@ -84,12 +89,11 @@
             <artifactId>itextpdf</artifactId>
             <version>5.5.13</version>
         </dependency>
-        <!--<dependency>
-            <groupId>com.itextpdf</groupId>
-            <artifactId>itext7-core</artifactId>
-            <version>7.1.4</version>
-            <type>pom</type>
-        </dependency>-->
+        <dependency>
+            <groupId>e-iceblue</groupId>
+            <artifactId>spire.pdf</artifactId>
+            <version>2.2.0</version>
+        </dependency>
     </dependencies>
 
     <build>

+ 11 - 11
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/sign/itext5/ItextUtils.java

@@ -55,10 +55,10 @@ public class ItextUtils {
      * @param password       密码
      * @param issuerStr      颁发机构信息
      * @param subjectStr     使用者信息
-     * @param certificateCRL 颁发地址
+     * @param certificateCrl 颁发地址
      * @return
      */
-    public static Map<String, byte[]> createCert(String password, String issuerStr, String subjectStr, String certificateCRL) {
+    public static Map<String, byte[]> createCert(String password, String issuerStr, String subjectStr, String certificateCrl) {
 
         Map<String, byte[]> result = new HashMap<String, byte[]>();
         ByteArrayOutputStream out = null;
@@ -70,7 +70,7 @@ public class ItextUtils {
             keyStore.load(null, null);
             KeyPair keyPair = getKey();
             //  issuer与 subject相同的证书就是CA证书
-            Certificate cert = generateCertificateV3(issuerStr, subjectStr, keyPair, result, certificateCRL, null);
+            Certificate cert = generateCertificateV3(issuerStr, subjectStr, keyPair, result, certificateCrl, null);
             // cretkey随便写,标识别名
             keyStore.setKeyEntry("cretkey", keyPair.getPrivate(), password.toCharArray(), new Certificate[]{cert});
             out = new ByteArrayOutputStream();
@@ -97,12 +97,12 @@ public class ItextUtils {
      * @param subjectStr
      * @param keyPair
      * @param result
-     * @param certificateCRL
+     * @param certificateCrl
      * @param extensions
      * @return
      */
     public static Certificate generateCertificateV3(String issuerStr, String subjectStr, KeyPair keyPair, Map<String, byte[]> result,
-                                                    String certificateCRL, List<Extension> extensions) {
+                                                    String certificateCrl, List<Extension> extensions) {
 
         ByteArrayInputStream bout = null;
         X509Certificate cert = null;
@@ -124,14 +124,14 @@ public class ItextUtils {
             jBuilder.setSecureRandom(secureRandom);
             ContentSigner singer = jBuilder.setProvider(new BouncyCastleProvider()).build(privateKey);
             // 分发点
-            ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31");
-            GeneralName generalName = new GeneralName(GeneralName.uniformResourceIdentifier, certificateCRL);
+            ASN1ObjectIdentifier crlDistributionPoints = new ASN1ObjectIdentifier("2.5.29.31");
+            GeneralName generalName = new GeneralName(GeneralName.uniformResourceIdentifier, certificateCrl);
             GeneralNames seneralNames = new GeneralNames(generalName);
             DistributionPointName distributionPoint = new DistributionPointName(seneralNames);
             DistributionPoint[] points = new DistributionPoint[1];
             points[0] = new DistributionPoint(distributionPoint, null, null);
-            CRLDistPoint cRLDistPoint = new CRLDistPoint(points);
-            builder.addExtension(cRLDistributionPoints, true, cRLDistPoint);
+            CRLDistPoint crlDistPoint = new CRLDistPoint(points);
+            builder.addExtension(crlDistributionPoints, true, crlDistPoint);
             // 用途
             ASN1ObjectIdentifier keyUsage = new ASN1ObjectIdentifier("2.5.29.15");
             // | KeyUsage.nonRepudiation | KeyUsage.keyCertSign
@@ -183,8 +183,8 @@ public class ItextUtils {
         // ST: 州或省份名称  C: 单位的两字母国家代码
         String issuerStr = "CN=天天凭证,OU=研发部,O=gitbook有限公司,C=CN,E=gitbook@sina.com,L=北京,ST=北京";
         String subjectStr = "CN=huangjinjin,OU=用户,O=借款人,C=CN,E=huangjinjin@sina.com,L=北京,ST=北京";
-        String certificateCRL = "https://gitbook.cn";
-        Map<String, byte[]> result = createCert("123456", issuerStr, subjectStr, certificateCRL);
+        String certificateCrl = "https://gitbook.cn";
+        Map<String, byte[]> result = createCert("123456", issuerStr, subjectStr, certificateCrl);
 
 //		FileOutputStream outPutStream = new FileOutputStream("C:/pdf/keystore.p12"); // 生成.p12
 //		outPutStream.write(result.get("keyStoreData"));

+ 7 - 7
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/sign/itext5/Pkcs.java

@@ -43,11 +43,11 @@ public class Pkcs {
      * @param password       密码
      * @param issuerStr      颁发机构信息
      * @param subjectStr     使用者信息
-     * @param certificateCRL 颁发地址
+     * @param certificateCrl 颁发地址
      * @return
      */
     public static Map<String, byte[]> createCert(String password,
-                                                 String issuerStr, String subjectStr, String certificateCRL) {
+                                                 String issuerStr, String subjectStr, String certificateCrl) {
         Map<String, byte[]> result = new HashMap<String, byte[]>();
         ByteArrayOutputStream out = null;
         try {
@@ -60,7 +60,7 @@ public class Pkcs {
             KeyPair keyPair = getKey();
             // issuer与 subject相同的证书就是CA证书
             Certificate cert = generateCertificateV3(issuerStr, subjectStr,
-                    keyPair, result, certificateCRL, null);
+                    keyPair, result, certificateCrl, null);
             // cretkey随便写,标识别名
             keyStore.setKeyEntry("cretkey", keyPair.getPrivate(),
                     password.toCharArray(), new Certificate[]{cert});
@@ -88,13 +88,13 @@ public class Pkcs {
      * @param subjectStr
      * @param keyPair
      * @param result
-     * @param certificateCRL
+     * @param certificateCrl
      * @param extensions
      * @return
      */
     public static Certificate generateCertificateV3(String issuerStr,
                                                     String subjectStr, KeyPair keyPair, Map<String, byte[]> result,
-                                                    String certificateCRL, List<Extension> extensions) {
+                                                    String certificateCrl, List<Extension> extensions) {
         ByteArrayInputStream bout = null;
         X509Certificate cert = null;
         try {
@@ -121,7 +121,7 @@ public class Pkcs {
             ASN1ObjectIdentifier cRLDistributionPoints = new ASN1ObjectIdentifier(
                     "2.5.29.31");
             GeneralName generalName = new GeneralName(
-                    GeneralName.uniformResourceIdentifier, certificateCRL);
+                    GeneralName.uniformResourceIdentifier, certificateCrl);
             GeneralNames seneralNames = new GeneralNames(generalName);
             DistributionPointName distributionPoint = new DistributionPointName(
                     seneralNames);
@@ -213,7 +213,7 @@ public class Pkcs {
     /**
      * 通过bouncycastle的CMSSignedData可以实现pkcs#7格式签名数据的验证,利用CMSSignedData生成pkcs#7格式签名数据。由于pkcs#7里面包含了原文和证书信息,所以参数只需要签名值即可
      *
-     * @param SignedData
+     * @param signedData
      * @return
      */
     public boolean SignedData_Verify(byte[] signedData) {

+ 6 - 6
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/sign/itext5/SignHighPdf.java

@@ -45,7 +45,7 @@ public class SignHighPdf {
                               String signText) {
         File signPdfSrcFile = new File(signPdfSrc);
         PdfReader reader = null;
-        ByteArrayOutputStream signPDFData = null;
+        ByteArrayOutputStream signPdfData = null;
         PdfStamper stp = null;
         FileInputStream fos = null;
         try {
@@ -58,10 +58,10 @@ public class SignHighPdf {
             PrivateKey key = (PrivateKey) ks.getKey(alias, password.toCharArray());
             Certificate[] chain = ks.getCertificateChain(alias);
             reader = new PdfReader(signPdfSrc);
-            signPDFData = new ByteArrayOutputStream();
+            signPdfData = new ByteArrayOutputStream();
             // 临时pdf文件
             File temp = new File(signPdfSrcFile.getParent(), System.currentTimeMillis() + ".pdf");
-            stp = PdfStamper.createSignature(reader, signPDFData, '\0', temp, true);
+            stp = PdfStamper.createSignature(reader, signPdfData, '\0', temp, true);
             PdfSignatureAppearance sap = stp.getSignatureAppearance();
             sap.setReason("数字签名,不可改变");
             // 是对应x轴和y轴坐标
@@ -105,13 +105,13 @@ public class SignHighPdf {
             MakeSignature.signDetached(sap, digest, signature, chain, null, null, null, 0, CryptoStandard.CADES);
             stp.close();
             reader.close();
-            return signPDFData.toByteArray();
+            return signPdfData.toByteArray();
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
-            if (signPDFData != null) {
+            if (signPdfData != null) {
                 try {
-                    signPDFData.close();
+                    signPdfData.close();
                 } catch (IOException e) {
                 }
             }

+ 147 - 0
jeecg-boot-module-system/src/main/java/org/jeecg/modules/ctop/sign/pdf/RSACertHelper.java

@@ -0,0 +1,147 @@
+package org.jeecg.modules.ctop.sign.pdf;
+
+import cn.hutool.core.codec.Base64;
+import com.spire.pdf.PdfDocument;
+import com.spire.pdf.graphics.PdfImage;
+import com.spire.pdf.security.GraphicMode;
+import com.spire.pdf.security.PdfCertificate;
+import com.spire.pdf.security.PdfCertificationFlags;
+import com.spire.pdf.security.PdfSignature;
+
+import java.awt.*;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.security.Key;
+import java.security.KeyStore;
+import java.security.PublicKey;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+
+/**
+ * @Author: zhangsong
+ * @Date: 2019/5/28 20:21
+ * @Version 1.0
+ * 首先需要通过jdk的keytool生成秘钥库等,需确保机器中安装有jdk
+ * 0.在本代码环境下,执行1命令时,秘钥库的密码和证书的密码须一致,请自行修改路径
+ * 请确保路径下无名为mykeystore.keystore的文件,否则可能会报密码错等
+ * 1.keytool -genkey -alias mykey -keyalg RSA -keystore D:/mykeystore.keystore -keysize 1024 -validity 3650
+ * 123456 songyh hcst hcst bj bj CH   秘钥口令  123456
+ * 2.keytool -export -alias mykey -keystore C:/mykeystore.keystore -file  C:/mykey.cer
+ * 3.代码中的秘钥库密码为keystore,请自行修改
+ */
+public class RSACertHelper {
+    public static void main(String[] args) {
+        //定义输入、输出文件和数字签名文件
+        String inputFile = "C:\\Users\\宋英豪\\Desktop\\sign\\test.pdf";
+        String outputFile = "C:\\Users\\宋英豪\\Desktop\\sign\\signed.pdf";
+        String pfxPath = "C:\\Users\\宋英豪\\Desktop\\sign\\mykey.pfx";
+        //加载PDF文件
+        PdfDocument doc = new PdfDocument();
+        doc.loadFromFile(inputFile);
+        //加载证书
+        PdfCertificate cert = new PdfCertificate(pfxPath, "123456");
+        PdfSignature signature = new PdfSignature(doc, doc.getPages().get(0), cert, "signature0");
+        Rectangle2D rect = new Rectangle2D.Float();
+        rect.setFrame(new Point2D.Float(90, 550), new Dimension(270, 90));
+        signature.setBounds(rect);
+        //设置图形显示模式,如果不设置图形显示模式,则应用默认的图形显示模式
+        signature.setGraphicMode(GraphicMode.Sign_Image_Only);
+        signature.setNameLabel("Signer:");
+        signature.setName("Gary");
+        signature.setContactInfoLabel("ContactInfo:");
+        signature.setContactInfo("136558284211");
+        signature.setDateLabel("Date:");
+        signature.setDate(new java.util.Date());
+        signature.setLocationInfoLabel("Location:");
+        signature.setLocationInfo("Chengdu");
+        signature.setReasonLabel("Reason: ");
+        signature.setReason("The certificate of this document");
+        signature.setDistinguishedNameLabel("DN: ");
+        signature.setDistinguishedName(signature.getCertificate().get_IssuerName().getName());
+        signature.setSignImageSource(PdfImage.fromFile("C:\\Users\\宋英豪\\Desktop\\sign\\sign.jpg"));
+        signature.setDocumentPermissions(PdfCertificationFlags.Forbid_Changes);
+        signature.setCertificated(true);
+        //保存文件
+        doc.saveToFile(outputFile);
+        doc.close();
+    }
+
+    public static void getPfxFile() {
+        String path = "D:/";
+        String keyStoreFile = "mykeystore.keystore";
+        String passwd = "123456";
+        String keyAlias = "mykey";
+        String pfxFile = "mykey.pfx";
+        String cerFile = "mykey.cer";
+
+        System.out.println("请确保已执行完注释中的两条命令再执行本代码\n\n");
+        System.out.println("1.开始生成PFX文件");
+        coverToPfx(path + keyStoreFile, passwd, keyAlias, path + pfxFile);
+        System.out.println("===============================================================");
+        System.out.println("2.开始提取.cer中的公钥字符串");
+        String cerStr = getPubStr(path + cerFile);
+        System.out.println("从.cer文件中提取的公钥字符串如下:");
+        System.out.println(cerStr);
+    }
+
+    //1生成pfx文件
+    public static void coverToPfx(String keyStoreFile, String passwd, String keyAlias, String pfxFile) {
+        try {
+            KeyStore inputKeyStore = KeyStore.getInstance("JKS");
+            FileInputStream fis = new FileInputStream(keyStoreFile);
+            char[] nPassword = null;
+            if ((passwd == null)
+                    || passwd.trim().equals("")) {
+                nPassword = null;
+            } else {
+                nPassword = passwd.toCharArray();
+            }
+            inputKeyStore.load(fis, nPassword);
+            fis.close();
+            KeyStore outputKeyStore = KeyStore.getInstance("PKCS12");
+            outputKeyStore.load(null, passwd.toCharArray());
+
+//            System.out.println("alias=[" + keyAlias + "]");
+            if (inputKeyStore.isKeyEntry(keyAlias)) {
+                Key key = inputKeyStore.getKey(keyAlias, passwd.toCharArray());
+                Certificate[] certChain = inputKeyStore
+                        .getCertificateChain(keyAlias);
+                outputKeyStore.setKeyEntry(keyAlias, key, passwd
+                        .toCharArray(), certChain);
+            }
+
+            FileOutputStream out = new FileOutputStream(pfxFile);
+            outputKeyStore.store(out, nPassword);
+            out.close();
+            System.out.println("已生成PFX文件" + pfxFile);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    //2获取公钥字符串
+    public static String getPubStr(String cerFile) {
+        String key = "";
+        // 读取证书文件
+        try {
+            CertificateFactory cf = CertificateFactory.getInstance("X.509");
+            FileInputStream in = new FileInputStream(cerFile);
+
+            //生成一个证书对象并使用从输入流 inStream 中读取的数据对它进行初始化。
+            Certificate c = cf.generateCertificate(in);
+            PublicKey publicKey = c.getPublicKey();
+            key = Base64.encode(publicKey.getEncoded());
+        } catch (CertificateException e) {
+            e.printStackTrace();
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        return key;
+    }
+
+
+}

+ 3 - 4
jeecg-boot-module-system/src/main/java/org/jeecg/modules/kuaishou/service/impl/KuaiShouCreateServiceImpl.java

@@ -140,7 +140,6 @@ public class KuaiShouCreateServiceImpl implements IKuaiShouCreateService {
                 if ("1".equals(platform) && appTemplate.getUploadType() == 1) {
                     apkJson.put("file", appTemplate.getFile());
                     apkMap = kuaishouInterfaceService.appCreate(accountId, accessToken, apkJson);
-
                 } else {
                     apkJson.put("url", appTemplate.getUrl());
                     apkMap = kuaishouInterfaceService.urlAppCreate(accountId, accessToken, apkJson);
@@ -451,9 +450,9 @@ public class KuaiShouCreateServiceImpl implements IKuaiShouCreateService {
                             return imageMap;
                         }
                         createJson.put("creative_name", creativeName + "_" + i);
-                        JSONArray image_tokens = new JSONArray();
-                        image_tokens.add(imageMap.get("imageToken"));
-                        createJson.put("image_tokens", image_tokens);
+                        JSONArray imageTokens = new JSONArray();
+                        imageTokens.add(imageMap.get("imageToken"));
+                        createJson.put("image_tokens", imageTokens);
                         Map<String, Object> creativeMap = kuaishouInterfaceService.creativeCreate(accessToken, accountId, createJson);
                         if ((Integer) creativeMap.get("code") != 0) {
                             logger.error("后贴片素材单张图片批量创建创意失败,accountId:{}", accountId);