本周主要的内容是:(1)实现填充RSA加密算法以及其攻击原理。(2)多个数字签名的历史地位,明白其各个签名所产生的背景。
PKCS1 v1.5 加密算法实现
定义 x x x如下图所示,图中数字的单位均为字节:
PKCS1 RSA加密的v1.5的具体实现过程分为以下几个步骤:
1.公私钥对生成
2.随机生成 117 117 117字节的字符串作为消息 D D D
2.在 D D D前面进行填充:“ 00 00 00”和“ 02 02 02”填充、 P S PS PS(非零随机数)填充、“ 00 00 00”填充
3.将八位字节字符串转换成整数
4.RSA计算
5.将整数转换成八位字节字符串
6.以 16 16 16进制输出密文
7.将八位字节字符串复制到 c i p h e r cipher cipher中(供解密使用)
解密过程:
1.将八位字节字符串转换成整数
2.RSA计算
3.将整数转换成八位字节字符串
4.加密块解析:去掉前面的“ 00 00 00”、“ 02 02 02”、 P S PS PS以及“ 00 00 00”,得到 D D D
5.将 D D D复制到 m e s s a g e message message中
6.以 16 16 16进制输出 m e s s a g e message message
// 填充与加密过程
//这里N=BLOCK_SIZE=128字节
for(int i=0;len>0;i++){
int d_len = (len >= (BLOCK_SIZE - 11)) ? BLOCK_SIZE - 11 : len;
/* 消息填充 */
// 00 || 02
mess_block[i++] = 0x00;
mess_block[i++] = 0x02;
// PS
while(i < (BLOCK_SIZE - d_len - 1))
mess_block[i++] = (rand() % (0xFF - 1)) + 1; //1-255
mess_block[i++] = 0x00;// 00
memcpy(mess_block + i, message + (length - len), d_len);// D
printf("填充后的消息为:");
print_hex(mess_block,BLOCK_SIZE);
printf("\n");
// 将八位字节字符串转换成整数
mpz_import(m, BLOCK_SIZE, 1, sizeof(mess_block[0]), 0, 0, mess_block);
// RSA计算
block_encrypt(c, m, pk);
// 最后生成的密文比BLOCK_SIZE短,就在密文前填充0
int off = block_count * BLOCK_SIZE;
off += (BLOCK_SIZE - (mpz_sizeinbase(c, 2) + 8 - 1)/8);
// 整数到八位字节字符串
mpz_export(FD + off, NULL, 1, sizeof(char), 0, 0, c);
printf("输出密文:");
print_hex(FD, BLOCK_SIZE);
printf("\n");
memcpy(cipher , FD , BLOCK_SIZE);
block_count++;
len -= d_len;
}
// 解密过程
int i;
for(i = 0; i < (length / BLOCK_SIZE); i++){
// 将八位字节字符串转换成整数
mpz_import(c, BLOCK_SIZE, 1, sizeof(char), 0, 0, cipher + i * BLOCK_SIZE);
// RSA计算
block_decrypt(m, c, sk);
int off = (BLOCK_SIZE - (mpz_sizeinbase(m, 2) + 8 - 1)/8);
// 整数到八位字节字符串
mpz_export(buf + off, NULL, 1, sizeof(char), 0, 0, m);
/* 加密块解析 */
// 去掉前面的0x00和0x02,以及PS,直到遇到一个“0”
int j;
for(j = 2; ((buf[j] != 0) && (j < BLOCK_SIZE)); j++);
j++;// 跳过“00”
// 将D复制到message中
memcpy(message + msg_idx, buf + j, BLOCK_SIZE - j);
printf("解密:");
print_hex(message + msg_idx, BLOCK_SIZE-j);
printf("\n");
msg_idx += BLOCK_SIZE - j;
}
main方法核心代码:
char buf[117];
for(i = 0; i < 117; i++)
buf[i] = rand() % 0xFF;
mpz_import(M, 117, 1, sizeof(buf[0]), 0, 0, buf);
printf("明文:%s\n\n", mpz_get_str(NULL, 16, M));
char bufed[BLOCK_SIZE];
encrypt(bufed,buf,117,pk);
char DDC[117];
decrypt(DDC,bufed,BLOCK_SIZE,sk);
system("pause");
return 0;
其中的一个运行结果为:
Bleichenbacher(布莱申巴赫)攻击
bleichenbacher攻击
①首先,将明文消息message进行PKCS1 v1.5格式填充,然后将其转换成整型,进行 R S A RSA RSA加密计算,得到密文 c i p h e r t e x t ciphertext ciphertext。
②其次, B l e i c h e n b a c h e r Bleichenbacher Bleichenbacher攻击。攻击者先将 c i p h e r t e x t ciphertext ciphertext转换成整型,得到 c c c。此时, B = 2 8 ( k − 2 ) , M = [ 2 B , 3 B − 1 ] B=2^{8(k-2)},M=[2B,3B-1] B=28(k−2),M=[2B,3B−1]。
③然后查找一个 s , s ≥ n / 3 B s,s \geq n/3B s,s≥n/3B,使得 o r a c l e oracle oracle收到 c ′ = c ⋅ s e m o d n = ( m ⋅ s ) e m o d n c'=c·s^e \bmod n=(m·s)^e \bmod n c′=c⋅semodn=(m⋅s)e