AES-RSA概要总结

AES

数据加密标准(Data Encryption Standard: DES)的密钥长度是56比特,因此算法的理论安全强度是256, 1997年,美国国家标准技术研究所(National Institute of Standards and Technology: NIST)宣布希望征集高级加密标准(Advanced Encryption Standard: AES),用以取代DES。

AES是一个分组密码,属于对称密码范畴,AES算法的模块在对称密码领域特别是分组密码领域常有使用。

AES加密位数(128【10轮】,192【12轮】,256【14轮】)
AES用的什么模式(ECB,CBC,CTR,CFB,OFB)
AES填充方式(NoPadding,PKCS5Padding,PKCS7Padding)
AES初始向量(iv【CBC模式】)

1. AES加密

一种对称加密,要了解三个概念:密钥、填充、模式

1.1 AES密钥

AES密钥:AES支持三种密钥长度:128位,192位,256位,大家经常说的AES128, AES256就是指不同的密钥长度;AES算法设计之初并不只提供了这三种长度的密钥,还有160,224位(32bit 递增),只不过最终只选择了以上三种而已。

不同的密钥长长度意味着AES加密的轮数不同,128位加密10轮,192加密12轮,256加密14轮,从安全性角度来讲,256位安全性最高,但是128位因为加密轮数少,所以性能更好一些。

1.3 算法流程

AES

1.3.1 字节代替

字节替代的主要功能是通过S盒完成一个字节到另外一个字节的映射。S盒的详细构造方法可以参考文献[1]。这里直接给出构造好的结果,下图(a)为S盒,图(b)为S-1(S盒的逆)。S盒用于提供密码算法的混淆性。
在这里插入图片描述
reverse

S和S-1分别为16x16的矩阵,完成一个8比特输入到8比特输出的映射,输入的高4-bit对应的值作为行标,低4-bit对应的值作为列标。假设输入字节的值为a=a7a6a5a4a3a2a1a0,则输出值为S[a7a6a5a4][a3a2a1a0],S-1的变换也同理。

例如:字节00000000B替换后的值为(S[0][0]=)63H,再通过S-1即可得到替换前的值,(S-1 [6][3]=)00H

1.3.2 行移位

行移位是一个4x4的矩阵内部字节之间的置换,用于提供算法的扩散性。

  1. 正向行移位
    正向行移位用于加密,其原理图如下。其中:第一行保持不变,第二行循环左移8比特,第三行循环左移16比特,第四行循环左移24比特。
    在这里插入图片描述
  2. 逆向行移位

逆向行移位即是相反的操作,即:第一行保持不变,第二行循环右移8比特,第三行循环右移16比特,第四行循环右移24比特。

1.3 列混淆

列混淆:利用GF(28)域上算术特性的一个代替,同样用于提供算法的扩散性
原理 : 两个矩阵互逆,经过一次逆向列混淆后即可恢复原文

  1. 正向列混淆

正向列混淆的原理图如下:
  在这里插入图片描述
2. 逆向列混淆

逆向列混淆的原理图如下:
  在这里插入图片描述

1.3.4 轮密钥加

这个操作相对简单,其依据的原理是“任何数和自身的异或结果为0”。加密过程中,每轮的输入与轮子密钥异或一次;因此,解密时再异或上该轮的轮子密钥即可恢复。

1.2 填充

AES不是将拿到的明文一次性加密,而是分组加密,就是先将明文切分成长度相等的块,每块大小128bit,再对每一小块进行加密。那么问题就来了,并不是所有的原始明文串能被等分成128bit,例如原串大小200bit,那么第二个块只有72bit,所以就需要对第二个块进行填充处理,让第二个块的大小达到128bit。常见的填充模式有

1.2.1 NoPadding:

不进行填充,要求原始加密串大小必须是128bit的整数倍;

1.2.2 PKCS5Padding:

假设块大小8字节,如果这个块跟8字节还差n个字节,那么就在原始块填充n,直到满8字节。例:块{1,2,3},跟8字节差了5个字节,那么补全后的结果{1,2,3,5,5,5,5,5}后面是五个5,块{1,2,3,…7}跟8字节差了1个字节,那么补全后就是{1,2,3,…,7,1},就是补了一个1。
如果恰好8字节又选择了PKCS5Padding填充方式呢?块{1,2,3…8}填充后变成{1,2,3…8,8…8},原串后面被补了8个8,这样做的原因是方便解密,只需要看最后一位就能算出原块的大小是多少。

1.2.3 PKCS7Padding

