JAVA AES加密使用

一.前言

AES(Advanced Encryption Standard),高级加密标准,是美国政府用于替换DES的一种加密算法标准,Java SDK中包含了部分AES的实现,但javadoc对于算法的描述非常少,本文将解释Java AES实现的使用和原理。

二.示例代码

AesECB.java
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
importjavax.crypto.Cipher;
importjavax.crypto.spec.SecretKeySpec;
 
public classAesECB{
     public static byte[]Encrypt( byte[]text, byte[]key) throwsException{
        SecretKeySpec aesKey= newSecretKeySpec(key, "AES");
 
        Cipher cipher=Cipher.getInstance( "AES/ECB/PKCS5Padding"); // default, same as "AES"
         // Cipher cipher = Cipher.getInstance("AES"); // same as above
        cipher.init(Cipher.ENCRYPT_MODE,aesKey);
         returncipher.doFinal(text);
    }
 
     public static byte[]Decrypt( byte[]text, byte[]key) throwsException{
        SecretKeySpec aesKey= newSecretKeySpec(key, "AES");
 
        Cipher cipher=Cipher.getInstance( "AES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, aesKey);
         returncipher.doFinal(text);
    }
 
     public static Stringbytes2hex( byte[]bytes){
        StringBuilder sb= newStringBuilder();
         for( inti= 0;i<bytes.length;i++){
             Stringtemp=( Integer.toHexString(bytes[i]& 0XFF));
             if(temp.length()== 1){
                temp= "0"+temp;
            }
            sb.append(temp);
            sb.append( " ");
        }
         returnsb.toString().toUpperCase();
    }
 
     public static voidmain( String[]args){
         try{
             Stringkey=args[ 0];
             Stringtext=args[ 1];
 
            System.out.printf( "text   : %s\n",bytes2hex(text.getBytes()));
 
             byte[]enc=AesECB.Encrypt(text.getBytes(),key.getBytes());
            System.out.printf( "encrypt: %s\n",bytes2hex(enc));
 
             byte[]dec=   AesECB.Decrypt(enc,key.getBytes());
            System.out.printf( "decrypt: %s\n",bytes2hex(dec));
        } catch(Exceptione){
            e.printStackTrace();
        }
    }
}

三.代码分析

JDK AES加密主要是几个步骤:

1.key变换

将传入的明文key做变换,AES的key固定为128bit,但变换后的key为加密位数的一倍,128bit的加密变换后key为256bit。注意加密和解密的key变换不一样。

2.加密解密

选择加密的模式和补齐填充方法生成加密实例,加密得到密文。

四.密码块工作模式

块密码工作模式(Block cipher mode of operation),是对于按块处理密码的加密方式的一种扩充,不仅仅适用于AES,包括DES, RSA等加密方法同样适用。

名称

英文

全名

方法

优点

缺点

ECB

Electronic codebook

电子密码本

每块独立加密

1.分块可以并行处理

1.同样的原文得到相同的密文,容易被攻击

CBC

Cipher-block chaining

密码分组链接

每块加密依赖于前一块的密文

1.同样的原文得到不同的密文
2.原文微小改动影响后面全部密文

1.加密需要串行处理
2.误差传递

PCBC

Propagating cipher-block chaining

填充密码块链接

CBC的扩种,较少使用

1.同样的原文得到不同的密文
2.互换两个邻接的密文块不会对后续块的解密造成影响

1.加密需要串行处理

CFB

Cipher feedback

密文反馈

 

 

 

OFB

Output feedback

输出反馈模式

加密后密文与原文异或XOR

 

1.能够对密文进行校验

CTR

Counter mode

计数器模式

增加一个序列函数对所有密文快做XOR

 

 

五.填充

填充(Padding),是对需要按块处理的数据,当数据长度不符合块处理需求时,按照一定方法填充满块长的一种规则。

名称

方法

示例

Zero padding

最常见的方式,全填充0x00

AA AA AA AA 00 00 00 00

ANSI X.923

Zero的改进,最后一个字节为填充字节个数

AA AA AA AA 00 00 00 04

ISO 10126

随机填充

AA AA AA AA 81 A6 23 04

PKCS7

ANSI X.923的变体
填充1个字符就全0x01
填充2个字符就全0x02
不需要填充就增加一个块,填充块长度,块长为8就填充0x08,块长为16就填充0x10

AA AA AA AA AA AA AA 01
AA AA AA AA 04 04 04 04
AA AA AA AA AA AA AA AA08 08 08 08 08 08 08 08

ISO/IEC 7816-4

以0x80开始作为填充开始标记,后续全填充0x00

AA AA AA AA AA AA AA 80
AA AA AA AA 80 00 00 00

六.JDK AES实现

1.实现支持

AES理论上支持128,192,256三种长度的密钥,几乎全部密码块工作模式和填充方法,但JDK 7中只实现如下四种AES加密算法:

(1)AES/CBC/NoPadding (128)
(2)AES/CBC/PKCS5Padding (128)
(3)AES/ECB/NoPadding (128)
(4)AES/ECB/PKCS5Padding (128)

2.使用须知

(1)缺省模式和填充为"AES/ECB/PKCS5Padding",Cipher.getInstance("AES")与Cipher.getInstance("AES/ECB/PKCS5Padding")等效。

(2)JDK的PKCS5Padding实际是上述的PKCS7的实现。

(3)由于AES是按照16Byte为块进行处理,对于NoPadding而言,如果需要加密的原文长度不是16Byte的倍数,将无法处理抛出异常,其实是由用户自己选择Padding的算法。密文则必然是16Byte的倍数,否则密文肯定异常。

(4)如果加密为PKCS5Padding,解密可以选择NoPadding,也能解密成功,内容为原文加上PKCS5Padding之后的结果。

(5)如果原文最后一个字符为>=0x00&&<=0x10的内容,PKCS5Padding的解密将会出现异常,要么是符合PKCS5Padding,最后的内容被删除,要么不符合,则解密失败抛出异常。对此有两种思路,一是原文通过Base64编码为可见字符,二是原文自带长度使用NoPadding解密。

七.参考

(1)AES(Wiki)
(2)Block cipher mode of operation(Wiki)
(3)块密码的工作模式(Wiki)
(4)Padding(Wiki)
(5)PKCS(Wiki)
(6)JAVA 7 Cipher

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值