Java使用RSA加密AES随机密钥,AES加密数据第三方接口测试demo

今天公司需求和别的公司要进行第三方接口对接,自己先写的一个小demo拿来跑跑
其中涉及到RSA非对称的加解密算法和AES的对称加解密算法,下面是楼主参考别人然后自己改了一下的工具类。

AES生成密钥,加解密工具类AESutil

package com.qyq.springbootapi.util;

import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * AES生成密钥,加解密工具类
 */
public class AesUtil {

    /**
     * 指定加密算法
     */
    private static final String KEY_ALGORITHM = "AES";

    /**
     * 指定生成多少位的密钥
     */
    private static final int KEY_BIT = 128;

    /**
     * 随机生成AES密钥
     * @return
     * @throws Exception
     */
    public static String getGenerateKey()throws Exception{
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_ALGORITHM);
        keyGenerator.init(KEY_BIT);
        SecretKey secretKey = keyGenerator.generateKey();
        byte[] encoded = secretKey.getEncoded();
        return Base64.encodeBase64String(encoded);
    }

    /**
     * 将String类型的密钥转化为SecretKey类型
     * @param generateKey
     * @return
     */
    private static SecretKey StringToSecretKey(String generateKey){
        byte[] bytes = Base64.decodeBase64(generateKey);
        SecretKeySpec spec = new SecretKeySpec(bytes,KEY_ALGORITHM);
        return  spec;
    }

    /**
     * 加密
     * @param data
     * @param generateKey
     * @return
     * @throws Exception
     */
    public static String encrypt(String data, String generateKey)throws Exception{
        SecretKey secretKey = StringToSecretKey(generateKey);

        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE,secretKey);
        byte[] aFinal = cipher.doFinal(data.getBytes("UTF-8"));
        return Base64.encodeBase64String(aFinal);
    }

    /**
     * 解密
     * @param data
     * @param generateKey
     * @return
     * @throws Exception
     */
    public static String decrypt(String data, String generateKey)throws Exception{
        SecretKey secretKey = StringToSecretKey(generateKey);
        byte[] bytes = Base64.decodeBase64(data);

        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE,secretKey);
        byte[] aFinal = cipher.doFinal(bytes);
        return new String(aFinal,"UTF-8");
    }

}

RSA加解密工具类:

package com.qyq.springbootapi.util;

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.Base64;
import java.util.HashMap;
import java.util.Map;

public class RsaUtil {

    /**
     * 指定加密算法
     */
    private static final String KEY_ALGORITHM = "RSA";

    /**
     * 指定生成多少位的密钥
     */
    private static final int KEY_BIT = 1024;

    /** *//**
     * RSA最大加密明文大小
     */
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /** *//**
     * RSA最大解密密文大小
     * 1024位密钥的要设置为128,
     * 248位密钥的要改成256,不然会报错
     */
    private static final int MAX_DECRYPT_BLOCK = 128;

    /**
     * 生成密钥对
     * @return
     * @throws Exception
     */
    public static Map genKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        keyPairGenerator.initialize(KEY_BIT);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();//生成公钥
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();//生成密钥
        Map map = new HashMap<>(2);
        map.put("publicKey",rsaPublicKey);
        map.put("privateKey",rsaPrivateKey);
        return map;
    }

    /**
     * 获取公钥
     * @param map
     * @return
     */
    public static String getPublicKey(Map map){
        Key key = (Key) map.get("publicKey");
        String publicKey = Base64.getEncoder().encodeToString(key.getEncoded());
        return publicKey;
    }

    /**
     * 获取私钥
     * @param map
     * @return
     */
    public static String getPrivate(Map map){
        Key key = (Key) map.get("privateKey");
        String privateKey = Base64.getEncoder().encodeToString(key.getEncoded());
        return privateKey;
    }

    /**
     * 公钥分段加密 --》公钥加密
     * @param data
     * @param publicKey
     * @return
     * @throws Exception
     */
    public static String encrypt(String data, String publicKey) throws Exception {
        byte[] bytes = Base64.getDecoder().decode(publicKey);//先把公钥进行解码
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PublicKey publicK = keyFactory.generatePublic(x509EncodedKeySpec);

        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.ENCRYPT_MODE, publicK);
        int inputLen = data.getBytes("UTF-8").length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offset = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段加密
        while (inputLen - offset > 0) {
            if (inputLen - offset > MAX_ENCRYPT_BLOCK) {
                cache = cipher.doFinal(data.getBytes("UTF-8"), offset, MAX_ENCRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(data.getBytes("UTF-8"), offset, inputLen - offset);
            }
            out.write(cache, 0, cache.length);
            i++;
            offset = i * MAX_ENCRYPT_BLOCK;
        }
        byte[] encryptedData = out.toByteArray();
        out.close();
        // 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串
        // 加密后的字符串
        return Base64.getEncoder().encodeToString(encryptedData);
    }

    /**
     * 私钥分段解密 --》私钥解密
     * @param data
     * @param privateKey
     * @return
     * @throws Exception
     */
    public static String decrypt(String data, String privateKey) throws Exception {
        byte[] bytes = Base64.getDecoder().decode(privateKey);//先对私钥进行解码
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bytes);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        PrivateKey privateK = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
        cipher.init(Cipher.DECRYPT_MODE, privateK);
        byte[] dataBytes = Base64.getDecoder().decode(data);//对要解密的数据进行解码
        int inputLen = dataBytes.length;
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offset = 0;
        byte[] cache;
        int i = 0;
        // 对数据分段解密
        while (inputLen - offset > 0) {
            if (inputLen - offset > MAX_DECRYPT_BLOCK) {
                cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);
            } else {
                cache = cipher.doFinal(dataBytes, offset, inputLen - offset);
            }
            out.write(cache, 0, cache.length);
            i++;
            offset = i * MAX_DECRYPT_BLOCK;
        }
        byte[] decryptedData = out.toByteArray();
        out.close();
        // 解密后的内容
        return new String(decryptedData, "UTF-8");
    }




}

