美文网首页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加密算法加密解析数据

    1.JAVA使用RSA加密算法解析数据 话不多说,直接开干 这是一个普通的接口,接下来我们分析一下解析里面的数据 ...

  • RSA加密转16进制

    知识补充: RSA算法是一种非对称加密算法,常被用于加密数据传输. RSA基本原理: RSA使用"秘匙...

  • RSA加密算法详解

    什么是RSA算法? RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是197...

  • # RSA 公钥加密算法

    # RSA 公钥加密算法 # RSA 公钥加密算法

  • RSA从原理到ctf解题(原理篇)

    简介: RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德...

  • 局1_RSA算法和SM2算法

    RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯...

  • RSA 密钥的生成

    简介 RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·...

  • JAVA加密系列(三)- 非对称加密算法 RSA、DSA

    JAVA加密系列(三)- 非对称加密算法 RSA、DSA 非对称加密算法需要两个密钥:公开密钥(publickey...

  • Android 拿到私钥字符串对目标字符串进行加密

    关于加密算法 分为对称和非对称加密算法,其中RSA是常用非对称加密算法。对称加密中AES高级加密标准使用Rijnd...

  • HASH&对称加密

    1、非对称加密(现代加密算法):RSA(不适合加密大数据)2、对称加密(传统加密算法):DES、3DES、AES;...

网友评论

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

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