aes高级aes加密 密钥标准中的分组大小是固定的,但是密钥长度可以有多个选择

128位分组对称加密算法:AES_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
128位分组对称加密算法:AES
上传于||暂无简介
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
下载文档到电脑,查找使用更方便
还剩4页未读,继续阅读
你可能喜欢1228人阅读
最近在重构之前写的HTTP代理,这个代理是由代理客户端和代理服务端组成的,二者之前使用SSL保证通信内容不会受到中间人(MITM)攻击。而新的实现打算移除SSL,因为SSL握手的开销过大,尤其是客户端与服务端之间隔了个太平洋,另一方面本月中旬的时候Google安全团队证明了SSLv3已经是不安全的了,需要升级到TLS,但TLS同样有握手的开销。在新的实现中客户端和服务端之间的通信将使用AES加密,每个连接使用独立的随机生成的密钥和初始化向量。客户端在向服务端发起连接后使用非对称加密算法RSA将密钥和初始化向量加密后发送给服务端,服务端在收到密钥和初始化向量后就全部使用AES加密通信,这保证了通信内容不会被窃听(但可能被篡改)。
本文作为备忘记录了学习分组加密模式的一些体会和理解。AES作为一种分组加密算法为了适应不同的安全性要求和传输需求允许在多种不同的加密模式下工作,本文只涉及到ECB、CBC、CFB和OFB四种加密模式,以OpenSSL开源库和C++语言作为描述。
高级加密标准AES
高级加密标准(Advanced Encryption Standard: AES)是美国国家标准与技术研究院(NIST)在2001年建立了电子数据的加密规范。它是一种分组加密标准,每个加密块大小为128位,允许的密钥长度为128、192和256位。
下面列出了AES在OpenSSL中最主要的函数
int AES_set_encrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);int AES_set_decrypt_key(const unsigned char *userKey, const int bits, AES_KEY *key);void AES_encrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);void AES_decrypt(const unsigned char *in, unsigned char *out, const AES_KEY *key);
这些函数声明在&openssl/aes.h&文件中,其中AES_set_encryp_key和AES_set_decrypt_key用来为加密器和解密器设置密钥,AES_encrypt用来加密单块数据(128位),AES_decrypt用来解密单块数据。OpenSSL中对ECB、CBC、CFB和OFB等加密模式都是对这两个函数的封装。
为了描述方便引入两个C++函数from_hex_string和to_hex_string前者用来将16进制字符串转为对应的二进制向量,后者用来将二进制向量序列化成16进制的字符串。
std::vector&unsigned char& from_hex_string(const std::string& hex);std::string to_hex_string(const std::vector&unsigned char&& vec);
一个简单的使用AES加密一个数据块并解密的例子如下
123456789101112131415161718
auto key = from_hex_string(&2B7E151628AED2A6ABFF3C&);auto plan_vec = from_hex_string(&6BC1BEE22E409F96E93D7EA&);std::vector&unsigned char& cipher_vec(16);std::vector&unsigned char& decrypt_vec(16);AES_KEY aes_enc_AES_set_encrypt_key(key.data(), 128, &aes_enc_ctx);AES_encrypt(plan_vec.data(), cipher_vec.data(), &aes_enc_ctx);AES_KEY aes_dec_AES_set_decrypt_key(key.data(), 128, &aes_dec_ctx);AES_decrypt(cipher_vec.data(), decrypt_vec.data(), &aes_dec_ctx);std::cout && &plan
: & && to_hex_string(plan_vec) && std::std::cout && &cipher : & && to_hex_string(cipher_vec) && std::std::cout && &decrypt: & && to_hex_string(decrypt_vec) && std::
第8行设置128位密钥2B7E151628AED2A6ABFF3C,第9行使用AES_encrypt对128位的数据块6BC1BEE22E409F96E93D7EA进行加密,第13、14行使用与加密时相同的密钥解密。
: 6BC1BEE22E409F96E93D7EA
cipher : 3AD77BB40D7A3660A89ECAF32466EF97
decrypt: 6BC1BEE22E409F96E93D7EA
ECB模式(电子密码本模式:Electronic codebook)
ECB是最简单的块密码加密模式,加密前根据加密块大小(如AES为128位)分成若干块,之后将每块使用相同的密钥单独加密,解密同理。
ECB加密流程(图片来自维基百科)
ECB解密流程(图片来自维基百科)
OpenSSL中针对ECB模式,有个名为AES_ecb_encrypt的函数,它的实现是这样的(其实就是AES_encrypt和AES_decrypt套了个马甲)。
void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,const AES_KEY *key, const int enc) {
assert(in && out && key);
assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
if (AES_ENCRYPT == enc)
AES_encrypt(in, out, key);
AES_decrypt(in, out, key);}
ECB模式由于每块数据的加密是独立的因此加密和解密都可以并行计算,ECB模式最大的缺点是相同的明文块会被加密成相同的密文块,这种方法在某些环境下不能提供严格的数据保密性。
CBC模式(密码分组链接:Cipher-block chaining)
CBC模式对于每个待加密的密码块在加密前会先与前一个密码块的密文异或然后再用加密器加密。第一个明文块与一个叫初始化向量的数据块异或。
CBC加密流程(图片来自维基百科)
CBC解密流程(图片来自维基百科)
OpenSSL中用于AES-CBC加密的函数是AES_cbc_encrypt
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, const int enc);
各参数的含义
in:待加密的明文数据out:密文输出缓冲区length:明文数据长度(字节)key:当enc为AES_ENCRYPT时此参数要用AES_set_encrypt_key初始化,当enc为AES_DECRYPT时要用AES_set_decrypt_key初始化enc:加密AES_ENCRYPT 解密AES_DECRYPT
AES_cbc_encrypt允许length不是16(128位)的整数倍,不足的部分会用0填充,输出总是16的整数倍。完成加密或解密后会更新初始化向量IV。举例如下
1234567891011121314151617181920
auto key = from_hex_string(&2B7E151628AED2A6ABFF3C&);auto i_vec = from_hex_string(&B0C0D0E0F&);auto plan_vec = from_hex_string(&6B&);AES_KEY aes_enc_AES_set_encrypt_key(key.data(), 128, &aes_enc_ctx);std::vector&unsigned char& cipher_vec(16);AES_cbc_encrypt(plan_vec.data(), cipher_vec.data(), 1, &aes_enc_ctx, i_vec.data(), AES_ENCRYPT);std::cout && &plan
: & && to_hex_string(plan_vec) && std::std::cout && &cipher : & && to_hex_string(cipher_vec) && std::std::cout && &ivec
: & && to_hex_string(i_vec) && std::AES_KEY aes_dec_AES_set_decrypt_key(key.data(), 128, &aes_dec_ctx);std::vector&unsigned char& decrypt_vec(16);i_vec = from_hex_string(&B0C0D0E0F&);AES_cbc_encrypt(cipher_vec.data(), decrypt_vec.data(), 16, &aes_dec_ctx, i_vec.data(), AES_DECRYPT);std::cout && &decrypt: & && to_hex_string(decrypt_vec) && std::
cipher : F05F94CA1BC35A4BCA72ED
: F05F94CA1BC35A4BCA72ED
decrypt: 6B000000
CBC模式相比ECB有更高的保密性,但由于对每个数据块的加密依赖与前一个数据块的加密所以加密无法并行。与ECB一样在加密前需要对数据进行填充,不是很适合对流数据进行加密。
CFB模式(密文反馈:Cipher feedback)
与ECB和CBC模式只能够加密块数据不同,CFB能够将块密文(Block Cipher)转换为流密文(Stream Cipher)。
CFB加密流程(图片来自维基百科)
CFB解密流程(图片来自维基百科)
注意:CFB、OFB和CTR模式中解密也都是用的加密器而非解密器。
CFB的加密工作分为两部分:
将一前段加密得到的密文再加密;将第1步加密得到的数据与当前段的明文异或。
由于加密流程和解密流程中被块加密器加密的数据是前一段密文,因此即使明文数据的长度不是加密块大小的整数倍也是不需要填充的,这保证了数据长度在加密前后是相同的。
这种模式称为128位的CFB模式(又称CFB128)在OpenSSL中用来进行这种加解密的函数为AES_cfb128_encrypt
void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, int *num, const int enc)
这个函数中大部分的参数都和AES_cbc_encrypt相同,除了
key: 无论是加密还是解密这个key都要用AES_set_encrypt_key初始化num: 用于返回自上次对前一个密文块加密后到函数返回为止已处理的明文数据长度(字节)见下文分析enc: 加密AES_ENCRYPT 解密AES_DECRYPT
刚开始用这个函数的时候一直疑惑于num这个参数,并且Google了下也没找到答案,就直接去源码中看实现了。
1234567891011
The extra state information to record how much of the * 128bit block we have used is contained in * */void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
size_t length, const AES_KEY *key,
unsigned char *ivec, int *num, const int enc) {
CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);}
上面这段代码注释中就是在讲这个参数的用途,但看了还是不明觉厉。下面是CRYPTO_cfb128_encrypt的实现(去掉了无关紧要的代码)。
123456789101112131415161718192021222324252627282930313233
void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out,
size_t len, const void *key,
unsigned char ivec[16], int *num,
int enc, block128_f block){
unsigned int
size_t l = 0;
assert(in && out && key && ivec && num);
if (enc) {
while (l&len) {
if (n == 0) {
(*block)(ivec, ivec, key);
out[l] = ivec[n] ^= in[l];
++l;
n = (n+1) % 16;
while (l&len) {
unsigned char
if (n == 0) {
(*block)(ivec, ivec, key);
out[l] = ivec[n] ^ (c = in[l]); ivec[n] =
++l;
n = (n+1) % 16;
看到这段代码就很清楚了,128位的CFB是对前一段数据的密文用块加密器加密后保存在IV中,之后用这128位数据与后面到来的128位数据异或,num用来记录自上次调用加密器后已经处理的数据长度(字节),当num重新变为0的时候就会再调用加密器,即每处理128位调用一次加密器。
12345678910111213141516171819202122
auto key = from_hex_string(&2B7E151628AED2A6ABFF3C&);auto i_vec = from_hex_string(&B0C0D0E0F&);auto plan_vec = from_hex_string(&6BC1BEE22E409F96E93D7E&); AES_KEY aes_enc_AES_set_encrypt_key(key.data(), 128, &aes_enc_ctx);std::vector&unsigned char& cipher_vec(plan_vec.size());int num = 0;for(std::size_t index = 0; index & plan_vec.size(); ++index) {
AES_cfb128_encrypt(&plan_vec[index], &cipher_vec[index], 1, &aes_enc_ctx, i_vec.data(), &num, AES_ENCRYPT);
std::cout && &i_vec: & && to_hex_string(i_vec) && & num: & && num && std::}std::cout && &cipher : & && to_hex_string(cipher_vec) && std::AES_KEY aes_dec_AES_set_encrypt_key(key.data(), 128, &aes_dec_ctx);std::vector&unsigned char& decrypt_vec(cipher_vec.size());i_vec = from_hex_string(&B0C0D0E0F&); num = 0;AES_cfb128_encrypt(cipher_vec.data(), decrypt_vec.data(), cipher_vec.size(), &aes_dec_ctx, i_vec.data(), &num, AES_DECRYPT);std::cout && &decrypt: & && to_hex_string(decrypt_vec) && std::
i_vec: 3BFE67CC996D32B6DA0937E99BAFEC60 num: 1
i_vec: 3B3F67CC996D32B6DA0937E99BAFEC60 num: 2
i_vec: 3B3FD9CC996D32B6DA0937E99BAFEC60 num: 3
i_vec: 3B3FD92E996D32B6DA0937E99BAFEC60 num: 4
i_vec: 3B3FD92EB76D32B6DA0937E99BAFEC60 num: 5
i_vec: 3B3FD92EB72D32B6DA0937E99BAFEC60 num: 6
i_vec: 3B3FD92EB72DADB6DA0937E99BAFEC60 num: 7
i_vec: 3B3FD92EB72DAD20DA0937E99BAFEC60 num: 8
i_vec: 3B3FD92EB72DADBAFEC60 num: 9
i_vec: 3B3FD92EB72DADBAFEC60 num: 10
i_vec: 3B3FD92EB72DADBAFEC60 num: 11
i_vec: 3B3FD92EB72DADBAFEC60 num: 12
i_vec: 3B3FD92EB72DADE8AFEC60 num: 13
i_vec: 3B3FD92EB72DADE83CEC60 num: 14
i_vec: 3B3FD92EB72DADE83CFB60 num: 15
i_vec: 3B3FD92EB72DADE83CFB4A num: 0
i_vec: 348BCF60BEB005ADAB36BDA num: 1
cipher : 3B3FD92EB72DADE83CFB4A34
decrypt: 6BC1BEE22E409F96E93D7E
CFB128是每处理128位数据调用一次加密器,此外还有两种常用的CFB是CFB8和CFB1,前者每处理8位调用一次加密器,后者每处理1位调用1次加密器,就运算量来讲CFB1是CFB8的8倍,是CFB128的128倍。对于CFB8和CFB1需要将IV作为移位寄存器。
CFB8的加密流程
使用加密器加密IV的数据;将明文的最高8位与IV的最高8位异或得到8位密文;将IV数据左移8位,最低8位用刚刚计算得到的8位密文补上。
重复1到3。
CFB1的加密流程
使用加密器加密IV的数据;将明文的最高1位与IV的最高1位异或得到1位密文;将IV数据左移1位,最低1位用刚刚计算得到的1位密文补上。
重复1到3。
OpenSSL中AES_cfb8_encrypt和AES_cfb1_encrypt分别用来加解密CFB8和CFB1。这两个函数的参数和AES_cfb128_encrypt完全一样,但num和length含义略有不同。
num: 应总是为0 否则会触发断言length: CFB8单位为byte CFB1单位为bit
CFB模式非常适合对流数据进行加密,解密可以并行计算。
OFB模式(输出反馈:Output feedback)
OFB是先用块加密器生成密钥流(Keystream),然后再将密钥流与明文流异或得到密文流,解密是先用块加密器生成密钥流,再将密钥流与密文流异或得到明文,由于异或操作的对称性所以加密和解密的流程是完全一样的。
OFB加密流程(图片来自维基百科)
OFB解密流程(图片来自维基百科)
OpenSSL中用来加解密AES-OFB的函数是AES_ofb128_encrypt其参数和各参数的含义与AES_cfb128_encrypt完全一样,但由于OFB加密和解密是对称的所以没有参数enc。
OFB与CFB一样都非常适合对流数据的加密,OFB由于加密和解密都依赖与前一段数据,所以加密和解密都不能并行。
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:41684次
积分:1199
积分:1199
排名:千里之外
原创:59篇
转载:138篇
(5)(7)(21)(3)(15)(16)(47)(8)(2)(19)(3)(8)(10)(3)(5)(2)(14)(4)(5)(1)当前位置: >
高级加密标准AES支持的3种密钥长度不包括()。
所属学科:
试题类型:客观题
所属知识点:
试题分数:1.0 分
用户编号:330502笔记时间: 11:34
笔记内容:AES支持的密钥长度:128、192、256,分组长度:128位
&&&&&&&&&&&&&&&希赛网 版权所有 & &&君,已阅读到文档的结尾了呢~~
高级加密标准(aes)在ipsec协议中的应用,高级加密标准aes,ipsec加密算法,i..
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
高级加密标准(aes)在ipsec协议中的应用
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口高级加密标准AES外文翻译及译文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
高级加密标准AES外文翻译及译文
上传于||文档简介
&&高​级​加​密​标​准​A​E​S​外​文​翻​译​及​译​文
阅读已结束,如果下载本文需要使用5下载券
想免费下载本文?
下载文档到电脑,查找使用更方便
还剩30页未读,继续阅读
你可能喜欢

我要回帖

更多关于 java aes 密钥长度 的文章

 

随机推荐