美文网首页Java 核心技术
JAVA使用RSA加密算法加密解析数据

JAVA使用RSA加密算法加密解析数据

作者: rs汀 | 来源:发表于2020-03-12 11:24 被阅读0次

    1.JAVA使用RSA加密算法解析数据

    话不多说,直接开干

        /**
         * 
         * @param test
         * @param request
         * @return
         */
        @RequestMapping(value = "/test", method = RequestMethod.POST)
        public ResultVO<?> test(@RequestBody SecretBO secretBO, HttpServletRequest request) {
            TestBO testBO = this.secretService.decryptpParameter(secretBO, TestBO.class);
            String userId = request.getHeader("userId");
            return this.testService.test(testBO, userId);
        }
    

    这是一个普通的接口,接下来我们分析一下解析里面的数据

        /**
         * 与前端商定结构
         * 
         */
    @Data
    public class SecretBO {
    
        private String ciphertext;// 加密后的参数
        
        private String key;// 公钥
        
        private String time;//超时时间
    }
    

    TestBO就是封装好的BO类。下面来看具体处理:

    import org.apache.commons.codec.binary.Base64;
    import org.test.bean.bo.secret.SecretBO;
    import org.test.contants.Codes;
    import org.test.contants.Messages;
    import org.test.exception.BusinessException;
    import org.test.util.DESCoder;
    import org.test.util.RSACoder;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    
    import com.alibaba.fastjson.JSONObject;
    
    @Service
    public class SecretService {
    
        private final static Logger logger = LoggerFactory.getLogger(SecretService.class);
    
    //  rsa:
     // publicKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDn/QnUfkKkQpG++6YDUYo8qc0mrcRbRsmokp3EJZJrwIblldv6W2+yAIWkkel4GzsL+oklZReqZcG4F+ug3otc6IZa3fFMXuaDzoDzicdOABe2s8igLjMcfhujI9MqYvkVVSyFWdVOLNAnzQJgkisnHKZGPQZcxnQAHxTOUco+LwIDAQAB
    //  privateKey: MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAOf9CdR+QqRCkb77pgNRijypzSatxFtGyaiSncQlkmvAhuWV2/pbb7IAhaSR6XgbOwv6iSVlF6plwbgX66Dei1zohlrd8Uxe5oPOgPOJx04AF7azyKAuMxx+G6Mj0ypi+RVVLIVZ1U4s0CfNAmCSKyccpkY9BlzGdAAfFM5Ryj4vAgMBAAECgYBPBc63Z1rkARkMaUQflUL1bxHGvyJHxVEj7u12xyWdNrO8uNN58HOXur3LVTimBQCUD/9vkYQCMy9Nujg1UBlAIokG9zdhNkK/5x2y1yVOAL+SDQolnumZyTYncWTnNOZtgCdCnqBmuHpw6LfF5nHm7/iCeThdUY2MJ+u9y9wAIQJBAPuCuokJ/lZY0GI5hzxkeK9TlNYn6+rJpkAehkNz4Aaa6tjXaGcrKsLgHrYXupYKLNXABhELY70nJaahltUgF3UCQQDsIRp6/poRIbLCZ4JyoXp4Mjvd8lJ03mBUdzYEsn3aH9jafqOxLHB3FseYz/fKl3Gb5xgbhsFUCQm+3I9slu6TAkBEaSCX2dIGZo33ybIRKTryZYecYKt453SDCEp42nHbGhQ6+wx403MEIrX3zaiA2y+qzFpaFIECmD1Tf6xpOBtpAkEAwi/XHx8ShNQ5tjZ5yNuTZBWrtjL6LLJUdiIzgllntmJKbCWJaMMrGkTZkIo3NZymCZha8wg3JWzpXtTz/lGBkQJAb3kjcBZHRg53s6/CLi5eVEGVW0RjXWo47SpwYUuu1b5miG9oXlmZxyG9nS8ZFWcBKh0IZMlhcGCqvq2qNoC6qw==
    
        @Value(value = "${rsa.privateKey}")
        private String privateKey; // 
        
        @Value(value = "${time.interval}")
        private String interval; // 600000 一个小时
    
        @SuppressWarnings("unchecked")
        public <T> T decryptpParameter(SecretBO secretBO, Class<T> clazz) {
            try {
                // 解密des秘钥
                String secretKey = new String(RSACoder.decryptByPrivateKey(Base64.decodeBase64(secretBO.getKey()),
                        Base64.decodeBase64(privateKey)));
                // 解密时间戳
                Long time = Long
                        .parseLong(DESCoder.decrypt(Base64.decodeBase64(secretBO.getTime()), secretKey));
                // 判断与当前时间的间隙
                if (System.currentTimeMillis() - time > Long.parseLong(interval)) {
                    logger.error(Messages.TIME_INTERVAL_IS_TOO_LONG);
                    throw new BusinessException(Codes.CODE_500, Messages.DECRYPTP_PARAMETER_ERROR);
                }
                // 解密数据
                String cleartext = DESCoder.decrypt(Base64.decodeBase64(secretBO.getCiphertext()), secretKey);
                T value;
                try {
                    value = JSONObject.parseObject(cleartext, clazz);
                } catch (Exception e) {
                    value = (T) cleartext;
                }
                return value;
            } catch (Exception e) {
                logger.error(Messages.DECRYPTP_PARAMETER_ERROR, e);
                throw new BusinessException(Codes.CODE_500, Messages.DECRYPTP_PARAMETER_ERROR); // 自定义的异常结构
            }
        }
    
    }
    
    

    提供一下处理方法

    import org.apache.commons.codec.binary.Base64;
    
    import javax.crypto.Cipher;
    
    import java.io.ByteArrayOutputStream;
    import java.security.*;
    import java.security.interfaces.RSAPrivateKey;
    import java.security.interfaces.RSAPublicKey;
    import java.security.spec.PKCS8EncodedKeySpec;
    import java.security.spec.X509EncodedKeySpec;
    import java.util.HashMap;
    import java.util.Map;
    
    public class RSACoder {
    
        // 非对称密钥算法
        public static final String KEY_ALGORITHM = "RSA";
    
        /**
         * 密钥长度,DH算法的默认密钥长度是1024 密钥长度必须是64的倍数,在512到65536位之间
         */
        private static final int KEY_SIZE = 1024;
    
        // 公钥
        private static final String PUBLIC_KEY = "RSAPublicKey";
    
        // 私钥
        private static final String PRIVATE_KEY = "RSAPrivateKey";
    
        private static final int MAX_ENCRYPT_BLOCK = 117;
    
        private static final int MAX_DECRYPT_BLOCK = 128;
    
        /**
         * 初始化密钥对
         *
         * @return Map 甲方密钥的Map
         */
        public static Map<String, Object> initKey() throws Exception {
            // 实例化密钥生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
            // 初始化密钥生成器
            keyPairGenerator.initialize(KEY_SIZE);
            // 生成密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            // 甲方公钥
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            // 甲方私钥
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            // 将密钥存储在map中
            Map<String, Object> keyMap = new HashMap<String, Object>();
            keyMap.put(PUBLIC_KEY, publicKey);
            keyMap.put(PRIVATE_KEY, privateKey);
            return keyMap;
        }
    
        /**
         * 私钥加密
         *
         * @param data 待加密数据
         * @param key  密钥
         * @return byte[] 加密数据
         */
        public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
            // 取得私钥
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            // 生成私钥
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
            // 数据加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            return cipher.doFinal(data);
        }
        
        /**
         * 公钥加密
         *
         * @param data 待加密数据
         * @param key  密钥
         * @return byte[] 加密数据
         */
        public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {
            // 实例化密钥工厂
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            // 初始化公钥
            // 密钥材料转换
            X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
            // 产生公钥
            PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
            // 数据加密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            // 对数据分段解密
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] cache;
            int inputLen = data.length;
            int offSet = 0;
            int i = 0;
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                    cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_ENCRYPT_BLOCK;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();
            return decryptedData;
        }
    
        /**
         * 私钥解密
         *
         * @param data 待解密数据
         * @param key  密钥
         * @return byte[] 解密数据
         */
        public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
            // 取得私钥
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
            // 生成私钥
            PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
            // 数据解密
            Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            // 对数据分段解密
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            byte[] cache;
            int inputLen = data.length;
            int offSet = 0;
            int i = 0;
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                    cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_DECRYPT_BLOCK;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();
            return decryptedData;
        }
    
        /**
         * 取得私钥
         *
         * @param keyMap 密钥map
         * @return byte[] 私钥
         */
        public static byte[] getPrivateKey(Map<String, Object> keyMap) {
            Key key = (Key) keyMap.get(PRIVATE_KEY);
            return key.getEncoded();
        }
    
        /**
         * 取得公钥
         *
         * @param keyMap 密钥map
         * @return byte[] 公钥
         */
        public static byte[] getPublicKey(Map<String, Object> keyMap) throws Exception {
            Key key = (Key) keyMap.get(PUBLIC_KEY);
            return key.getEncoded();
        }
    
        /**
         * @param args
         * @throws Exception
         */
        public static void main(String[] args) throws Exception {
            // 初始化密钥
            // 生成密钥对
            Map<String, Object> keyMap = RSACoder.initKey();
            // 公钥
            byte[] publicKey = RSACoder.getPublicKey(keyMap);
    
            // 私钥
            byte[] privateKey = RSACoder.getPrivateKey(keyMap);
            System.out.println("公钥:/n" + Base64.encodeBase64String(publicKey));
            System.out.println("私钥:/n" + Base64.encodeBase64String(privateKey));
    
    
    }
    

    这个工具类提供加密解密方法
    效果:


    image.png

    总结:利用RAS加密方法可以让我们的程序安全性提高,但是也不是万能的,写程序一定要思路清晰,多校验。

    相关文章

      网友评论

        本文标题:JAVA使用RSA加密算法加密解析数据

        本文链接:https://www.haomeiwen.com/subject/mlvyjhtx.html