跟PKCS5Padding的填充方式一样,不同的是,PKCS5Padding只是对8字节的进行填充,PKCS7Padding可以对1~256字节大小的block进行填充。openssl里aes的默认填充方式就是PKCS7Padding

1.3. 模式

AES有多种加密模式,包括:ECB,CBC,CTR,OCF,CFB,最常见的还是ECB和CBC模式。

1.3.1 ECB模式

最简单的一种加密模式,每个块进行独立加密,块与块之间加密互不影响,这样就能并行,效率高。
虽然这样加密很简单,但是不安全,如果两个块的明文一模一样,那么加密出来的东西也一模一样。
openssl的相关函数:
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)

1.3.2 CBC模式

CBC模式中引入了一个新的概念,初始向量iv。iv的作用就是为了防止同样的明文块被加密成同样的内容。原理是第一个明文块跟初始向量做异或后加密,第二个块跟第一个密文块做异或再加密,依次类推,避免了同样的块被加密成同样的内容。
openssl相关函数:
void AES_cbc_encrypt (const unsigned char *in, unsigned char *out, size_t length, const AES_KEY *key, unsigned char *ivec, const int enc)
int AES_set_decrypt_key (const unsigned char *userKey, const int bits, AES_KEY *key)

敲黑板!! 所以跟第三方对接的时候,如果对面说他们用aes加密,务必对他们发起灵魂三问:

aes用的什么模式?
aes的填充方式是什么?有的第三方不用标准的填充方式,令人费解,所以一定要问清楚
设置的初始向量是什么?(如果对方说他们用cbc)

2. RSA

一种非对称加密方式。需要两个密钥,一个公钥一个私钥,使用其中一把密钥加密后的明文,只有对应的密钥才能解的开。
rsa可以用来做加密或者做签名,两者性质不一样。

2.1. 签名和加密的区别

签名的作用是让接受方验证你传过去的数据没有被篡改;加密的作用是保证数据不被窃取。

2.2 rsa签名

原理:你有一个需要被验签的原串A。
步骤一:选择hash算法将A进行hash得到hash_a;
步骤二:将hash_a进行加密,得到加密值encrypt_a;
步骤三:将原串A和加密的encrypt_a发给第三方,第三方进行验签。第三方先解密encrypt_a,得到一个hash值hash_a1,然后对原串A使用同样的hash算法进行hash,得到的即为加密前的hash_a,如果hash_a = hash_a1, 那么验签成功。
rsa使用私钥对信息加密来做签名,使用公钥解密去验签。
openssl相关函数:
int RSA_sign(int type, const unsigned char *m, unsigned int m_len,
unsigned char *sigret, unsigned int *siglen, RSA *rsa);

int RSA_verify(int type, const unsigned char *m, unsigned int m_len,
unsigned char *sigbuf, unsigned int siglen, RSA *rsa);

注意:两个函数中的m,是原串hash后的值,type表示生成m的算法,例如NID_sha256表示使用sha256对原串进行的hash,返回1为签名成功或者验签成功,-1位为失败。
再次敲黑板!! 所以如果第三方说使用rsa验签,要让对方告知他们的hash算法。

2.3 rsa加密

首先明确,私钥加密不等于签名。加密的时候,使用使用公钥加密,第三方使用你的私钥进行解密。
openssl里公钥加密函数为RSA_public_encrypt,私钥解密函数为RSA_private_decrypt,具体的可以自己去查看下官方文档。
rsa也涉及到了填充方式,所以对接的时候也要问清楚
在使用公钥进行加密时,会发现每次加密出的结果都不一样,但使用私钥加密时,每次的结果都一样,网上查了一圈,说是因为填充方式的原因。
官方文档说明:
EB = 00 || BT || PS || 00 || D .
BT:块类型
PS:填充字串
D:原始数据
BT为00或01或02,使用私钥时为00和01,这两种类型下,PS均为固定值;
02类型表示公钥,这时PS就变成随机的字串,这也就是为什么每次公钥加密结果不一样的原因。

那么为什么一定要使用私钥做签名,公钥做加密,而不是公钥做签名,私钥做加密呢?
举个栗子:

A使用公钥做签名,传输过程中被劫持,因为公钥是公开的,黑客篡改数据后使用公钥重新做签名,接受者B用私钥验签是可以通过的;
A使用私钥做加密,传输过程中被黑客劫持,因公钥是公开的,黑客就能用公钥解开数据,拿到原始信息。

[^1] Joan Daemen and Vincent Rijmen, The Design of Rijndael, AES - The Advanced Encryption Standard, Springer-Verlag 2002 (238 pp.)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值