AES和RSA前后端加解密

先了解AES和RSA加密算法

AES算法

1、运算速度快,在有反馈模式、无反馈模式的软硬件中,Rijndael都表现出非常好的性能。

2、对内存的需求非常低,适合于受限环境。

3、Rijndael 是一个分组迭代密码, 分组长度和密钥长度设计灵活。

4、AES标准支持可变分组长度,分组长度可设定为32 bit的任意倍数,最小值为128 bit,最大值为256 bit。

5、AES的密钥长度比DES大, 它也可设定为32 比特的任意倍数,最小值为128bit,最大值为256 bit,所以用穷举法是不可能破解的。

7、AES算法的设计策略是WTS。WTS 是针对差分分析和线性分析提出的,可对抗差分密码分析和线性密码分析。

RSA算法

RSA 公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对 其乘积进行因式分解却极其难,因此可以将乘积公开作为加密密钥。

一般来说有两种用途:

一、公钥加密
假设一下,我找了两个数字,一个是1,一个是2。我喜欢2这个数字,就保留起来,不告诉你们(私钥),然后我告诉大家,1是我的公钥。
我有一个文件,不能让别人看,我就用1加密了。别人找到了这个文件,但是他不知道2就是解密的私钥啊,所以他解不开,只有我可以用
数字2,就是我的私钥,来解密。这样我就可以保护数据了。
我的好朋友x用我的公钥1加密了字符a,加密后成了b,放在网上。别人偷到了这个文件,但是别人解不开,因为别人不知道2就是我的私钥,
只有我才能解密,解密后就得到a。这样,我们就可以传送加密的数据了。
二、私钥签名
如果我用私钥加密一段数据(当然只有我可以用私钥加密,因为只有我知道2是我的私钥),结果所有的人都看到我的内容了,因为他们都知
道我的公钥是1,那么这种加密有什么用处呢?
但是我的好朋友x说有人冒充我给他发信。怎么办呢?我把我要发的信,内容是c,用我的私钥2,加密,加密后的内容是d,发给x,再告诉他
解密看是不是c。他用我的公钥1解密,发现果然是c。
这个时候,他会想到,能够用我的公钥解密的数据,必然是用我的私钥加的密。只有我知道我得私钥,因此他就可以确认确实是我发的东西。
这样我们就能确认发送方身份了。这个过程叫做数字签名。当然具体的过程要稍微复杂一些。用私钥来加密数据,用途就是数字签名。

总结:公钥和私钥是成对的,它们互相解密。
公钥加密,私钥解密。
私钥数字签名,公钥验证。

RSA加解密过程图解

接下来就是一个基于两种算法的前后端加解密Demo

加解密逻辑并不复杂,所以只写了一个controller层的代码

package com.example.rsa_aes_demo03.controller;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.SecretKey;
import javax.servlet.http.HttpServletRequest;

import com.example.rsa_aes_demo03.util.AESUtil;
import com.example.rsa_aes_demo03.util.RSAUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;


/**
 * @author LL
 * @Description:
 * @date
 */
@Controller
public class HomeController {

    @RequestMapping("/")
    public String index() {
        return "index";
    }

    /**
     * 获取公钥
     *
     * @return
     */
    @ResponseBody
    @GetMapping("/getPublicKey")
    public Map<String, Object> getKey(HttpServletRequest request) throws Exception {
        Map<String, String> keyMap = RSAUtil.createKeys(1024);
        String publicKey = keyMap.get("publicKey");
        String privateKey = keyMap.get("privateKey");
        Map<String, String> maps = new HashMap<>();
        maps.put("publickey", publicKey);
        maps.put("privatekey", privateKey);
        request.getSession().setAttribute("privateKey", privateKey);
        // 构建反馈模型
        Map<String, Object> map = new HashMap<>();
        map.put("code", 0);
        map.put("message", "success");
        map.put("data", maps);

        return map;
    }

    @ResponseBody
    @PostMapping("/login")
    public Map<String, Object> login(String content, HttpServletRequest request) throws Exception {
        String privateKey = request.getSession().getAttribute("privateKey").toString();
        String newContent = RSAUtil.privateDecrypt(content, RSAUtil.getPrivateKey(privateKey));

        Map<String, String> maps = new HashMap<>();
        maps.put("content", "解密后的内容:   " + newContent);
        // 构建反馈模型
        Map<String, Object> map = new HashMap<>();
        map.put("code", 0);
        map.put("message", "success");
        map.put("data", maps);

        return map;
    }

