zoukankan      html  css  js  c++  java
  • 非对称和对称加密结合

    package test;
    
    import com.fasterxml.jackson.annotation.JsonInclude;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.DeserializationFeature;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import org.apache.commons.codec.binary.Base64;
    
    import javax.crypto.*;
    import javax.crypto.spec.SecretKeySpec;
    import java.security.*;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    
    public class ParseUtil {
        /**
         * AES算法名称
         */
        private final static String AES = "AES";
        /**
         * 算法
         */
        public final static String ALGORITHM = "RSA";
        /**
         * 哈希算法
         */
        public final static String HASH = "SHA";
        //
        /**
         * 签名哈希算法
         */
        public final static String SHA1WITHRSA = "SHA1withRSA";
    
    
        public static void main(String[] args) {
    
    //        用户系统持有的秘钥
            String userPrivate = "MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJkxG9Xo1O/bnqZWTt4HgjNxlDgnNjFXm9ZJbxTOpoao6pCGcZzT1hHHUJSoMrYlQR3/qkjUwEr72G71aBdTa7KXATVs0ca2IfOA9HxNV13XlpikwDGzL0fERlRAj3eCPM6ykouOpLSoXZBtIS2dw0tlHn14ufWcmHVOyuhkPgIfAgMBAAECgYEAjFyCtKxw7pS7+Ix8FtOqaJhYxlqnPO6Yyu7d6KKv0hJTWbjVwGwYaJHHM24piNr5nxLyY2kMB6hZ1tDkXvsAYWZk3R4sf9t0+Qrwh3xwM2OhWpUlyeTCA16fxCloSVLrhiwvLZmjinVKybYTNUIvg7bFoVDK+YCOjoLvA+38agECQQDTt/pGhOudiHEVt+0QMGf1HvMLZWFjtxPQulVgmHXL95hh1y6Qyj39Q58xOQupig6rUcqOJE/4hLS8YXyQzX/PAkEAuTtv7s2DIwP4J0GqQ4gG69xEb/LLWqx8qajn2SinSH8V4bpd1z2O6gnqrpWdqvGFab86BGJxrq8TPRbJfnIcsQJBALcdmdbiYhMXjo91TBHDfDaS9S13GvuuvfG7J9rrIn8uf9qnzXunoGPr18UwDLkvUi61CFdWauCMjvGb86weQRsCQArbKe9ECjiGJgge+BynH0i5iyVIhJSW4WOMK7J1iIBeOmkVZCSWTgb3d9KtoCUBrMEK3Rqermz/g9AjwsFvbLECQEVekV8lUacnXehwU+wvNw+rD53E6cW7ntS142g4oH0TulASSi8w1IMTBrgE3OfPsoKQM67Tm8wzTiSubnMFCog=";
            String systemPubic = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnuJEgORIe4jROGM7MlKYqBT+nCid95oUoQYHyv0wXkxJehBCveqgxlC0Ql1MsKT96wz8aY2mduwCtyRyhYB+pyj6kLj/hkSk83p5jA5ylw/ATJ7C1v0tCW64qZ/u3K+Nw/yqDNTpeP8/9DoIsD4rOnkHbTckisbtijIo88sAyMQIDAQAB";
    
    //        系统持有的秘钥
            String systemPrivate = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAKe4kSA5Eh7iNE4YzsyUpioFP6cKJ33mhShBgfK/TBeTEl6EEK96qDGULRCXUywpP3rDPxpjaZ27AK3JHKFgH6nKPqQuP+GRKTzenmMDnKXD8BMnsLW/S0Jbripn+7cr43D/KoM1Ol4/z/0OgiwPis6eQdtNySKxu2KMijzywDIxAgMBAAECgYAEBo0NLfF+ZkWFHllQVb0LQyb89mRuRCssBS5+ShMkebY2KItR+uqwjfLq9AbeB3trkeYg1wQA8i0Y/ru+L9VyrqqEntqoWtoJtFc968/qu+Qt28gn/t85nEnchlvc1J7oSpdpNRfLxSjAqQ0xz7/dXcBDH9V3RHik+CTqSB06xQJBAP9+c+oCXEjUJzoR+WcDirA7kFnlk0Y3p+QslRvTEpLq9w1f26PQj/2Jqdu1/kUyzoA4B5esIcqWUUeCXmSv0JsCQQCoDZvxrsIRGPDM6xaaLugBfd5vuUTOztiNZm9XfOosn8s8imcJ2FUu0qRHKhsVbCmEd2AlVfLBE5T3QbzcllcjAkEAipYwEAY5wrN5l7E6RJuSNigJFApIibUU19srAo3KrHDRk6qkfEZcZJ2wymH8y9JUWw6JZ8dSCQ7ihdR8mUcY8wJAHOOKBTfngIzrCC75ibO6ilca39XXcD26mEQdq8p7bwRhKZ0ZLWYU7qGjP+CLG1mmoXDsBD8MJgi5uO+CCeGGRQJAA8kbFl1eSFnI367JPLZBd8GEvLmmw7N1NeVz7iJ30bYJ/5OOFWRxKkeTastTWJlkIvEK/srwJKQyk4tNZ67tcg==";
            String userPublic = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCZMRvV6NTv256mVk7eB4IzcZQ4JzYxV5vWSW8UzqaGqOqQhnGc09YRx1CUqDK2JUEd/6pI1MBK+9hu9WgXU2uylwE1bNHGtiHzgPR8TVdd15aYpMAxsy9HxEZUQI93gjzOspKLjqS0qF2QbSEtncNLZR59eLn1nJh1TsroZD4CHwIDAQAB";
            //加密userId
            String userId = "3";
            byte[] bytes = RSAUtils.sign(Base64.decodeBase64(userPrivate), RSAUtils.mdigestSHA(userId.getBytes()));
            String cryptUserId = Base64.encodeBase64String(bytes);//加密后的userId
    
            //用户系统加密数据示例
            String cyptContent = encryptSample(userPrivate, systemPubic, "用户加密测试数据",Long.valueOf(userId));
    
            //用户系统解密数据示例
            String data =encryptSample(systemPrivate, userPublic, "用户解密测试数据",Long.valueOf(userId));//系统加密数据
            String plainContent = decryptSample(systemPubic, userPrivate, data);//用户系统解密
    
            System.out.println("加密内容:" + cyptContent);
            System.out.println("解密内容:" + plainContent);
        }
    
    
        /**
         * 生成密钥
         *
         * @return
         */
        public static byte[] initkey() {
            SecretKey secretKey = null;
            try {
                KeyGenerator keyGen = KeyGenerator.getInstance(AES);
                keyGen.init(128);
                secretKey = keyGen.generateKey();
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            }
            return secretKey.getEncoded();
        }
    
        /**
         * AES加密
         *
         * @param data
         * @param key
         * @return
         */
        public static byte[] encrypt(byte[] data, byte[] key) {
            byte[] cipherBytes = null;
            try {
                SecretKey secretKey = new SecretKeySpec(key, AES);
                Cipher cipher = Cipher.getInstance(AES);
                cipher.init(Cipher.ENCRYPT_MODE, secretKey);
                cipherBytes = cipher.doFinal(data);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            }
            return cipherBytes;
        }
    
        /**
         * AES解密
         *
         * @param data
         * @param key
         * @return
         */
        public static byte[] decrypt(byte[] data, byte[] key) {
            byte[] plainBytes = null;
            try {
                SecretKey secretKey = new SecretKeySpec(key, AES);
                Cipher cipher = Cipher.getInstance(AES);
                cipher.init(Cipher.DECRYPT_MODE, secretKey);
                plainBytes = cipher.doFinal(data);
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            }
            return plainBytes;
        }
    
        /**
         * 使用RSA公钥加密数据
         *
         * @param pubKeyInByte 打包的byte[]形式公钥
         * @param data         要加密的数据
         * @return 加密数据
         */
        public static byte[] encryptByRSA(byte[] pubKeyInByte, byte[] data) {
            try {
                KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
                X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(pubKeyInByte);
                PublicKey publicKey = keyFactory.generatePublic(pubSpec);
                Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                cipher.init(Cipher.ENCRYPT_MODE, publicKey);
                return cipher.doFinal(data);
            } catch (Exception e) {
                return null;
            }
        }
    
        /**
         * 用RSA私钥解密
         *
         * @param privateKeyInByte 私钥打包成byte[]形式
         * @param data             要解密的数据
         * @return 解密数据
         */
        public static byte[] decryptByRSAPrivateKey(byte[] privateKeyInByte, byte[] data) {
            try {
                PKCS8EncodedKeySpec privSpec = new PKCS8EncodedKeySpec(
                        privateKeyInByte);
                KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
                PrivateKey privateKey = keyFactory.generatePrivate(privSpec);
                Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
                cipher.init(Cipher.DECRYPT_MODE, privateKey);
                return cipher.doFinal(data);
            } catch (Exception e) {
                return null;
            }
        }
    
        /**
         * 生成数字摘要
         * @param source
         * @return
         */
        public static byte[] mdigestSHA(byte[] source) {
            try {
                MessageDigest thisMD = MessageDigest.getInstance(HASH);
                byte[] digest = thisMD.digest(source);
                return digest;
            } catch (Exception e) {
                return null;
            }
        }
    
        /**
         * 使用私钥加密数据(发送数据采用私钥签名)
         * 用一个已打包成byte[]形式的私钥加密数据,即数字签名
         *
         * @param privateKeyInByte 打包成byte[]的私钥
         * @param source           要签名的数据,一般应是数字摘要
         * @return 签名 byte[]
         */
        public static byte[] sign(byte[] privateKeyInByte, byte[] source) {
            try {
                PKCS8EncodedKeySpec privateSpec = new PKCS8EncodedKeySpec(privateKeyInByte);
                KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
                PrivateKey privateKey = keyFactory.generatePrivate(privateSpec);
                Signature signature = Signature.getInstance(SHA1WITHRSA);
                signature.initSign(privateKey);
                signature.update(source);
                return signature.sign();
            } catch (Exception e) {
                return null;
            }
        }
    
        /**
         * 验证签名(接收数据使用发送方公钥验证签名)
         *
         * @param publicKeyInByte 二进制公钥
         * @param source           源数据
         * @param sign             数字签名
         * @return 验证结果
         */
        public static boolean verify(byte[] publicKeyInByte, byte[] source, byte[] sign) {
            try {
                KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
                Signature signature = Signature.getInstance(SHA1WITHRSA);
                X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(publicKeyInByte);
                PublicKey publicKey = keyFactory.generatePublic(pubSpec);
                signature.initVerify(publicKey);
                signature.update(source);
                return signature.verify(sign);
            } catch (Exception e) {
                return false;
            }
        }
    
    
        /**
         * 加密示例
         * @param userPrivateKey
         * @param sysPublicKey
         * @param content
         * @return
         */
        public static String encryptSample(String userPrivateKey, String sysPublicKey, String content,Long userId) {
            SendData data = new SendData();
            //生成AES密钥
            byte[] AESKeyBytes = ParseUtil.initkey();
    
            //RSA公钥加密AES密钥
            byte[] cipherKeyBytes = ParseUtil.encryptByRSA(Base64.decodeBase64(sysPublicKey), AESKeyBytes);
            //加密文本
            byte[] cipherTextBytes = ParseUtil.encrypt(content.getBytes(), AESKeyBytes);
            //签名(通过加密文本获取数字摘要,然后对摘要通过用户私钥进行签名)
            byte[] signBytes = ParseUtil.sign(Base64.decodeBase64(userPrivateKey), ParseUtil.mdigestSHA(cipherTextBytes));
    
            data.setAESKeyString(Base64.encodeBase64String(cipherKeyBytes));
            data.setCyptContent(Base64.encodeBase64String(cipherTextBytes));
            data.setSign(Base64.encodeBase64String(signBytes));
            data.setUserId(userId);
            return JsonUtil.toJson(data);
        }
    
        /**
         * 解密示例
         * @param userPublicKey
         * @param sysPrivateKey
         * @param cyptContent
         * @return
         */
        public static String decryptSample(String userPublicKey, String sysPrivateKey, String cyptContent) {
            ReceiveData data = JsonUtil.fromJson(cyptContent, ReceiveData.class);
    
            //从base64中获取字节数组
            //RSA公钥加密AES密钥
            byte[] cipherKeyBytes = Base64.decodeBase64(data.getAESKeyString());
            //加密文本
            byte[] cipherTextBytes = Base64.decodeBase64(data.getCyptContent());
            //签名(通过加密文本获取数字摘要,然后对摘
            byte[] signBytes = Base64.decodeBase64(data.getSign());
    
            //验证签名
            boolean isValid = ParseUtil.verify(Base64.decodeBase64(userPublicKey),
                    ParseUtil.mdigestSHA(cipherTextBytes),
                    signBytes);
    
            if (isValid) {
                //RSA私钥解密AES密钥
                byte[] AESKeyBytes = decryptByRSAPrivateKey(Base64.decodeBase64(sysPrivateKey), cipherKeyBytes);
                if (AESKeyBytes != null) {
                    byte[] plainText = decrypt(cipherTextBytes, AESKeyBytes);
                    return new String(plainText);
                }
            }
            return null;
        }
    
        /**
         * json转换工具
         */
        public static class JsonUtil {
    
            private static final ObjectMapper JSON_MAPPER;
    
            static {
                JSON_MAPPER = new ObjectMapper();
                JSON_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
                JSON_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            }
    
            public static String toJson(Object obj) {
                try {
                    return JSON_MAPPER.writeValueAsString(obj);
                } catch (JsonProcessingException e) {
                    e.printStackTrace();
                }
                return null;
            }
    
            public static <T> T fromJson(String json, Class<T> cla) {
                try {
                    return JSON_MAPPER.readValue(json, cla);
                } catch (Exception e) {
                    e.printStackTrace();
                    //LOG.error("error on fromJson", e);
                }
                return null;
            }
        }
    
        /**
         * 企业方接收数据格式
         */
        public static class ReceiveData {
            private final String status = "success";
            private String sign;
            private String cyptContent;
            private String AESKeyString;
    
            public String getStatus() {
                return status;
            }
    
            public String getSign() {
                return sign;
            }
    
            public void setSign(String sign) {
                this.sign = sign;
            }
    
            public String getCyptContent() {
                return cyptContent;
            }
    
            public void setCyptContent(String cyptContent) {
                this.cyptContent = cyptContent;
            }
    
            public String getAESKeyString() {
                return AESKeyString;
            }
    
            public void setAESKeyString(String AESKeyString) {
                this.AESKeyString = AESKeyString;
            }
        }
    
        /**
         * 企业方发送数据格式
         */
        public static class SendData {
    
            private Long userId;
            private String sign;
            private String cyptContent;
            private String AESKeyString;
    
            public Long getUserId() {
                return userId;
            }
    
            public void setUserId(Long userId) {
                this.userId = userId;
            }
    
            public String getSign() {
                return sign;
            }
    
            public void setSign(String sign) {
                this.sign = sign;
            }
    
            public String getCyptContent() {
                return cyptContent;
            }
    
            public void setCyptContent(String cyptContent) {
                this.cyptContent = cyptContent;
            }
    
            public String getAESKeyString() {
                return AESKeyString;
            }
    
            public void setAESKeyString(String AESKeyString) {
                this.AESKeyString = AESKeyString;
            }
        }
    
    }
  • 相关阅读:
    【测试平台学习1】 vue使用与启动
    【Devops】 发布一个Python项目(Flask服务后端)到K8S环境
    Spring5源码分析(024)——IoC篇之bean加载:parentBeanFactory和依赖处理
    Spring5源码分析(023)——IoC篇之bean加载:从缓存中获取单例 bean
    Java基础(018):Class.forName和ClassLoader的区别
    Spring5源码分析(022)——IoC篇之bean加载:FactoryBean的用法
    Spring5源码分析(021)——IoC篇之bean加载
    Java基础(017):反射初探
    Java基础(015):泛型
    Java基础(001):关于 short i = 1; i += 1;
  • 原文地址:https://www.cnblogs.com/guozhigang/p/10775730.html
Copyright © 2011-2022 走看看