本文重点在于如何在JAVA和Python中使用AES,以及相关的重要概念,而不是专门讲AES算法原理。
AES作为一个块加密算法 [block cipher],每次加密的明文大小固定为128bit,所以明文比较长的时候需要先分组再加密然后整合,这个过程中就会出现两个重要的因素:模式 和 填充方式。
1. 模式
分组密码工作模式,常用的包含ECB,CBC,OFB,CFB和CTR,详见 Block_cipher_mode_of_operation
1)ECB模式作为最简单的工作模式,直接将明文分组,每组分别加密,每个分组独立且前后文无关。
2)CBC模式,将明文分组与前一个密文分组进行XOR运算,然后再进行加密。每个分组的加解密都依赖于前一个分组。而第一个分组没有前一个分组,因此需要一个初始化向量 IV。
3)其他模式不再详述,ECB模式因为其简洁性(不需要额外的初始化向量IV)仍然被广泛使用,但是已经被认为是不安全的工作模式,具体原因见上文引用的wiki,为了保证传输信息的安全性,CBC目前是个推荐的选择,而且建议每次加密使用不同的 Key 和 IV 。
2. 填充方式
鉴于明文长度随机,分组之后,最后一个组往往需要补齐。
填充方式很多,详见 Padding (cryptography)
以下是在Java中常用的 PKCS7, 它是基于字节的填充方案 [Byte padding],其特点为:
1)填充的都是相同的字节
2)该字节的值,就是要填充的字节的个数
举例,
假定加密块长度要求为 8 byte,数据长度为 1 byte,那么需要填充7个byte,每个byte值为0x07
数据: FF
PKCS7 填充: FF 07 07 07 07 07 07 07
如果明文正好被整除了,需要增加一个完整的填充块,方便解密时判断最后一个字节是消息字节还是填充字节。
PKCS7支持长度小于256字节的加密块,而Java中经常出现的是PKCS5,PKCS5可以认为是PKCS7的一个特例,只处理8字节的加密块,理论上来说PKCS5是不适用于AES加密的,但是JCA (Java Cryptography Architecture) 标准中却只有PKCS5,这个可以认为是历史原因,实际上在加密块大于8字节时,PKCS5内部就用PKCS7方式填充。
3. 关于秘钥Key,长度可以是 128, 192 和 256 bits(注意加密块始终是 128 bits),Java默认只支持 128 bits,如果需要支持更长的key,需要添加扩展包 Java Cryptography Extension (JCE)。
4. Java中加密和解密的流程
创建Cipher实例 -> 用key初始化 -> 执行加解密,分组的操作只需要在创建实例时指定模式即可,不需要手动处理
以 CBC 模式加密为例
public byte[] encryptCBCMode(String key, String vector, String plainText) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException { IvParameterSpec iv = new IvParameterSpec(vector.getBytes(StandardCharsets.UTF_8)); SecretKey keySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING"); cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv); return cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8)); }
解密时将 Cipher.ENCRYPT_MODE 替换为 Cipher.DECRYPT_MODE。
5. Python中加密和解密的流程
使用 cryptography 库,和Java流程类似,同样以 CBC 模式为例
def encrypt_cbc_mode(key, iv, plain_bytes): backend = default_backend() cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=backend) encryptor = cipher.encryptor() # add pkcs#7 padding before encrypt padder = padding.PKCS7(128).padder() padded_data = padder.update(plain_bytes) + padder.finalize() return encryptor.update(padded_data) + encryptor.finalize()
更多代码可以参考 Information-Security
相关推荐
基于C++的AES加密和解密代码,请用MFC工程打开——VS2010以上版本
1.版本:matlab2019a,不会运行可私信 2.领域:基础教程 3.内容:matlab实现AES加密和解密算法 4.适合人群:本科,硕士等教研学习使用
* 测试AES加密和解密 * @param args */ public static void main(String[] args) { /**数据初始化**/ String content = "http://www.mbaike.net"; String password = "1234567890"; /**加密(1)**/...
AES加密和解密的源码事例,其它没什么可描述的。
Qt自身没有对应的对称加密算法,这里提供一个加密实现,拿来就能用
AES加密和解密算法的MATLAB实现算法,经过验证能够实现其功能,很值得大家来学习! AES_matlab\add_round_key.m AES_matlab\aes_demo.m AES_matlab\aes_init.m AES_matlab\aff_trans.m AES_matlab\cipher.m AES...
本篇文章主要介绍了android使用AES加密和解密文件实例代码,非常具有实用价值,需要的朋友可以参考下
1.采用秘钥为16位长度的加密字符 2.加密算法为AES/ECB/PKCS5Padding 3.解决加解密乱码问题 4.完整的线上可运行代码及各方法及步骤注释 5.无任何插件,java环境直接运行
AES加密和解密的工具类库文件,支持C#引用。(实测兼容所有版本,靠谱)
用C语言实现的AES加密解密算法,用C语言实现的AES加密解密算法
AES加密和解密源码,Delphi源码实例``
主要介绍了Java使用AES加密和解密的实例详解的相关资料,需要的朋友可以参考下
AES加密和解密-CryptoJS和Java AES(Advanced Encryption Standard,高级加密标准)是一种对称加密算法,加密和解密使用相同的密钥 CryptoJS:https://github.com/brix/crypto-js
AES加密与解密源代码,环境:VS2008 .Net Framework 3.5
(原创)android使用AES加密和解密文件,博客链接地址:http://blog.csdn.net/lnn368/article/details/52712407#comments
1. 在深入理解AES加密/解密算法理论的基础上,设计一个AES加密/解密软件系统; 2. 完成CBC和ECB模式加密解密
MCrypt 明文和密文之间的加密转换。
Delphi实现AES加密和解密, 同Java加解密兼容
AES加密和解密PHP封装类,php代码加密利器,非常实用,可以用在登录时用户名与密码优化。