    @GetMapping("/aesview")
    public String aesView() {
        return "aesview";
    }

    @ResponseBody
    @RequestMapping("/getAesKey")
    public Map<String,Object> aesKey(HttpServletRequest request){
        String key = "AESD2524fegs2s5g";
        String iv = "AESD2524fegs2s5g";
        Map<String, String > maps=new HashMap<>();
        maps.put("key",key);
        maps.put("iv",iv);

        Map<String, Object> map=new HashMap<>();
        map.put("code",0);
        map.put("message","success");
        map.put("data",maps);
        return map;
    }



    @ResponseBody
    @PostMapping("/aesencode")
    public String aesEncode(String encryptData, String key, String iv) {
        // 加密
        return null;
    }

    @ResponseBody
    @PostMapping("/aes" )
    public Map<String, Object> aesDncode(String content) {
		// 解密
        System.out.println("执行到aes代码");
        String keys = "AESD2524fegs2s5g";
        SecretKey key = AESUtil.stringToSecretKey(keys);
		String decryptData = AESUtil.aesEcbDecrypt(content, key);
		Map<String,String> mas = new HashMap<>();
		mas.put("content",decryptData);
        // 构建反馈模型
        Map<String, Object> map = new HashMap<>();
        map.put("code", 0);
        map.put("message", "success");
        map.put("data",mas );
        return map;
    }
}

这里还有个加密没有写完,但逻辑都是差不多的。

还需要两个工具类,
AESUtil

package com.example.rsa_aes_demo03.util;

import java.io.UnsupportedEncodingException;
import java.security.SecureRandom;
import java.util.Base64;

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

/**
 * AES加密工具类
 */
public class AESUtil {
    /**
     * 字符集
     */
    public static final String CHARSET = "UTF-8";
    /**
     * 参数分别代表 : 算法名称/加密模式/数据填充方式</br>
     * 加密模式:</br>
     * <li>1.电码本模式(Electronic Codebook Book (ECB))<li>
     * 这种模式是将整个明文分成若干段相同的小段,然后对每一小段进行加密
     * 2.密码分组链接模式(Cipher Block Chaining (CBC))
     * 这种模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或运算后,再与密钥进行加密。
     */
    public static final String AES_ALGORITHM = "AES";
    // js使用PKCS7的补码方式,其实和PKCS5是一致的
    public static final String ECB_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    public static final String CBC_CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
    /**
     * AES理论上支持128,192,256三种长度的密钥,但是jdk只支持128位
     */
    private static final int KEY_SIZE = 128;

    /**
     * IV(Initialization Value)是一个初始值,对于CBC模式来说,它必须是随机选取并且需要保密的
     * 而且它的长度和密码分组相同(比如:对于AES 128为128位,即长度为16的byte类型数组)
     */
    public static final byte[] IVPARAMETERS = new byte[]{1, 2, 3, 4, 5, 6, 7,
            8, 9, 10, 11, 12, 13, 14, 15, 16};

