精华内容
下载资源
问答
  • 北京交通大学密码学作业,第三次实验源码及实验报告,包括工程文件和测试用例
  • AES加密算法java)实现

    热门讨论 2015-01-15 16:32:38
    AES高级加密标准,在密码学中又称Rijndael加密法,是美国联邦政府采用的一种...本软件是用java语言开发,实现了AES算法对文件的加密和解密,并在界面上加了进度条,来提示用户加密解密的进度。如果不足之处,欢迎留言。
  • 这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用,已然成为对称密钥加密中最流行的算法之一。详见 百科 高级加密标准 AES 1.2. JAVA实现AES加解密 import lombok.extern....

    1. AES

    1.1. 概念

    密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。
    这个标准用来替代原先的DES(Data Encryption Standard),已经被多方分析且广为全世界所使用,已然成为对称密钥加密中最流行的算法之一。详见 百科 高级加密标准 AES

    1.2. JAVA实现AES加解密

    import lombok.extern.slf4j.Slf4j;
    
    import javax.crypto.Cipher;
    import javax.crypto.KeyGenerator;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    import java.security.SecureRandom;
    import java.util.Arrays;
    
    @Slf4j
    class AESCryptoUtil {
        public static void main(String[] args) {
            String content = "美好的世界,美好的中国,美好的未来!!!";
    
            byte[] encryptResult = encrypt(content);
            byte[] decryptResult = decrypt(encryptResult);
    
    
            String encryptStr = parseByte2HexStr(encryptResult);
            printMsg("========\n加密前:%s\n加密后:%s\n解密后:%s", content, encryptStr, new String(decryptResult));
    
            //解密时,不能new String(encryptResult,"utf-8").getBytes("utf-8")
            decryptResult = decrypt(parseHexStr2Byte(encryptStr));
            printMsg("========\n加密前:%s\n加密后:%s\n解密后:%s", content, encryptStr,new String(decryptResult));
    
    
            //采用AES/ECB/NoPadding时,要求密钥长度16、24、32中的一个、待加密内容的byte[]长度必须是16的倍数
            encryptResult = encrypt2(content);
            decryptResult = decrypt2(encryptResult);
            encryptStr = parseByte2HexStr(encryptResult);
            printMsg("========\n加密前:%s\n加密后:%s\n解密后:%s", content, encryptStr, new String(decryptResult));
    
        }
    
        private static void printMsg(String template, Object... args) {
            System.out.println(String.format(template, args));
        }
    
        private static String password = "科技兴国@!##";
        private static SecretKeySpec key;
    
        static {
            init();
        }
    
        private static void init() {
            try {
                KeyGenerator kgen = KeyGenerator.getInstance("AES");
                kgen.init(256, new SecureRandom(password.getBytes()));
                SecretKey secretKey = kgen.generateKey();
                byte[] enCodeFormat = secretKey.getEncoded();
                key = new SecretKeySpec(enCodeFormat, "AES");
            } catch (Exception e) {
                log.error("初始化AES算法失败" + e.getMessage(), e);
            }
        }
    
        /**
         * 加密
         *
         * @param content 需要加密的内容
         * @return
         */
        public static byte[] encrypt(String content) {
            try {
                Cipher cipher = Cipher.getInstance("AES");
                byte[] byteContent = content.getBytes("utf-8");
                cipher.init(Cipher.ENCRYPT_MODE, key);
                byte[] result = cipher.doFinal(byteContent);
                return result;
            } catch (Exception e) {
                log.error("AES加密失败" + e.getMessage(), e);
            }
            return null;
        }
    
        public static byte[] decrypt(byte[] content) {
            try {
                Cipher cipher = Cipher.getInstance("AES");
                cipher.init(Cipher.DECRYPT_MODE, key);
                byte[] result = cipher.doFinal(content);
                return result;
            } catch (Exception e) {
                log.error("AES解密失败" + e.getMessage(), e);
            }
            return null;
        }
    
        /**
         * 加密
         *
         * @param content 需要加密的内容
         * @return
         */
        public static byte[] encrypt2(String content) {
            try {
                byte[] bytePassword = password.getBytes();
                bytePassword = checkByteLength(bytePassword);
                SecretKeySpec key = new SecretKeySpec(bytePassword, "AES");
                Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
                byte[] byteContent = content.getBytes("utf-8");
                byteContent = checkByteLength(byteContent);
                cipher.init(Cipher.ENCRYPT_MODE, key);
                byte[] result = cipher.doFinal(byteContent);
                return result;
            } catch (Exception e) {
                log.error("AES加密失败" + e.getMessage(), e);
            }
            return null;
        }
    
        public static byte[] decrypt2(byte[] content) {
            try {
                byte[] bytePassword = password.getBytes();
                bytePassword = checkByteLength(bytePassword);
                SecretKeySpec key = new SecretKeySpec(bytePassword, "AES");
                Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
                cipher.init(Cipher.DECRYPT_MODE, key);
                byte[] result = cipher.doFinal(content);
                return result;
            } catch (Exception e) {
                log.error("AES解密失败" + e.getMessage(), e);
            }
            return null;
        }
    
        private static byte[] checkByteLength(byte[] byteContent) {
            int length = byteContent.length;
            int remainder = length % 16;
            if(remainder == 0){
                return byteContent;
            }else{
                return Arrays.copyOf(byteContent,length+(16-remainder));
            }
        }
    
        /**将二进制转换成16进制
         * @param buf
         * @return
         */
        public static String parseByte2HexStr(byte buf[]) {
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < buf.length; i++) {
                String hex = Integer.toHexString(buf[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        }
    
        public static byte[] parseHexStr2Byte(String hexStr) {
            if (hexStr.length() < 1) {
                return null;
            }
            byte[] result = new byte[hexStr.length()/2];
            for (int i = 0;i< hexStr.length()/2; i++) {
                int high = Integer.parseInt(hexStr.substring(i*2, i*2+1), 16);
                int low = Integer.parseInt(hexStr.substring(i*2+1, i*2+2), 16);
                result[i] = (byte) (high * 16 + low);
            }
            return result;
        }
    }
    

    2. 使用中的各种坑

    2.1. 加密后的byte数组不能强制转换成字符串

    加密后返回byte[],此byte数组强制转换为字符串是乱码,然后再用转换后的字符串转换为byte数组去解码(见下面的代码)会报错:Input length must be multiple of 16 when decrypting with padded cipher

    在这种情况下: 字符串和byte数组不是互逆的;要避免这种情况,需要做一些修订,可以考虑将二进制数据转换成十六进制表示。详见parseByte2HexStr、parseHexStr2Byte两个方法

    decryptResult = decrypt(new String(encryptResult,"utf-8").getBytes("utf-8"));
    

    2021-07-02 11:27:39.067 [main] ERROR pattern.chain.AESCryptoUtil:decrypt:87 - AES解密失败Input length must be multiple of 16 when decrypting with padded cipher
    javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:936) ~[sunjce_provider.jar:1.8.0_171]
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847) ~[sunjce_provider.jar:1.8.0_171]
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446) ~[sunjce_provider.jar:1.8.0_171]
    at javax.crypto.Cipher.doFinal(Cipher.java:2164) ~[?:1.8.0_171]
    at org.apache.design.pattern.chain.AESCryptoUtil.decrypt(AESCryptoUtil.java:84) [classes/:?]
    at org.apache.design.pattern.chain.AESCryptoUtil.main(AESCryptoUtil.java:26) [classes/:?]

    2.2. 采用AES/ECB/NoPadding加密的限制

    当采用如下方式获取Cipher实例时,则要求密钥长度16、24、32中的一个、待加密内容的byte[]长度必须是16的倍数,否则报如下错误:

    Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
    

    2021-07-02 11:37:15.432 [main] ERROR pattern.chain.AESCryptoUtil:encrypt2:111 - AES加密失败Input length not multiple of 16 bytes
    javax.crypto.IllegalBlockSizeException: Input length not multiple of 16 bytes
    at com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1042) ~[sunjce_provider.jar:1.8.0_171]
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:1010) ~[sunjce_provider.jar:1.8.0_171]
    at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:847) ~[sunjce_provider.jar:1.8.0_171]
    at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446) ~[sunjce_provider.jar:1.8.0_171]
    at javax.crypto.Cipher.doFinal(Cipher.java:2164) ~[?:1.8.0_171]


    2021-07-02 11:36:39.064 [main] ERROR pattern.chain.AESCryptoUtil:encrypt2:111 - AES加密失败Invalid AES key length: 18 bytes
    java.security.InvalidKeyException: Invalid AES key length: 18 bytes
    at com.sun.crypto.provider.AESCrypt.init(AESCrypt.java:87) ~[sunjce_provider.jar:1.8.0_171]
    at com.sun.crypto.provider.ElectronicCodeBook.init(ElectronicCodeBook.java:94) ~[sunjce_provider.jar:1.8.0_171]
    at com.sun.crypto.provider.CipherCore.init(CipherCore.java:592) ~[sunjce_provider.jar:1.8.0_171]
    at com.sun.crypto.provider.CipherCore.init(CipherCore.java:468) ~[sunjce_provider.jar:1.8.0_171]
    at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:313) ~[sunjce_provider.jar:1.8.0_171]
    at javax.crypto.Cipher.implInit(Cipher.java:801) ~[?:1.8.0_171]
    at javax.crypto.Cipher.chooseProvider(Cipher.java:863) ~[?:1.8.0_171]

    2.3 美国的出口管制限制引起的坑

    2.3.1. 背景

    因为美国的出口管制限制,Java发布的运行环境包中的加解密有一定的限制。
    比如默认不允许256位密钥的AES加解密,如果使用,会报如下错误:
    2021-07-02 11:40:34.048 [main] ERROR pattern.chain.AESCryptoUtil:encrypt:75 - AES加密失败Illegal key size or default parameters
    java.security.InvalidKeyException: Illegal key size or default parameters
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1025) ~[?:1.8.0_171]
    at javax.crypto.Cipher.implInit(Cipher.java:800) ~[?:1.8.0_171]
    at javax.crypto.Cipher.chooseProvider(Cipher.java:863) ~[?:1.8.0_171]
    at javax.crypto.Cipher.init(Cipher.java:1248) ~[?:1.8.0_171]
    at javax.crypto.Cipher.init(Cipher.java:1185) ~[?:1.8.0_171]

    从Java 1.8.0_151

    2.3.2. 解决方案

    方案1
    将%JDK_HOME%\jre\lib\security\java.security, 找到定义java安全性属性crypto.policy的行,将值修改为unlimited。
    默认情况下,您应该能找到一条注释掉的行:
    #crypto.policy=unlimited
    您可以通过取消注释该行来启用无限制,删除#:

    方案2
    如果%JDK_HOME%\jre\lib\security目录下有jar包 且 crypto.policy 未配置,则使用jar包内置的规则
    将%JDK_HOME%\jre\lib\security\policy\unlimited下的2个JAR【local_policy.jar、US_export_policy.jar】复制到%JDK_HOME%\jre\lib\security目录下,如果有,直接覆盖。

    方案3
    如果%JDK_HOME%\jre\lib\security目录下没有jar包 且 crypto.policy 未配置,则默认启用无限制的。

    升级版本
    https://www.oracle.com/technetwork/java/javase/8u161-relnotes-4021379.html
    在官方文档写到,
    security-libs/javax.crypto
    Unlimited cryptography enabled by default
    The JDK uses the Java Cryptography Extension (JCE) Jurisdiction Policy files to configure cryptographic algorithm restrictions. Previously, the Policy files in the JDK placed limits on various algorithms. This release ships with both the limited and unlimited jurisdiction policy files, with unlimited being the default. The behavior can be controlled via the new ‘crypto.policy’ Security property found in the /lib/java.security file. Please refer to that file for more information on this property.
    也就是从 1.8.0_161-b12 版本后,默认将采用无限制的加密算法,也就是使用 unlimited 下的jar包。我们也可以通过 设置 java.security 文件的 crypto.policy的值来改变这个默认的值。

    展开全文
  • AES加密算法JAVA实现

    2015-12-27 02:30:59
    AES加密算法JAVA实现(只有加密)
  • Java实现AES加密算法

    万次阅读 2019-10-02 12:00:27
    高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥,具体的加密流程如下图: 下面简单介绍下各个部分的...

    最近恶补了一些关于加密算法的知识,然后用编程语言来实现

    AES简介

    高级加密标准(AES,Advanced Encryption Standard)为最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。对称加密算法也就是加密和解密用相同的密钥,具体的加密流程如下图:

    下面简单介绍下各个部分的作用与意义:

    • 明文P

    没有经过加密的数据

    • 密钥K

    用来加密明文的密码,在对称加密算法中,加密与解密的密钥是相同的,密钥为接收方与发送方协商产生,但不可以直接在网络上传输,否则会导致密钥泄露,通常是通过非对称加密算法加密密钥,然后再通过网络传输给对方,或者直接面对面商量密钥。密钥绝对不能泄露,否则会被攻击者还原密钥,窃取数据

    • AES加密函数

    设AES加密函数为E,则C = E(K,P).其中P为明文,K为密钥,C为密文。也就是说,把明文P和密钥K作为加密函数的参数输入,则加密函数E会输出密文C

    • 密文C

    经过加密函数处理后的数据

    • AES解密函数

    设AES解密函数为D,则P = D().其中C为密文,K为密钥,P为明文。也就是说,把密文C和密钥K作为解密函数的参数输入,则解密函数会输出明文P

    这里简单解释下对称加密算法非对称加密算法

    • 对称加密算法

    加密和解密使用的密钥是相同的,这种加密方式加密速度非常快,适合经常发送数据的场合。缺点是密钥的传输比较麻烦

    • 非对称加密算法

    加密和解密使用的密钥是不同的,这种加密方式是用数学定理或者公式构造的,通常加密解密的速度比较慢,适合偶尔发送数据的场合。优点是密钥传输方便。常见的非对称加密算法为RSA、ECC和EIGamal

    实际中,一般是通过RSA加密AES的密钥,传输到接收方,接收方解密得到AES密钥

    AES的基本结构

    AES为分组密码,分组密码也就是把明文分成一组一组的,每组长度相等,每次加密一组数据,直到加密完所有组。在AES标准规范中,分组长度只能是128位,也就是说,每个分组为16个字节。密钥的长度可以使用128位、192位或256位。密钥的长度不同,推荐加密轮数也不同。如下表所示:

    AES密钥长度(32bit)分组长度(32bit)加密轮数
    AES-1284410
    AES-1926412
    AES-2568414

    上面说到,AES的加密公式为C = E(K,P),在加密函数E种,会执行一个轮函数,并且执行n(n为加密轮数)次这个轮函数,这个轮函数的前n-1次执行的操作是一样的,只有第n次有所不同

    AES的处理单位是字节,128位的输入明文分组P和输入密钥K都被分成16字节,分别记为 P = P 0 , P 1 , . . . , P 15 P = P_0,P_1,...,P_{15} P=P0,P1,...,P15 K = K 0 , K 1 , . . . , K 15 K = K_0,K_1,...,K_{15} K=K0,K1,...,K15。如明文分组为P=abcdefghijklmnop,其中字符a对应 P 0 P_0 P0,p对应 P 15 P_{15} P15。一般地,明文分组用字节为单位地正方形矩阵描述,称为状态矩阵。在算法地每一轮中,状态矩阵地内容不断发生变化,最后的结果作为密文输出。该矩阵中字节地排列顺序为从上到下、从左至右依次排列,如下图所示:

    现在假设明文分组P=abcdefghijklmnop,则对应上面生成地状态矩阵图如下:

    上图中,0x61为a字符的十六进制表示,可以看到,明文经过AES加密后,已经面目全非了

    类似地,128位密钥也是用以字节为单位的矩阵表示,矩阵的每一列被称为1个32为比特字。通过密钥编排函数可以将该密钥矩阵扩展成一个44字组成的序列W[0],W[1],…,W[43]。该序列的前4个元素W[0],W[1],W[2],W[3]是原始密钥,用于加密运算中的初始密钥。后面40个字分为10组,每组4个字(128bit)分别用于10轮加密运算中的轮密钥加,如下图所示:

    上图中,设K=abcdefghijklmnop,则 K 0 = a , K 15 = p K_0=a,K_{15}=p K0=a,K15=p,w[0] = K 0 k 1 K 2 K 3 = a b c d =K_0k_1K_2K_3=abcd =K0k1K2K3=abcd

    AES整体的结构如下图所示,其中W[0,3]是指W[0]、W[1]、W[2]和W[3]串联组成的128位密钥。加密的第一轮到第9轮的轮函数一样,包括4个操作,字节代换、行位移、列混合和轮密钥加。最后一轮迭代不执行列混合。另外,在第一轮迭代之前,先将明文和原始密钥进行一次异或加密操作

    上图也展示了AES的解密过程,解密过程仍为10轮,每一轮的操作是加密操作的逆操作。由于AES的4个轮操作都是可逆的,因此,解密操作的每一轮就是顺序执行逆行移位、逆字节代换、轮密钥加和逆列混合。同加密操作类似,最后一轮不执行逆列混合,在第1轮解密之前,要执行1次密钥加操作

    下面分别介绍AES中一轮的4个操作阶段,这4分操作阶段使输入位得到充分的混淆

    字节代换

    1.字节代换操作

    AES的字节代换其实就是一个简单的查表操作。AES定义了一个S盒和一个逆S盒

    AES的S盒:

    把该字节的高4位作为行值,低4位作为列值,取出S盒或者逆S盒中对应的行的元素作为输出。例如,加密时,输出的字节S1为0x12,则查S盒的第0x01行和0x02列,得到值0xc9,然后替换S1原有的0x12为0xc9。状态矩阵经字节代换后的图如下:

    2.字节代换逆操作

    逆字节代换也就是查逆S盒来变换,逆S盒如下:

    行位移

    1.行位移变换

    行移位是一个简单的左循环移位操作。当密钥长度为128比特时,状态矩阵的第0行左移0字节,第1行左移1字节,第2行左移2字节,第3行左移3字节,如下图所示:

    2.行位移逆变换

    行移位的逆变换是将状态矩阵中的每一行执行相反的移位操作,例如AES-128中,状态矩阵的第0行右移0字节,第1行右移1字节,第2行右移2字节,第3行右移3字节

    列混合

    1.列混合预算

    列混合变换是通过矩阵相乘来实现的,经行移位后的状态矩阵与固定的矩阵相乘,得到混淆后的状态矩阵,如下图的公式所示:

    状态矩阵中的第j列(0 ≤j≤3)的列混合可以表示为:
    KaTeX parse error: Expected 'EOF', got '&' at position 16: S'_{0,j} = (2 &̲#042; S_{0,j}) …

    2.列混合逆运算

    逆向列混合变换可由下图的矩阵乘法定义:

    可以验证,逆变换矩阵同正变换矩阵的乘积恰好为单位矩阵

    轮密钥加

    轮密钥加是将128位轮密钥 K i K_i Ki同状态矩阵中的数据进行逐位异或操作,如下图所示。其中,密钥 K i K_i Ki中每个字W[4i],W[4i+1],W[4i+2],W[4i+3]为32位比特字,包含4个字节,他们的生成算法下面在下面介绍。轮密钥加过程可以看成是字逐位异或的结果,也可以看成字节级别或者位级别的操作。也就是说,可以看成S0 S1 S2 S3 组成的32位字与W[4i]的异或运算

    轮密钥加的逆运算同正向的轮密钥加运算完全一致,这是因为异或的逆操作是其自身。轮密钥加非常简单,但却能够影响S数组中的每一位

    密钥扩展


    这个4*4矩阵的每一列的4个字节组成一个字,矩阵4列的4个字依次命名为W[0]、W[1]、W[2]和W[3],它们构成一个以字为单位的数组W。例如,设密钥K=abcdefghijklmnop,则 K 0 = a , K 1 = b , K 2 = c , K 3 = d K_0 = a,K_1 = b,K_2 = c,K_3 = d K0=a,K1=b,K2=c,K3=d,W[0] = abcd

    接着,对W数组扩充40个新列,构成总共44列的扩展密钥数组。新列以如下的递归方式产生:

    1. 如果i不是4的倍数,那么第i列由如下等式确定:W[i]=W[i-4]⨁W[i-1]
    2. 如果i是4的倍数,那么第i列由如下等式确定:W[i]=W[i-4]⨁T(W[i-1])

    其中,函数T由3部分组成:字循环、字节代换和轮常量异或,这3部分的作用分别如下:

    • 字循环:将1个字中的4个字节循环左移1个字节。即将输入字[b0, b1, b2, b3]变换成[b1,b2,b3,b0]
    • 字节代换:对字循环的结果使用S盒进行字节代换
    • 轮常量异或:将前两步的结果同轮常量Rcon[j]进行异或,其中j表示轮数

    轮常量Rcon[j]是一个字,其值见下表:

    j12345
    Rcon[j]01 00 00 0002 00 00 0004 00 00 0008 00 00 0010 00 00 00
    j678910
    Rcon[j]20 00 00 0040 00 00 0080 00 00 001B 00 00 0036 00 00 00

    举个例子,设初始的128为密钥为:3C A1 0B 21 57 F0 19 16 90 2E 13 80 AC C1 07 BD,那么4个初始值为

    W[0] = 3C A1 0B 21 
    W[1] = 57 F0 19 16 
    W[2] = 90 2E 13 80 
    W[3] = AC C1 07 BD 
    

    下面求扩展的第1轮的子密钥(W[4],W[5],W[6],W[7])

    由于4是4的倍数,所以:W[4] = W[0] ⨁ T(W[3]),T(W[3])的计算步骤如下:

    1. 循环地将W[3]的元素移位:AC C1 07 BD变成C1 07 BD AC
    2. C1 07 BD AC作为S盒的输入,输出为78 C5 7A 91
    3. 78 C5 7A 91与第一轮轮常量Rcon[1]进行异或运算,将得到79 C5 7A 91,因此,T(W[3]) = 79 C5 7A 91,故W[4] = 3C A1 0B 21 ⨁ 79 C5 7A 91 = 45 64 71 B0

    其余3个子密钥段的计算如下:

    W[5] = W[1] ⨁ W[4] = 57 F0 19 16 ⨁ 45 64 71 B0 = 12 94 68 A6 
    W[6] = W[2] ⨁ W[5] =90 2E 13 80 ⨁ 12 94 68 A6 = 82 BA 7B 26 
    W[7] = W[3] ⨁ W[6] = AC C1 07 BD ⨁ 82 BA 7B 26 = 2E 7B 7C 9B 
    

    所以,第一轮的密钥为45 64 71 B0 12 94 68 A6 82 BA 7B 26 2E 7B 7C 9B

    Java实现AES算法

    由于Java有自带的函数,因此可以直接调用

    首先生成密钥,密钥是SecretKey类型的对象

    static final String ALGORITHM = "AES";
    
    public static SecretKey generateKey() throws NoSuchAlgorithmException { // 生成密钥
    	KeyGenerator secretGenerator = KeyGenerator.getInstance(ALGORITHM);
    	SecureRandom secureRandom = new SecureRandom();
    	secretGenerator.init(secureRandom);
    	SecretKey secretKey = secretGenerator.generateKey();
    	return secretKey;
    }
    

    首先创建密钥生成器KeyGenerator对象,产生的是AES算法的密钥,因此传入参数AES。这里使用安全的随机数SecureRandom作为参数传入密钥生成器的init()函数中,最后调用密钥生成器的generateKey()方法产生密钥对象secretKey

    然后实现加密方法和解密方法

    static Charset charset = Charset.forName("UTF-8");
    public static byte[] encrypt(String content, SecretKey secretKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { // 加密
    	return aes(content.getBytes(charset),Cipher.ENCRYPT_MODE,secretKey);
    }
    
    public static String decrypt(byte[] contentArray, SecretKey secretKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { // 解密
    	byte[] result =  aes(contentArray,Cipher.DECRYPT_MODE,secretKey);
    	return new String(result,charset);
    }
    

    加密方法传入的是需要加密的明文content以及密钥;解密方法传入的是密文contentArray以及密钥

    最后实现aes函数

    private static byte[] aes(byte[] contentArray, int mode, SecretKey secretKey)
    		throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    	Cipher cipher = Cipher.getInstance(ALGORITHM);
    	cipher.init(mode, secretKey);
    	byte[] result = cipher.doFinal(contentArray);
    	return result;
    }
    

    完整代码如下:

    import java.nio.charset.Charset;
    import java.security.InvalidKeyException;
    import java.security.NoSuchAlgorithmException;
    import java.security.SecureRandom;
    
    import javax.crypto.BadPaddingException;
    import javax.crypto.Cipher;
    import javax.crypto.IllegalBlockSizeException;
    import javax.crypto.KeyGenerator;
    import javax.crypto.NoSuchPaddingException;
    import javax.crypto.SecretKey;
    
    public class Aes {
    
    	
    	static final String ALGORITHM = "AES";
    
    	public static SecretKey generateKey() throws NoSuchAlgorithmException { // 生成密钥
    		KeyGenerator secretGenerator = KeyGenerator.getInstance(ALGORITHM);
    		SecureRandom secureRandom = new SecureRandom();
    		secretGenerator.init(secureRandom);
    		SecretKey secretKey = secretGenerator.generateKey();
    		return secretKey;
    	}
    
    	static Charset charset = Charset.forName("UTF-8");
    	public static byte[] encrypt(String content, SecretKey secretKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { // 加密
    		return aes(content.getBytes(charset),Cipher.ENCRYPT_MODE,secretKey);
    	}
    
    	public static String decrypt(byte[] contentArray, SecretKey secretKey) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException { // 解密
    		byte[] result =  aes(contentArray,Cipher.DECRYPT_MODE,secretKey);
    		return new String(result,charset);
    	}
    
    	private static byte[] aes(byte[] contentArray, int mode, SecretKey secretKey)
    			throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
    		Cipher cipher = Cipher.getInstance(ALGORITHM);
    		cipher.init(mode, secretKey);
    		byte[] result = cipher.doFinal(contentArray);
    		return result;
    	}
    
    	public static void main(String[] args) {
    		String content = "你好,我很喜欢加密算法";
    		SecretKey secretKey;
    		try {
    			long timeStart = System.currentTimeMillis();
    			secretKey = generateKey();
    			byte[] encryptResult = encrypt(content, secretKey);
    			long timeEnd = System.currentTimeMillis();
    			System.out.println("加密后的结果为:" + new String(encryptResult,charset));
    			String decryptResult = decrypt(encryptResult,secretKey);
    			System.out.println("解密后的结果为:" + decryptResult);
    			System.out.println("加密用时:" + (timeEnd - timeStart));
    		} catch (NoSuchAlgorithmException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) {
    			e.printStackTrace();
    		}
    	}
    }
    

    运行GIF图如下所示:

    展开全文
  • AES加密算法java源代码

    热门讨论 2011-08-29 00:30:37
    AES加密算法java实现源代码。只有一个java源文件,非常简单。
  • AES加密算法 Java与Python跨平台实现

    千次阅读 2018-12-13 18:10:12
    AES加密算法 Java与Python跨平台实现什么是AESJava的实现Python的实现 什么是AES Note: 网上有很多实现代码但是鱼龙混杂,笔者摸索了半天,实现了AES加密文本跨平台的安全传输 这里以Python和Java为例,方案采用...

    AES加密算法 Java与Python跨平台实现

    什么是AES

    Note:

    1. 网上有很多实现代码但是鱼龙混杂,笔者摸索了半天,实现了AES加密文本跨平台的安全传输
    2. 这里以Python和Java为例,方案采用AES128+Base64.这里以Python和Java为例,方案采用AES128+Base64。

    AES的算法本身是跨平台的,只不过以下这些要素决定了跨平台不是那么简单:

    • 加密模式: ECB,CBC,CFB,OFB,CTR,XTS…
    • 密钥长度: 128, 256
    • iv向量(init vector): 需要与密钥同时设置
    • padding: NoPadding,ZeroPadding,PKCS5Padding,ISO10126Padding,ANSI X.923,SSL3Padding…
    • 密钥: 用于加解密的key
      参见: Github aes-cross

    Java的实现

    Note:

    1. Base64 需要第三方jar包 http://www.java2s.com/Code/Jar/a/Downloadaxis103jar.htm
    2. 注意padding与unpadding的方法
    import java.util.Arrays;
    import java.lang.Throwable;
    
    import javax.crypto.Cipher;
    import javax.crypto.spec.IvParameterSpec;
    import javax.crypto.spec.SecretKeySpec;
    
    import org.apache.axis.encoding.Base64;
    
    public class aesEncryption {
        private static final String CYPHER_MODE = "AES/CBC/NoPadding";
    
        public static byte[] encrypt(byte[] key, byte[] initVector, byte[] value) {
            try {
                IvParameterSpec iv = new IvParameterSpec(initVector);
                SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    
                Cipher cipher = Cipher.getInstance(CYPHER_MODE);
                cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
                int blockSize = cipher.getBlockSize();
                byte[] plaintext = padding(value, blockSize);
                return cipher.doFinal(plaintext);
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            return null;
        }
    
        public static byte[] decrypt(byte[] key, byte[] initVector, byte[] encrypted) {
            try {
                IvParameterSpec iv = new IvParameterSpec(initVector);
                SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    
                Cipher cipher = Cipher.getInstance(CYPHER_MODE);
                cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
    
                return unpadding(cipher.doFinal(encrypted));
            } catch (Exception ex) {
                ex.printStackTrace();
            }
    
            return null;
        }
    
        private static byte[] padding(byte[] value, int blockSize) {
            int plaintextLength = value.length;
            if (plaintextLength % blockSize != 0) {
                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
            }
            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(value, 0, plaintext, 0, value.length);
            return plaintext;
        }
    
        private static byte[] unpadding(byte[] bytes) {
            int i = bytes.length - 1;
            while (i >= 0 && bytes[i] == 0)
            {
                --i;
            }
    
            return Arrays.copyOf(bytes, i + 1);
        }
    
        public static void main(String[] args) {
            try {
                byte[] key = "keyskeyskeyskeys".getBytes();
                byte[] iv = "keyskeyskeyskeys".getBytes();
                byte[] content = "123".getBytes("utf-8");
                byte[] cyphertext = encrypt(key, iv, content);
                String b64 = Base64.encode(cyphertext);
                System.out.println(b64);
                byte[] de_b64 = decrypt(key, iv, Base64.decode(b64));
                String plaintext = new String(de_b64);
                System.out.println(plaintext);
            } catch (Throwable t) {
                t.printStackTrace();
            }
        }
    }
    

    Python的实现

    Note:

    1. key 和 iv 值要与之前的Java代码里分别
    2. 注意padding与unpadding的方法
    from Crypto.Cipher import AES
    import base64
    
    
    class AESEncrypt:
        def __init__(self, key, iv):
            self.key = key
            self.iv = iv
            self.mode = AES.MODE_CBC
    
        def encrypt(self, text):
            cryptor = AES.new(self.key, self.mode, self.key)
            length = AES.block_size
            text_pad = self.padding(length, text)
            ciphertext = cryptor.encrypt(text_pad)
            cryptedStr = str(base64.b64encode(ciphertext), encoding='utf-8')
            return cryptedStr
    
        def padding(self, length, text):
            count = len(text.encode('utf-8'))
            if count % length != 0:
                add = length - (count % length)
            else:
                add = 0
            text1 = text + ('\0' * add)
            return text1
    
        def decrypt(self, text):
            base_text = base64.b64decode(text)
            cryptor = AES.new(self.key, self.mode, self.key)
            plain_text = cryptor.decrypt(base_text)
            ne = plain_text.decode('utf-8').rstrip('\0')
            return ne
    
    
    if __name__ == '__main__':
        aes_encrypt = AESEncrypt(key='keyskeyskeyskeys', iv="keyskeyskeyskeys")  # 初始化key和IV
        text = '123'
        sign_data = aes_encrypt.encrypt(text)
        print(sign_data)
        data = aes_encrypt.decrypt(sign_data)
        print(data)
    

    结果

    明文:123
    密文:nUY/Ft988QAYJYbKh2pxyw==

    展开全文
  • [转]AES加密算法java代码实现

    千次阅读 2017-08-22 14:59:50
    AES加密 AES是一个对称密码,旨在取代DES成为广泛使用的标准。 一、AES的加密过程   二、AES的数据结构 加密解密算法的输入是一个128位分组。这些分组被描述成4×4的字节方阵,这个分组被复制到state数组...

    转自:http://www.cnblogs.com/block2016/p/5596676.html

    AES是一个对称密码,旨在取代DES成为广泛使用的标准。

    一、AES的加密过程

     

    二、AES的数据结构

    加密解密算法的输入是一个128位分组。这些分组被描述成4×4的字节方阵,这个分组被复制到state数组中,并在加密和解密的每一阶段都被修改。在字节方阵中,每一格都是一个字,包含了4字节。在矩阵中字是按列排序的。

     

     加密由N轮构成,轮数依赖于密钥长度:16字节密钥对应10轮,24字节密钥对应12轮,32字节对应14轮。

     

    三、加密解密的详细结构

    AES未使用Feistel结构。其前N-1轮由4个不同的变换组成:字节代替、行移位、列混淆和轮密钥加。最后一轮仅包含三个变换。而在第一轮前面有一个起始的单变换(轮密钥加),可以视为0轮。

      字节代替SubBytes):用一个S盒完成分组的字节到字节的代替。

      行移位ShiftRows):一个简单的置换。

      列混淆MixColumns):利用域GF(28)上的算术特性的一个代替。

      轮密钥加AddRoundKey):当前分组和扩展密钥的一部分进行按位异或XOR

     

    首尾使用轮密钥加的理由:若将其他不需要密钥的阶段放在首尾,在不知道密钥的情况下就能计算其逆,这就不能增加算法的安全性。

    加密原理:轮密钥加实际是一种Vernam密码形式,其本身不难被破解。另外三个阶段一起提供了混淆、扩散和非线性功能。这三个阶段没有涉及密钥,就它们自身而言,并未提供算法的安全性。然而,该算法经历一个分组的XOR加密(轮密钥加),再对该分组混淆扩散(其他三个阶段),再接着又是XOR加密,如此交替进行,这种方式非常有效非常安全。

    可逆原理:每个阶段均可逆。对字节代替、行移位和列混淆,在解密算法中用它们相对应的逆函数。轮密钥加的逆就是用同样的轮密钥和分组相异或,其原理就是ABB = A。和大多数分组密码一样,AES解密算法按逆序利用扩展密钥,然而其解密算法和加密算法并不一样,这是由AES的特定结构决定的。图5.3中加密和解密流程在纵向上是相反的,在每个水平点上,state数组在加密和解密函数中都是一样的。

     

    四、AES的变换函数

    1、字节代替变换

     

    字节代替变换是一个简单的查表操作。AES定义了一个S盒,它是由16×16个字节组成是矩阵,包含了8位所能表示的256个数的一个置换。State中每个字节按照如下方式映射为一个新的字节:把该字节的高4位作为行值,低4位作为列值,以这些数值为索引从S盒的对应位置取出元素作为输出。如,十六进制数{95}所对应的S盒行值是9,列值是5S盒中在此位置的值是{2A},相应的,{95}被映射为{2A}

    S盒的构造

    (1)按字节值的升序逐行初始化S盒(相当于每个值都代表了坐标)

    (2)把S盒的每个字节映射为它在有限域GF(28)中的逆

    (3)把S盒中的每个字节的8个构成位记为(b7,b6,b5,b4,b3,b2,b1,b0)。对S盒的每个字节的每个位作如下变换:

      bi’=b(i+4)mod8b(i+5)mod8b(i+6)mod8b(i+7)mod8ci          (5.1

      这里ci 是指值为{63}的字节c的第i位。

      AES标准用矩阵形式描述了这个变换:

       

    逆字节代替变换则采用逆S盒,

    S盒的构造

    (1)按字节值的升序逐行初始化S

    (2)利用式5.1的逆变换,该逆变换如下:

      bi’=b(i+2)mod8b(i+5)mod8b(i+7)mod8di          (5.3

      这里di 是指值为{05}的字节d的第i位。也可以用矩阵形式描述:

       

    3求其在GF(28)内的乘法逆

     

    可逆证明:

    令字节代替变换和逆字节代替变换中的矩阵分别为XY,常量cd的向量表示分别为CD。对于某个8位的向量B,式5.2变成了B’=XBC。我们需证明Y(XBC)D=B

     

    DES加密的S盒的区别

      1、AESS盒的原理是运用了GF(28)的乘法逆和矩阵的可逆运算来保证加密与解密过程的可逆性。DESS盒设计主要是为了确保非线性关系,并不需要可逆。因而在设计理念上有极大的不同。

      2、AESS盒与DESS盒形式上差别也很大,AESS盒输入和输出的位数相同,均为128位,大小为16×16的字节矩阵,且只有1组;而DESS盒输入6位,输出只有4位,大小是4×16的位矩阵,并且有8组。在输入的坐标选择规定上亦有不同。

     

    2、行移位变换

    操作本身很简单,将state数组的第一行保持不变,第二行循环左移一个字节,第三行循环左移两个字节,第四行循环左移三个字节。

     

    其逆变换则将移位的几行执行相反方向的移位操作即可。

    基本原理

    由于轮密钥加、字节代替变换都是逐列地作用在state数组上,每一轮的行移位变换将会打乱列排列,使得保密性得到很大的提升。

    3、列混淆变换

    列混淆变换实际上是使用乘法矩阵(注意:其运算中涉及的加法和乘法都是定义在GF(28)上的加法和乘法,目的就是为了确保运算结果不会溢出定义域),可用以下式子描述。

     

    逆向列混淆变换可由如下矩阵乘法定义

     

    其可逆性可以简单运算得到证明

    基本原理

    5.3中矩阵的系数是基于码字间有最大距离的线性编码,这使得在每列的所有字节中有良好的混淆性。列混淆变换和行移位变换使得经过几轮变换后,所有的输入位和所有的输出位相关。

    此外,列混淆变换的系数,即{01}{02}{03}是基于算法实现角度考虑的。不过,逆向列混淆变换的系数则更加难以实现,然而加密被视为比解密更重要,因为:

      1、对于CFBOFB密码模式,仅用到加密算法

      2、和任何其他分组密码一样,AES能用于构造消息验证码,这仅仅用到了加密过程。

     

    4、轮密钥加变换

    这个比较简单,没有太多好说的,密钥扩展的复杂性是确保算法安全性的重要部分。

     

    以下是描述单轮AES的另一个视角,强调各变换的机制和输入。

     

     

     

    五、AES的密钥扩展

    AES密钥扩展算法的输入值是4个字(16字节),输出值是一个由44个字组成(176字节)的一维线性数组。以下伪码描述了这个扩展:

      KeyExpansion(byte key[16], word w[44]){

        word temp

        for(i=0; i<4; i++)  //将输入的密钥直接复制到扩展密钥数组的前四个字

          w[i]=word(key[4*i],key[4*i+1],key[4*i+2],key[4*i+3]);

        temp = w[i-1];

        if(i mod 4 == 0)  //w数组下标为4的倍数的元素采用更复杂的函数来计算

          temp = SubWord(RotWord(temp))Rcon[i/4];

        w[i] = w[i-4] + temp; //每一个新增的字w[i]依赖于w[i-1] w[i-4] 

      }

      RotWord的功能是字循环,即使一个字的4个字节循环左移1个字节。

      SubWord是利用S盒对输入字的每个字节进行字节代替。

      Rcon[i]是轮常量,代表一个字,这个字最右边三个字节总是0,因此字与Rcon异或,其结果只是与该字最左边的那个字节相异或。每一轮的轮常量都不相同,其定义为

      Rcon[i] = (RC[i],0,0,0),其中RC[1] = 1RC[i] = 2•RC[i-1] 乘法是定义在域GF(28)上的。

      RC[i]的值按照十六进制表示为

     

    轮常量取不同值就是为了消除不同轮密钥产生方式上的对称性或相似性。

     

    密钥扩展算法的设计规范:

    1、找到密钥或轮密钥的部分位不足以计算出轮密钥的其他位;

    2、它是一个可逆的变换(即知道扩展密钥中任何连续的Nk个字能够重新产生整个扩展密钥,Nk是构成密钥所需的字数);

    3、能够在各种处理器上有效地执行;

    4、使用轮常量消除对称性;

    5、将密钥差异性扩散到轮密钥中的能力,即密钥的每个位能影响轮密钥的许多位;

    6、足够的非线性以防止轮密钥的差异完全由密钥的差异所决定。

     

    改进--等价的逆算法

    上文所述的标准解密流程与标准加密流程并不完全一致,加密每一轮的流程是:字节代替-->行移位-->列混淆-->轮密加。而解密每一轮的流程是:逆向行移位-->逆向字节代替-->轮密加-->逆向列混淆。

    可以对解密构成进行改进,使得解密流程与加密流程等效。

    1、交换逆向行移位和逆向字节代替:

    由于逆向行移位并不影响state数组中字节的内容,而逆向字节代替也不会影响state数组中字节的位置,因而两者可以交换顺序而不影响解密。

    2、交换轮密钥加和逆向列混淆:

    这两种操作均不会改变state中字节的顺序,给定状态Si和给定轮密钥wi,可证明

    逆向列混淆(Siwi)= [逆向列混淆(Si)][逆向列混淆(wi)]

    这个等式显然是正确的,因而如果要改变这两种操作的顺序,则必须改进逆向列混淆的操作,即先对轮密钥应用逆向列混淆(注意,无需对首尾的轮密钥应用逆向列混淆)。最终,改进后的解密流程如下图:

     


    加密代码实现:

    public static byte[] decrypt(byte[] content, String password) {  
            try {  
                     KeyGenerator kgen = KeyGenerator.getInstance("AES");  
                     kgen.init(128, new SecureRandom(password.getBytes()));  
                     SecretKey secretKey = kgen.generateKey();  
                     byte[] enCodeFormat = secretKey.getEncoded();  
                     SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");              
                     Cipher cipher = Cipher.getInstance("AES");// 创建密码器  
                    cipher.init(Cipher.DECRYPT_MODE, key);// 初始化  
                    byte[] result = cipher.doFinal(content);  
                    return result; // 加密  
            } 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加密和Base64加密通过这些算法得出的结果均是字节码但是我程序中使用一个通讯接口其接受的参数类型为String。所以在发送时需要转换为String

            对于java来说,byte只能表示有符号的数据即范围为-128~127,所以对于编码后如果原本字节流中的信息有大于127的话将其转换成String类型发送的时候再转换为byte[]会出现与原始字节码不一致的现象。

            因为在java中如果找不到合适的字符的话默认会用'?'代替如对于0xC9,很显然无法表示成字符所以在进行byte[]->String->byte[]的时候就会变成0x3F('?')


    此时可以通过字符编码的方式来解决在进行byte[]->String的转换时利用"new String(byteArray, "ISO-8859-1");"得到String。在进行String->byte[]的时候再通过pkt.getBytes("ISO-8859-1")得到原始byte[],这样数据就不会出现错误。



    展开全文
  • 主要介绍了Java实现的对称加密算法AES,结合实例形式分析了对称加密算法AES的定义、特点、用法及使用场景,需要的朋友可以参考下
  • 本文就简单介绍如何通过JAVA实现AES加密: /** * 测试AES加密和解密 * @param args */ public static void main(String[] args) { /**数据初始化**/ String content = "http://www.mbaike.net"; String...
  • 主要介绍了java实现的AES加密算法,结合完整实例形式分析了AES加密类的实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
  • android AES 加密算法

    2014-12-29 09:37:41
    android和JAVAAES加密算法,从自己的项目中取出来的,分享给有需要的机油
  • aes加密算法java代码实现

    千次阅读 2015-02-13 18:08:39
    public class Aes { public enum KeySize{ Bits128(4,10),Bits192(6,12),Bits256(8,14); /**以字为单位的种子密钥长度,16bytes=1word=128bits*/ private int nk; /**轮密钥的次数*/ private int
  • JavaAES加密算法,亲测可用
  • AES加密算法java实现

    2019-07-23 18:18:38
    AES加密算法是密码学中的高级加密标准,该加密算法采用对称分组密码体制,密钥长度的最少支持为128、192、256,分组长度128位,算法应易于各种硬件和软件实现。这种加密算法是美国联邦政府采用的区块加密标准,这个...
  • C# JAVA nodejs通用的AES加密解密算法,考虑到实际使用过程中由于客户端和服务端使用的语言不一样而又需要对数据进行加密和解密的情况,特此总结了C# JAVA nodejs通用的AES加密解密算法,供需要者参考。
  • JAVA AES 加密算法

    2020-08-29 17:17:53
    JAVA AES 加密算法 javax.crypto.Cipher AES/ECB/PKCS5Padding
  • 湖北工业大学应用密码学期末课程设计,我做的是AES算法java实现对文档的保护。做的一个应用。
  • DES算法为密码体制中的对称密码体制,是一个分组加密算法,典型的DES以64位为分组对数据加密,加密和解密用的是同一个算法。 这里以Java代码实现DES算法。
  • Java AES128加密解密

    2019-01-19 20:53:59
    Java AES128加密解密 示例源码(AES-ECB-PKCS7Padding)
  • java和js实现aes加密解密,对重要信息进行加密传输,使得java、JavaScript、android、ios一致
  • 自己在项目开发中有需要用到AES,但都没有直接能用的,所以封装了相应的类。同时,提供我用于测试的测试工程。实际使用中,只需要使用其中的AESAlg.java文件即可,希望能帮到各位。工程运行结果如下: 密文:[B@57fa...
  • 实现功能 已知明文为0123456789ABCDEF的ASCII码表示的128比特 * 密钥是0101101100001110的12次重复构成的192比特密钥 * 编写AES的加解密程序对明文进行加密并进行解密验证 1.程序结构 2.运行结果 源代码 <1.AESclass...
  • AES/DES 对称加密算法

    2018-12-25 14:04:55
    DES、AES对称加密算法,之前从网上找的,但是在MAC上运行发现每次加密出来的结果都不一样,后来查了一些博客,最后确认是SecureRandom的随机算法问题,需要设置setSeed.
  • 这个是我之前在网上看到一个大神做的基于Java语言实现AES算法加密解密文件的应用,希望对于一些有志于密码学同学有点用处。zip文件包括AES算法原理以及详解还有实现的源代码(Eclipse直接导入使用就好)
  • AES对称加密java工具类

    2020-12-30 19:48:10
    适用于java开发者使用,用于对称加密的数据。进行加密
  • aes加密算法 五种模式

    2013-06-24 23:59:11
    使用ECB,CBC,CFB,OFB,CTR五种模式进行AES加密解密
  • AES加密算法是对称加密算法,其不同于MD5等摘要算法,其是可以进行解密,并还原为原始密文的。其经过10-14轮加密混淆步骤,因此如果仅仅从加密后信息来看,是很难被攻击的。 重要的步骤如下: 字节替代 行移位 列...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,725
精华内容 7,490
关键字:

aes加密算法java

java 订阅