进行第三方接口测试
controller层:

package com.qyq.springbootapi.controller;

import com.alibaba.fastjson.JSON;
import com.qyq.springbootapi.result.ResponseResult;
import com.qyq.springbootapi.util.AesUtil;
import com.qyq.springbootapi.util.RsaUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import java.net.URI;
import java.net.URLDecoder;
import java.net.URLEncoder;

/**
 * 使用RSA加密AES密钥,然后用AES加密数据进行传输
 * 非对称算法加解密速度慢,对称算法快。so....
 */
@RestController
public class AESController {

    @Autowired
    private RestTemplate restTemplate;
    @Value("${RSA.publicKey}")
    private String publicKey;
    @Value("${RSA.privateKey}")
    private String privateKey;

    @GetMapping("/server")
    public ResponseResult TestApiController(@RequestParam("desKey") String desKey,
                                            @RequestParam("data") String data){
        try {
            String des_key = URLDecoder.decode(desKey, "UTF-8");
            String r_data = URLDecoder.decode(data, "UTF-8");
            System.out.println("接收到的加密AES密钥:"+des_key);
            System.out.println("接收到的加密数据:"+r_data);
            //先用RSA私钥解密得到AES密钥
            String decrypt = RsaUtil.decrypt(des_key, privateKey);
            System.out.println("解密后得到的AES密钥:"+decrypt);
            //再使用AES密钥解密数据
            String s = AesUtil.decrypt(r_data, decrypt);
            System.out.println("AES密钥解密后的数据:"+s);
            //加签返回信息
            String sign = RsaUtil.sign(s, privateKey);
            return new ResponseResult(0,"成功",sign);

        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseResult(0,"失败",404);
        }


    }

    @GetMapping("/client")
    public ResponseResult TestApiController1(String content){
        try {
            //生成AES随机密钥
            String generateKey = AesUtil.getGenerateKey();
            System.out.println("生成AES随机密钥:"+generateKey);
            //使用RSA加密AES密钥
            String desKey = RsaUtil.encrypt(generateKey, publicKey);
            System.out.println("公钥加密AES密钥:"+desKey);
            //AES加密数据
            String data = AesUtil.encrypt(content, generateKey);
            URI uri = UriComponentsBuilder.fromHttpUrl("http://localhost:8080/server").queryParam("desKey", URLEncoder.encode(desKey,"UTF-8"))
                    .queryParam("data",URLEncoder.encode(data,"UTF-8")).build().toUri();
            ResponseResult result = restTemplate.getForObject(uri, ResponseResult.class);
            String jsonString = JSON.toJSONString(result.getData());
            System.out.println("返回的签证信息:"+jsonString);
            boolean verify = RsaUtil.verify(content, publicKey, jsonString);
            System.out.println("验签结果:"+verify);
            return new ResponseResult(0,"成功",verify);

        } catch (Exception e) {
            e.printStackTrace();
            return new ResponseResult(0,"失败",404);
        }

    }



}

你可能感兴趣的:(RSA加解密)