    /**
     * ECB模式加密
     *
     * @param encryptData 加密内容
     * @param encryptKey  密钥(key)
     * @return 返回Base64字符串
     */
    public static String aesEcbEncrypt(String encryptData, SecretKey encryptKey) {
        try {
            Cipher cipher = Cipher.getInstance(ECB_CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, encryptKey);
            byte[] src = cipher.doFinal(encryptData.getBytes(CHARSET));
            Base64.Encoder encoder = Base64.getEncoder();
            return encoder.encodeToString(src);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * ECB模式解密
     *
     * @param decryptData 密文(解密内容)
     * @param decryptKey  密钥
     * @return 解密后的内容
     */
    public static String aesEcbDecrypt(String decryptData, SecretKey decryptKey) {
        try {
            Base64.Decoder decoder = Base64.getDecoder();
            byte[] encryptBytes = decoder.decode(decryptData);
            Cipher cipher = Cipher.getInstance(ECB_CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, decryptKey);
            byte[] decryptBytes = cipher.doFinal(encryptBytes);
            return new String(decryptBytes, CHARSET);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * CBC模式加密
     *
     * @param encryptData 加密内容
     * @param encryptKey  密钥
     * @param iv          密钥偏移量
     * @return 密文
     */
    public static String aesCbcEncrypt(String encryptData, SecretKey encryptKey, String iv) {
        try {
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(CHARSET));
            Cipher cipher = Cipher.getInstance(CBC_CIPHER_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, encryptKey, ivParameterSpec);
            byte[] src = cipher.doFinal(encryptData.getBytes(CHARSET));
            Base64.Encoder encoder = Base64.getEncoder();
            return encoder.encodeToString(src);
        } catch (Exception e) {
            // TODO: handle exception
            return null;
        }
    }

    /**
     * CBC模式解密
     *
     * @param decryptData 密文
     * @param decryptKey  密钥
     * @param iv          密钥偏移量
     * @return 解密后的内容
     */
    public static String aesCbcDecrypt(String decryptData, SecretKey decryptKey, String iv) {
        try {
            Base64.Decoder decoder = Base64.getDecoder();
            byte[] encryptBytes = decoder.decode(decryptData);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes(CHARSET));
            Cipher cipher = Cipher.getInstance(CBC_CIPHER_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, decryptKey, ivParameterSpec);
            return new String(cipher.doFinal(encryptBytes), CHARSET);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 生成密钥
     *
     * @return
     */
    public static SecretKey generateAESSecretKey() {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_ALGORITHM);
            keyGenerator.init(KEY_SIZE);
            byte[] key = keyGenerator.generateKey().getEncoded();
            return new SecretKeySpec(key, AES_ALGORITHM);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 生成密钥,根据传入的明文key生成,调用SecureRandom进行随机
     *
     * @param decryptKey
     * @return
     */
    public static SecretKey generateAESSecretKey(String decryptKey) {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(AES_ALGORITHM);
            keyGenerator.init(KEY_SIZE, new SecureRandom(decryptKey.getBytes()));
            byte[] key = keyGenerator.generateKey().getEncoded();
            return new SecretKeySpec(key, AES_ALGORITHM);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 字符串key转为SecretKey
     *
     * @param key
     * @return
     */
    public static SecretKey stringToSecretKey(String key) {
        try {
            return new SecretKeySpec(key.getBytes("UTF-8"), "AES");
        } catch (UnsupportedEncodingException e) {
            // TODO: handle exception
            e.printStackTrace();
            return null;
        }
    }

    /**
     * Ecb加密模式,推荐使用 aesEcbEncrypt方法<br>
     * 这个方法使用了SecureRandom,所以前端加密的时候注意
     *
     * @param encodeRules 密钥
     * @param data        加密内容
     * @return
     */
    @Deprecated
    public static String aesEcbEncode(String encodeRules, String data) {

        byte[] byte_AES = null;
        try {
            // 算法实例
            KeyGenerator generator = KeyGenerator.getInstance(AES_ALGORITHM);
            // 根据encodeRules规则初始化密钥生成器
            generator.init(KEY_SIZE, new SecureRandom(encodeRules.getBytes()));
            // 产生原始对称密钥
            SecretKey old_key = generator.generateKey();
            // 获取原始对称密钥的字节数组
            byte[] raw = old_key.getEncoded();
            // 根据字节数组生成ASE密钥
            SecretKey key = new SecretKeySpec(raw, AES_ALGORITHM);
            // 根据指定算法生成密码器
            Cipher cipher = Cipher.getInstance(ECB_CIPHER_ALGORITHM);
            // 初始化密码器,ENCRYPT_MODE 加密,
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // 获取加密内容的字节数组,需要设置为UTF-8,不然中英文混合解密就会乱码
            byte[] byte_encode = data.getBytes(CHARSET);
            // 根据密码器初始化方式--加密:
            byte_AES = cipher.doFinal(byte_encode);
            // 将加密或的数据转换为字符串
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(byte_AES);
    }

    /**
     * Ecb加密模式,推荐使用 aesEcbDncrypt方法<br>
     * 这个方法使用了SecureRandom,所以前端加密的时候注意
     *
     * @param encodeRules 密钥
     * @param data        加密内容
     * @return
     */
    @Deprecated
    public static String aesEcbDncode(String encodeRules, String data) {
        String AES_decode = null;
        try {
            // 1.构造密钥生成器,指定为AES算法,不区分大小写
            KeyGenerator keygen = KeyGenerator.getInstance(AES_ALGORITHM);
            // 2.根据ecnodeRules规则初始化密钥生成器
            // 生成一个128位的随机源,根据传入的字节数组
            keygen.init(128, new SecureRandom(encodeRules.getBytes()));
            // 3.产生原始对称密钥
            SecretKey original_key = keygen.generateKey();
            // 4.获得原始对称密钥的字节数组
            byte[] raw = original_key.getEncoded();
            // 5.根据字节数组生成AES密钥
            SecretKey key = new SecretKeySpec(raw, AES_ALGORITHM);
            // 6.根据指定算法AES自成密码器
            Cipher cipher = Cipher.getInstance(ECB_CIPHER_ALGORITHM);
            // 7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
            cipher.init(Cipher.DECRYPT_MODE, key);
            // 8.将加密并编码后的内容解码成字节数组
            Base64.Decoder decoder = Base64.getDecoder();
            byte[] byte_content = decoder.decode(data);
            /*
             * 解密
             */
            byte[] byte_decode = cipher.doFinal(byte_content);
            AES_decode = new String(byte_decode, CHARSET);
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
        return AES_decode;
    }


    public static void main(String[] args) throws Exception {
        String keys = "8NONwyJtHesysWpM";
        System.out.println(keys.length());
        SecretKey key = stringToSecretKey(keys);
        //SecretKey key = generateAESSecretKey("13245");
        String decryptData = AESUtil.aesEcbEncrypt("ABCDEFGH", key);
        System.out.println("ECB模式  加密后:" + decryptData);
        System.out.println("ECB模式  解密后:" + AESUtil.aesEcbDecrypt(decryptData, key));

        String iv = "8NONwyJtHesysWpM";
        String cbcDecryptData = AESUtil.aesCbcEncrypt("ABCDEFGH", key, iv);
        System.out.println("CBC模式  加密后:" + cbcDecryptData);
        System.out.println("CBC模式  解密后:" + AESUtil.aesCbcDecrypt(cbcDecryptData, key, iv));
    }
}

最后的main 方法中 也展示了各个方法的使用。

RSAUtil

package com.example.rsa_aes_demo03.util;

import com.fasterxml.jackson.databind.ser.Serializers;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import java.io.ByteArrayOutputStream;
import java.security.*;
import java.security.KeyPairGenerator;
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;

/**
 * RSA工具类
 */
public class RSAUtil {

    public static final String CHARSET = "UTF-8";
    public static final String RSA_ALGORITHM = "RSA";

    public static Map<String, String> createKeys(int keySize) {
        //为RSA算法创建一个KeyPairGenerator对象
        KeyPairGenerator kpg;
        try {
            kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
        }

        //初始化KeyPairGenerator对象,密钥长度
        kpg.initialize(keySize);
        //生成密匙对
        KeyPair keyPair = kpg.generateKeyPair();
        //得到公钥
        Key publicKey = keyPair.getPublic();
        Base64.Encoder encoder = Base64.getEncoder();
        String publicKeyStr = encoder.encodeToString(publicKey.getEncoded());
        //得到私钥
        Key privateKey = keyPair.getPrivate();
        String privateKeyStr = encoder.encodeToString(privateKey.getEncoded());
        Map<String, String> keyPairMap = new HashMap<String, String>();
        keyPairMap.put("publicKey", publicKeyStr);
        keyPairMap.put("privateKey", privateKeyStr);

        return keyPairMap;
    }

    /**
     * 公钥加密
     *
     * @param data
     * @param publicKey
     * @return
     */
    public static String publicEncrypt(String data, RSAPublicKey publicKey) {
        try {
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            Base64.Encoder encoder = Base64.getEncoder();
            return encoder.encodeToString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
        } catch (Exception e) {
            throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
        }
    }

    private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
        int maxBlock = 0;
        if (opmode == Cipher.DECRYPT_MODE) {
            maxBlock = keySize / 8;
        } else {
            maxBlock = keySize / 8 - 11;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] buff;
        int i = 0;
        try {
            while (datas.length > offSet) {
                if (datas.length - offSet > maxBlock) {
                    buff = cipher.doFinal(datas, offSet, maxBlock);
                } else {
                    buff = cipher.doFinal(datas, offSet, datas.length - offSet);
                }
                out.write(buff, 0, buff.length);
                i++;
                offSet = i * maxBlock;
            }
        } catch (Exception e) {
            throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
        }
        byte[] resultDatas = out.toByteArray();
        try {
            out.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return resultDatas;
    }

    /**
     * 私钥解密
     *
     * @param data
     * @param privateKey
     * @return
     */

    public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
        try {
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            Base64.Decoder decoder = Base64.getDecoder();
            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, decoder.decode(data), privateKey.getModulus().bitLength()), CHARSET);
        } catch (Exception e) {
            throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
        }
    }

    /**
     * 得到公钥
     *
     * @param publicKey 密钥字符串(经过base64编码)
     * @throws Exception
     */
    public static RSAPublicKey getPublicKey(String publicKey) throws Exception {
        //通过X509编码的Key指令获得公钥对象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        Base64.Decoder decoder = Base64.getDecoder();
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(decoder.decode(publicKey));
        RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
        return key;
    }

    /**
     * 得到私钥
     *
     * @param privateKey 密钥字符串(经过base64编码)
     * @throws Exception
     */
    public static RSAPrivateKey getPrivateKey(String privateKey) throws Exception {
        //通过PKCS#8编码的Key指令获得私钥对象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        Base64.Decoder decoder = Base64.getDecoder();
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(decoder.decode(privateKey));
        RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
        return key;
    }

    public static void main(String[] args) throws Exception {
        Map<String, String> keyMap = RSAUtil.createKeys(1024);
        String publicKey = keyMap.get("publicKey");
        String privateKey = keyMap.get("privateKey");
        System.out.println("公钥: \n\r" + publicKey);
        System.out.println("私钥: \n\r" + privateKey);
        System.out.println("公钥加密——私钥解密");
        String str = "111";
        System.out.println("\r明文:\r\n" + str);
        System.out.println("\r明文大小:\r\n" + str.getBytes().length);
        String encodedData = RSAUtil.publicEncrypt(str, RSAUtil.getPublicKey(publicKey));
        System.out.println("密文:\r\n" + encodedData);
        String decodedData = RSAUtil.privateDecrypt(encodedData, RSAUtil.getPrivateKey(privateKey));
        System.out.println("解密后文字: \r\n" + decodedData);
    }
}

有不懂的怎么用的可以参考main方法。

最后就是两个前端页面的代码了。
index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<a href="/aesview">AES对称加密</a><br>
<input type="text" id="content"/>
<input type="button" value="根据服务端公钥加密" onclick="login()"><br><br>
<hr>
<label>服务端公钥: </label>
<div id="serverPublicKey"></div>
<br>
<label>服务端秘钥:</label>
<div id="serverPrivateKey"></div>
<label>JS加密传输</label>
<div id="encryptContent"></div>
<label>解密后</label>
<div id="decryptContent"></div>
<label>Js解密</label>
<div id="decryptContent2"></div>
</body>
</html>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://cdn.bootcss.com/jsencrypt/2.3.1/jsencrypt.min.js"></script>
<script>
    $(function () {
        getKey();
    })

    function getKey() {
        $.ajax({
            url: '/getPublicKey',
            method: 'get',
            dataType: 'json',
            success: function (res) {
                if (res.code == 0) {
                    var key = res.data.publickey;
                    $("#serverPublicKey").text(key);
                    $("#serverPrivateKey").text(res.data.privatekey);
                }
            }
        })
    }

    function login() {
        var content = $('#content').val();
        // 前端进行加密
        var publicKey = $("#serverPublicKey").text();
        var contents = encrypt(content, publicKey);
        console.log(contents)
        $("#encryptContent").text(contents);
        // 前端进行解密
        var privateKey = $("#serverPrivateKey").text();
        var encryptContent = $("#encryptContent").text()
        var contents2 = decrypt(encryptContent, privateKey);
        console.log(contents2)
        $("#decryptContent2").text(contents2);
        dologin(contents)
    }

    function dologin(content) {
        $.ajax({
            url: '/login',
            method: 'post',
            dataType: 'json',
            data: {
                content: content
            },
            success: function (res) {
                console.log(res);
                $("#decryptContent").text(res.data.content)
            }
        })
    }

    /**
     * 加密内容 text 公钥key
     */
    function encrypt(text, key) {
        // Encrypt with key...
        var encryptKey = new JSEncrypt();
        encryptKey.setPublicKey(key);
        // return encryptKey.encrypt(text);
        return encryptKey.encrypt(text);
    }

    /**
     * 解密内容 text 密钥key
     */
    function decrypt(text, key) {
        console.log('秘钥:   ' + key);
        console.log('秘钥:   ' + text);
        // Encrypt with key...
        var decryptor = new JSEncrypt();
        // 设置密钥key
        decryptor.setPrivateKey(key);
        return decryptor.decrypt(text);
    }

</script>

aesview.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
</head>
<body>
<input type="text" id="content"/>
<input type="button" value="根据服务端公钥加密" onclick="login()">
<br>
<br>
<hr>
<label>密文:</label>
<div id="cipherText"></div>
<label>密钥:</label>
<div id="aeskey"></div>
<label>iv:</label>
<div id="iv"></div>
<label>加密传输</label>
<div id="encryptContent"></div>
<label>解密后</label>
<div id="decryptContent"></div>
<label>Js解密</label>
<div id="decryptContent2"></div>
</body>
</html>
<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/core.js"></script>
<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/cipher-core.js"></script>
<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/mode-ecb.js"></script>
<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/aes.js"></script>
<script src="https://cdn.bootcss.com/crypto-js/3.1.9-1/enc-base64.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script>
    // 测试加、解密
    function testAES() {
        var key = "8NONwyJtHesysWpM";
        var plaintText = 'ABCDEFGH'; // 明文
        var encryptedData = getAesString(plaintText, key);
        console.log(encryptedData);
        var encryptedBase64Str = CryptoJS.enc.Base64.stringify(encryptedData.ciphertext);
        console.log("密文: " + encryptedBase64Str + "");
        console.log("解密后: " + getDAesString(encryptedData, key));
    }

    $(function () {
        getKey();
    })
    function getKey() {
        $.ajax({
            url: '/getAesKey',
            method: 'get',
            dataType: 'json',
            success:function (res) {
                if (res.code == 0){
                    var key=res.data.key;
                    var iv= res.data.iv;
                    $("#aeskey").text(key);
                    $("#iv").text(iv);
                }
            }
        })


    }
    function login() {
        var content = $('#content').val();
        //前端进行加密
        var key =$("#aeskey").text();
        var Encryptcontent = getAesString(content,key);
        $("#encryptContent").text(Encryptcontent);
        //前端进行解密
        var decrypt= getDAesString(Encryptcontent,key);
        $("#decryptContent2").text(decrypt);
        dologin(Encryptcontent)
    }

    function dologin(content) {
        $.ajax({
            url: '/aes',
            method: 'post',
            dataType: 'json',
            data: {
                content: content
            },
            success: function (res) {
                console.log(res);
                $("#decryptContent").text(res.data.content)
            }
        })
    }




    function getAesString(data, key) {//加密
        var key = CryptoJS.enc.Utf8.parse(key);
        var encrypted = CryptoJS.AES.encrypt(data, key, {
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7
        });
        return encrypted;    //返回的是base64格式的密文
    }

    function getDAesString(encrypted, key) {//解密
        var key = CryptoJS.enc.Utf8.parse(key);
        var decrypted = CryptoJS.AES.decrypt(encrypted, key,
            {
                mode: CryptoJS.mode.ECB,
                padding: CryptoJS.pad.Pkcs7
            });
        return decrypted.toString(CryptoJS.enc.Utf8);
    }
</script>

参考博客:https://blog.csdn.net/bruce135lee/article/details/78283806
还有些不记得原地址,在此也感谢大佬们。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值