• 从零开始构建前后端AES加密通信


    推荐

    这里推荐使用ECB方式

    CBC方式还是有问题,后端没有解密成功

    使用方式

    前端加密接口参数

    后端解密参数,返回正常数据

    下包

    npm i -S crypto-js
    

    aes的ECB加密方式

    新建crypto.js文件,构建crypto类

    import CryptoJS from 'crypto-js';
    class CryptoFile {
      constructor () {
        // 秘钥
        this.key = CryptoJS.enc.Utf8.parse('CRYPTOJSKEY00000'); // 16位
        this.iv = CryptoJS.enc.Utf8.parse('CRYPTOJSKEY00000');
      }
      // 加密
      encrypt(word) {
        let words = CryptoJS.enc.Utf8.parse(word);
        let encrypted = CryptoJS.AES.encrypt(words, this.key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 });
        return encrypted.toString();
      }
      
      // 解密
      decrypt(word) {
        let decrypt = CryptoJS.AES.decrypt(word, this.key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 });
        let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
        return decryptedStr.toString();
      }
    }
    export default new CryptoFile()
    
    

    前端使用

    引入类

    import crypto from './crypto';
    

    在需要的地方使用

    我们可以自己测试,看看是不是加密,解密成功

    let data = '你加密的数据'
    let encryptData = crypto.encrypt(JSON.stringify(data)); // 加密后的数据
    let decryptData = crypto.decrypt(encryptData) // 解密后的数据
    

    后端java使用

    java不支持Pkcs7,这个需要自己去下jar包设置

    package com.CryptPacket;
    
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.UnsupportedEncodingException;
    import java.security.InvalidAlgorithmParameterException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.util.Base64;
    
    
    /**
     * AES加解密工具
     * AES-128: key和iv都是16个字节,16*8=128bit,java似乎只支持AES-128
     */
    public class AESCrypt {
        /**
         * AES ECB 加密
         * @param message 需要加密的字符串
         * @param key   密匙
         * @return  返回加密后密文,编码为base64
         */
        public static String encryptECB(String message, String key) {
            final String cipherMode = "AES/ECB/PKCS5Padding";
            final String charsetName = "UTF-8";
            try {
                byte[] content = new byte[0];
                content = message.getBytes(charsetName);
                //
                byte[] keyByte = key.getBytes(charsetName);
                SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
    
                Cipher cipher = Cipher.getInstance(cipherMode);
                cipher.init(Cipher.ENCRYPT_MODE, keySpec);
                byte[] data = cipher.doFinal(content);
                final Base64.Encoder encoder = Base64.getEncoder();
                final String result = encoder.encodeToString(data);
                return result;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            }
    
            return null;
        }
        /**
         * AES ECB 解密
         * @param messageBase64 密文,base64编码
         * @param key   密匙,和加密时相同
         * @return  解密后数据
         */
        public static String decryptECB(String messageBase64, String key) {
            final String cipherMode = "AES/ECB/PKCS5Padding";
            final String charsetName = "UTF-8";
            try {
                final Base64.Decoder decoder = Base64.getDecoder();
                byte[] messageByte = decoder.decode(messageBase64);
    
                //
                byte[] keyByte = key.getBytes(charsetName);
                SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
    
                Cipher cipher = Cipher.getInstance(cipherMode);
                cipher.init(Cipher.DECRYPT_MODE, keySpec);
                byte[] content = cipher.doFinal(messageByte);
                String result = new String(content, charsetName);
                return result;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 测试
         */
        public static void Test()
        {
            String key = "1234567890123456";
            String iv = "1234567890000000";
            String msg = "这是一个测试这是一个测试这是一个测试";
            {
                String encrypt = AESCrypt.encryptCBC(msg, key, iv);
                System.out.println(encrypt);
                String decryptStr = AESCrypt.decryptCBC(encrypt, key, iv);
                System.out.println(decryptStr);
            }
            {
                String encrypt = AESCrypt.encryptECB(msg, key);
                System.out.println(encrypt);
                String decryptStr = AESCrypt.decryptECB(encrypt, key);
                System.out.println(decryptStr);
            }
        }
    }
    

    aes的CBC加密方式

    前端构建crypto类

    import CryptoJS from 'crypto-js';
    class CryptoFile {
      constructor () {
        // 秘钥
        this.key = CryptoJS.enc.Utf8.parse('CRYPTOJSKEY00000'); // 16位
        this.iv = CryptoJS.enc.Utf8.parse('CRYPTOJSKEY00000');
      }
      // 加密
      encrypt(word) {
        let words = CryptoJS.enc.Utf8.parse(word);
        let encrypted = CryptoJS.AES.encrypt(words, this.key, { iv: this.iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
        return encrypted.ciphertext.toString().toUpperCase();
      }
      
      // 解密
      decrypt(word) {
        let encryptedHexStr = CryptoJS.enc.Hex.parse(word);
        let words = CryptoJS.enc.Base64.stringify(encryptedHexStr);
        let decrypt = CryptoJS.AES.decrypt(words, this.key, { iv: this.iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
        let decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
        return decryptedStr.toString();
      }
    }
    export default new CryptoFile()
    
    

    前端使用

    引入类

    import crypto from './crypto';
    

    在需要的地方使用

    我们可以自己测试,看看是不是加密,解密成功

    let data = '你加密的数据'
    let encryptData = crypto.encrypt(JSON.stringify(data)); // 加密后的数据
    let decryptData = crypto.decrypt(encryptData) // 解密后的数据
    

    后端java使用

    java不支持Pkcs7,这个需要自己去下jar包或者自己设置

    package com.CryptPacket;
    
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    import java.io.UnsupportedEncodingException;
    import java.security.InvalidAlgorithmParameterException;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.util.Base64;
    
    
    /**
     * AES加解密工具
     * AES-128: key和iv都是16个字节,16*8=128bit,java似乎只支持AES-128
     */
    public class AESCrypt {
        /**
         * AES CBC 加密
         * @param message 需要加密的字符串
         * @param key   密匙
         * @param iv    IV,需要和key长度相同
         * @return  返回加密后密文,编码为base64
         */
        public static String encryptCBC(String message, String key, String iv) {
            final String cipherMode = "AES/CBC/PKCS5Padding";
            final String charsetName = "UTF-8";
            try {
                byte[] content = new byte[0];
                content = message.getBytes(charsetName);
                //
                byte[] keyByte = key.getBytes(charsetName);
                SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
                //
                byte[] ivByte = iv.getBytes(charsetName);
                IvParameterSpec ivSpec = new IvParameterSpec(ivByte);
    
                Cipher cipher = Cipher.getInstance(cipherMode);
                cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
                byte[] data = cipher.doFinal(content);
                final Base64.Encoder encoder = Base64.getEncoder();
                final String result = encoder.encodeToString(data);
                return result;
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (NoSuchPaddingException e) {
                e.printStackTrace();
            } catch (InvalidKeyException e) {
                e.printStackTrace();
            } catch (InvalidAlgorithmParameterException e) {
                e.printStackTrace();
            } catch (IllegalBlockSizeException e) {
                e.printStackTrace();
            } catch (BadPaddingException e) {
                e.printStackTrace();
            }
    
            return null;
        }
        /**
         * AES CBC 解密
         * @param messageBase64 密文,base64编码
         * @param key   密匙,和加密时相同
         * @param iv    IV,需要和key长度相同
         * @return  解密后数据
         */
        public static String decryptCBC(String messageBase64, String key, String iv) {
            final String cipherMode = "AES/CBC/PKCS5Padding";
            final String charsetName = "UTF-8";
            try {
                final Base64.Decoder decoder = Base64.getDecoder();
                byte[] messageByte = decoder.decode(messageBase64);
    
                //
                byte[] keyByte = key.getBytes(charsetName);
                SecretKeySpec keySpec = new SecretKeySpec(keyByte, "AES");
                //
                byte[] ivByte = iv.getBytes(charsetName);
                IvParameterSpec ivSpec = new IvParameterSpec(ivByte);
    
                Cipher cipher = Cipher.getInstance(cipherMode);
                cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
                byte[] content = cipher.doFinal(messageByte);
                String result = new String(content, charsetName);
                return result;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 测试
         */
        public static void Test()
        {
            String key = "1234567890123456";
            String iv = "1234567890000000";
            String msg = "这是一个测试这是一个测试这是一个测试";
            {
                String encrypt = AESCrypt.encryptCBC(msg, key, iv);
                System.out.println(encrypt);
                String decryptStr = AESCrypt.decryptCBC(encrypt, key, iv);
                System.out.println(decryptStr);
            }
            {
                String encrypt = AESCrypt.encryptECB(msg, key);
                System.out.println(encrypt);
                String decryptStr = AESCrypt.decryptECB(encrypt, key);
                System.out.println(decryptStr);
            }
        }
    }
    

    参考资料

    AES加解密,js前端和java后端实现

    前端加密JS库--CryptoJS 使用指南

    强大的前端加密/解密js库crypto-js使用解析

    Aes加密和解密 Cryptojs和java

  • 相关阅读:
    单多文件上传
    C程序多项式加法器
    显示桌面回来了,太牛了
    Meta 方便搜索引擎排序
    数据结构(c)试验题目汇总
    dos 命令符
    两夜之后,停车场模拟告一段落
    php 搜索数据表 排序
    读取 Radio 的值
    JSF2.0/Richfaces/MiniOA开发入门视频教程
  • 原文地址:https://www.cnblogs.com/WhiteM/p/14068778.html
Copyright © 2020-2023  润新知