• JAVA 解密pkcs7(smime.p7m)加密内容 ,公钥:.crt 私钥:.pem 使用Bouncy Castle生成数字签名、数字信封


    第三方使用公钥.crt加密后返回的内容,需要使用私钥解密.pem

    返回内容格式如下

    MIME-Version: 1.0
    Content-Disposition: attachment; filename="smime.p7m"
    Content-Type: application/pkcs7-mime; smime-type=enveloped-data; name="smime.p7m"
    Content-Transfer-Encoding: base64
    
    MIICEQYJKoZIhvcNAQcDoIICAjCCAf4CAQAxggFAMIIBPAIBADAkMBYxFDASBgNV
    BAMTC1NpbmFwdElRIENBAgoeg+bBAAAAAAAMMA0GCSqGSIb3DQEBAQUABIIBACGx
    OPGANR0bAlwPxlYt6DBTEPinPc2eiduiYLXEOftEmDA3vLNyeQ+Q1sxfYj1U5K2o
    26qKr937yNwrtZ1VTird4NXHiR60Gtm0VJ+sd88XylHe2VxJrrNWHFPwoT+q7nfy
    IT6cfMgfOMzA1YO3/efWKEFJgmiUoeo+PZgrcRr4PIMYIFnnxQNKz+iwutfd+O44
    H5wIviHsqGjiSqoVzEg5/pWh07aZ9hr/2CNGbDwBH4f+hucJTzt98tvMhrjFvbDy
    uiegAgxN/nolzRQv7lUlLvUrNJSOiFM5/1BWUfoiTLRgoseHjt9RxPKb8WRpul7f
    Om0hWxXl0mWus9GLBCIwgbQGCSqGSIb3DQEHATAUBggqhkiG9w0DBwQIBcIBRSKJ
    WEuAgZCcvoeat07ncIZI6owiP7WMSC9RXfuRQ//FKuBx+cpJdHnGkYuPTA3gJJca
    kTis/5rpDiE7bmiCiDlMBdoM1h+A0jSpR78nOCsJuJI08clAJQmj82ACbPmwRUwg
    OCrkTLUqbJ7brsYJeMYZWyBZIAL3bKtgqi2VRqOPerzaxOcjqv873wed/2kRUrhV
    gMw9bSc=

    解密开始,你需要提取内容部分,并去掉换行,让内容部分保持在一行

    比如:MIICEQYJKoZIhvcNAQcDoIICAjCCAf4CAQAxggFAMIIBPAIBADAkMBYxFDASBgNVBAMTC......

    maven pom.xml需要引用

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcpkix-jdk15on</artifactId>
        <version>1.60</version>
    </dependency>

    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.60</version>
    </dependency>

    JAVA解密加密工具类

    package com.perfect.all.core.util.pay.toc2p;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.security.KeyPair;
    import java.security.NoSuchProviderException;
    import java.security.PrivateKey;
    import java.security.Security;
    import java.security.cert.CertificateEncodingException;
    import java.security.cert.CertificateException;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    import java.security.interfaces.RSAPublicKey;
    import java.util.Base64;
    import java.util.Collection;
    import java.util.Iterator;
    
    import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
    import org.bouncycastle.cms.CMSEnvelopedData;
    import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
    import org.bouncycastle.cms.CMSEnvelopedDataParser;
    import org.bouncycastle.cms.CMSException;
    import org.bouncycastle.cms.CMSProcessableByteArray;
    import org.bouncycastle.cms.CMSTypedData;
    import org.bouncycastle.cms.RecipientInformation;
    import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
    import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
    import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.bouncycastle.openssl.PEMDecryptorProvider;
    import org.bouncycastle.openssl.PEMEncryptedKeyPair;
    import org.bouncycastle.openssl.PEMKeyPair;
    import org.bouncycastle.openssl.PEMParser;
    import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
    import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
    
    public class Pcks7EncryptOrDecryptUtil {
    
        private static final String PRIVATE_KEY_PATH = "/xxxx.pem";
        private static final String PRIVATE_KEY_PASSWORD="xxxx";
        public static final String PUBLIC_KEY_PATH="/xxx.crt";
        
        private static PrivateKey PRIVATE_KEY = null;
        private static RSAPublicKey PUBLIC_KEY = null;
        private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6',
                '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
        
        static {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        }
        
        public static void main(String[] args) throws Exception {
            String sendConent="<PaymentProcessRequest><version>3.0</version><timeStamp>161018173004</timeStamp><merchantID>764764000001350</merchantID><processType>R</processType><invoiceNo>THBPOps180808153209</invoiceNo><actionAmount>0.01</actionAmount><hashValue>E8CCDCDBDBB7428CF0CC9F06AB30B595067F4C89</hashValue></PaymentProcessRequest>";
            String rsaPubEncrypt = encryptByRsaPub(PUBLIC_KEY_PATH,sendConent,"utf-8");//加密数据
            System.out.println(rsaPubEncrypt);    
            System.out.println(decryptByContent(rsaPubEncrypt, PRIVATE_KEY_PATH, PRIVATE_KEY_PASSWORD)); //解密数据
            
            //第三方返回的数据
            String encryptContent = "MIICcgYJKoZIhvcNAQcDoIICYzCCAl8CAQA......";
            System.out.println(decryptByContent(encryptContent, PRIVATE_KEY_PATH, PRIVATE_KEY_PASSWORD));
    
        }
    
        /**
         * 使用私钥加密
         */
        public static String encryptByRsaPub(String content) {
            return  encryptByRsaPub( PUBLIC_KEY_PATH,content,"utf-8");
        }
    
        /**
         * 使用私钥加密
         */
        public static String encryptByRsaPub(String publicKeyPath , String content,String charSet) {
     
            try {
                X509Certificate cert = getX509Certificate(publicKeyPath);
                //添加数字信封
                CMSTypedData msg = new CMSProcessableByteArray(content.getBytes(charSet));
     
                CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
     
                edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(
                        cert).setProvider("BC"));
     
                CMSEnvelopedData ed = edGen.generate(msg,
                        new JceCMSContentEncryptorBuilder(PKCSObjectIdentifiers.rc4)
                                .setProvider("BC").build());
     
                String rslt = new String(Base64.getEncoder().encode(ed.getEncoded()));
     
                System.out.println(rslt);
                return rslt;
            } catch (CertificateEncodingException | CMSException | IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
    
        /**
         * 使用公钥解密
         * @param encryptContent  比如:MIICEQYJKoZIhvcNAQcDoIICAjCCAf4CAQAxggFAMIIBPAIBADAkMBYxFDASBgNVBAMTC......
         * @param privatePemKeyPath  xxxx.pem
         * @param privatePemKeyPassword
         * @return
         */
        public static String decryptByContent(String encryptContent,String privatePemKeyPath,String privatePemKeyPassword) {
            return decryptByContent(encryptContent,getPrivateKey(privatePemKeyPath, privatePemKeyPassword));
        }
    
        public static String decryptByContent(String encryptContent,PrivateKey privateKey) {
            return decryptByContent(Base64.getDecoder().decode(encryptContent),privateKey);
        }
        public static String decryptByContent(String encryptContent) {
            return decryptByContent(Base64.getDecoder().decode(encryptContent),getPrivateKey(PRIVATE_KEY_PATH, PRIVATE_KEY_PASSWORD));
        }
    
        public static String decryptByContent(byte[] encryptContent,PrivateKey privateKey) {
            try {
                CMSEnvelopedDataParser cmsEnvelopedDataParser = new CMSEnvelopedDataParser(encryptContent); 
                Collection<RecipientInformation> recInfos = cmsEnvelopedDataParser.getRecipientInfos().getRecipients(); 
                Iterator<RecipientInformation> recipientIterator = recInfos.iterator(); 
                if (recipientIterator.hasNext()) { 
                    RecipientInformation recipientInformation = (RecipientInformation) recipientIterator.next(); 
                    JceKeyTransEnvelopedRecipient jceKeyTransEnvelopedRecipient = new JceKeyTransEnvelopedRecipient(privateKey);
                    byte[] contentBytes = recipientInformation.getContent(jceKeyTransEnvelopedRecipient); 
                    String decryptContent = new String(contentBytes); 
                    return decryptContent;
                }
            } catch (CMSException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } 
            System.out.println("decrypt error");
            return null;
        }
    
    
        public static PrivateKey getPrivateKey(String pemFilePath, String password){
            if(PRIVATE_KEY != null) {
                return PRIVATE_KEY;
            }
            Security.addProvider(new BouncyCastleProvider());
            KeyPair kp;
            try{
                kp = (KeyPair)initKeyPair(new File(pemFilePath), password.toCharArray());
                PrivateKey privateKey = kp.getPrivate();
                return (PRIVATE_KEY = privateKey);
            }catch(Exception e){
                e.printStackTrace();
    
            }
    
            return null;
        }
    
    
        public static KeyPair initKeyPair(File pemFile, char[] password) throws Exception{
            PEMParser pemParser = new PEMParser(new FileReader(pemFile));
            Object object = pemParser.readObject();
            pemParser.close();
            PEMDecryptorProvider decProv = new JcePEMDecryptorProviderBuilder().build(password);
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
            //获得密钥对
            KeyPair kp = null;
            if(object instanceof PEMEncryptedKeyPair){
                kp = converter.getKeyPair(((PEMEncryptedKeyPair)object).decryptKeyPair(decProv));
            }else{
                kp = converter.getKeyPair((PEMKeyPair)object);
            }
            return kp;
        }
        
        public static RSAPublicKey getRSAPublicKey(String crtFileName) {
            if(PUBLIC_KEY != null) {
                return PUBLIC_KEY;
            }
            return (PUBLIC_KEY = (RSAPublicKey) getX509Certificate(crtFileName).getPublicKey());
        }
    
        /**
         * 获取公钥
         */
        public static X509Certificate getX509Certificate(String crtFileName) {
            try {
                CertificateFactory certificatefactory;
                X509Certificate cert;
                // 使用公钥对对称密钥进行加密 //若此处不加参数 "BC" 会报异常:CertificateException -
                certificatefactory = CertificateFactory.getInstance("X.509", "BC");
                // 读取.crt文件;你可以读取绝对路径文件下的crt,返回一个InputStream(或其子类)即可。
                InputStream bais = new FileInputStream(crtFileName);
         
                cert = (X509Certificate) certificatefactory.generateCertificate(bais);
                return cert;
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (CertificateException e) {
                e.printStackTrace();
            } catch (NoSuchProviderException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return null;
        }
    
        public static String byteArrayToString(byte[] data) {
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < data.length; i++) {
                // 取出字节的高四位 作为索引得到相应的十六进制标识符 注意无符号右移
                stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);
                // 取出字节的低四位 作为索引得到相应的十六进制标识符
                stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);
                if (i < data.length - 1) {
                    stringBuilder.append(' ');
                }
            }
            return stringBuilder.toString();
        }
        
        public static byte[] hexStringToBytes(String hexString) {
            if (hexString == null || hexString.equals("")) {
                return null;
            }
            hexString = hexString.toUpperCase();
            int length = hexString.length() / 2;
            char[] hexChars = hexString.toCharArray();
            byte[] d = new byte[length];
            for (int i = 0; i < length; i++) {
                int pos = i * 2;
                d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
            }
            return d;
        }
    
        /** * Convert char to byte * @param c char * @return byte */
        private static byte charToByte(char c) {
            return (byte) "0123456789ABCDEF".indexOf(c);
        }
        
    }    
  • 相关阅读:
    k8s-存储-volume
    k8s-存储-configmap
    k8s-集群调度
    k8s-常用命令
    k8s-资源限制
    k8s-更改证书时间
    kubeadmin安装k8s
    CCPC-Wannafly Winter Camp Day7 D---二次函数【数论】【构造】
    洛谷P1219 八皇后【dfs】
    2019寒假计数器
  • 原文地址:https://www.cnblogs.com/binz/p/9835143.html
Copyright © 2020-2023  润新知