欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

Java和JS之间实现AES算法加解密通信

最编程 2024-08-14 08:01:05
...

实际开发中客户端与服务端的通信内容往往需要通过密文传输,本文将介绍可以实现Java与js的互相加解密的AES加密方式

Java语言实现

public class AESTest {

    //static String data = "123456RWEQR";
    static String key = "abcdef0123456789";  //16位
    static String iv = "0123456789abcdef";  //16位

    public static void main(String args[]) throws Exception {
       System.out.println(encryptAES("123456"));
        System.out.println(decryptAES(encryptAES("123456")));
    }

    public static String encryptAES(String data) throws Exception {

        try {

            Cipher cipher = Cipher.getInstance("AES/CBC/NOPadding");   //参数分别代表 算法名称/加密模式/数据填充方式
            int blockSize = cipher.getBlockSize();

            byte[] dataBytes = data.getBytes();
            int plaintextLength = dataBytes.length;
            if (plaintextLength % blockSize != 0) {
                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
            }

            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);

            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());

            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
            byte[] encrypted = cipher.doFinal(plaintext);

            return new sun.misc.BASE64Encoder().encode(encrypted);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    public static String decryptAES(String data) throws Exception {
        try {
            byte[] encrypted1 = new BASE64Decoder().decodeBuffer(data);

            Cipher cipher = Cipher.getInstance("AES/CBC/NOPadding");
            SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());

            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);

            byte[] original = cipher.doFinal(encrypted1);
            String originalString = new String(original);
            return originalString;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}

js实现

需要引入 aes.js依赖包 密码:oeer

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>AES TEST</title>
</head>
<body>
<p>待加密值:123456RWEQR</p>
<p id="p1"></p>
<p id="p2"></p>

<script type="text/javascript" src="js/vendor/jquery-1.12.0.min.js"></script>
<script type="text/javascript" src="js/aes/aes.js"></script>
<script type="text/javascript" src="js/aes/pad-zeropadding.js"></script>
<script type="text/javascript">
    $(function () {
        var data = "123456RWEQR";
        var key = CryptoJS.enc.Latin1.parse('abcdef0123456789');
        var iv = CryptoJS.enc.Latin1.parse('0123456789abcdef');

        //加密
        var encrypted = CryptoJS.AES.encrypt(data, key, {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.ZeroPadding
        });
        $("#p1").text("加密结果:"+encrypted.toString());
        console.log(encrypted.toString())
        //解密
        var decrypted = CryptoJS.AES.decrypt(encrypted, key, {iv: iv, padding: CryptoJS.pad.ZeroPadding});
        console.log(decrypted.toString(CryptoJS.enc.Utf8));
        $("#p2").text("解密结果:"+decrypted.toString(CryptoJS.enc.Utf8));
    })
</script>
</body>
</html>

AES四种常用的加密模式

对称/分组密码一般分为流加密(如OFB、CFB等)和块加密(如ECB、CBC等)。对于流加密,需要将分组密码转化为流模式工作。对于块加密(或称分组加密),如果要加密超过块大小的数据,就需要涉及填充和链加密模式。


一、 ECB(Electronic Code Book电子密码本)模式
ECB模式是最早采用和最简单的模式,它将加密的数据分成若干组,每组的大小跟加密密钥长度相同,然后每组都用相同的密钥进行加密。
优点:
1.简单; 2.有利于并行计算; 3.误差不会被传送; 
缺点: 1.不能隐藏明文的模式; 2.可能对明文进行主动攻击; 因此,此模式适于加密小消息。

二、CBC(Cipher Block Chaining,加密块链)模式
优点:
1.不容易主动攻击,安全性好于ECB,适合传输长度长的报文,是SSL、IPSec的标准。 
缺点: 1.不利于并行计算; 2.误差传递; 3.需要初始化向量IV且必须是16字节

三、CFB(Cipher FeedBack Mode,加密反馈)模式
优点:
1.隐藏了明文模式; 2.分组密码转化为流模式; 3.可以及时加密传送小于分组的数据; 
缺点: 1.不利于并行计算; 2.误差传送:一个明文单元损坏影响多个单元; 3.唯一的IV;

四、OFB(Output FeedBack,输出反馈)模式
优点:
1.隐藏了明文模式; 2.分组密码转化为流模式; 3.可以及时加密传送小于分组的数据; 
缺点: 1.不利于并行计算; 2.对明文的主动攻击是可能的; 3.误差传送:一个明文单元损坏影响多个单元

AES三中数据填充方式

PKCS7Padding
Java不支持此方式
PKCS7Padding是缺几个字节就补几个字节的0

PKCS5Padding
JS不支持此方式
PKCS5Padding是缺几个字节就补充几个字节的几,例如缺8个字节,就补充8个字节的8

NOPadding
不补充字节

推荐阅读