公钥密码学3

本周主要的内容是:(1)实现填充RSA加密算法以及其攻击原理。(2)多个数字签名的历史地位,明白其各个签名所产生的背景。

PKCS1 v1.5 加密算法实现

定义 x x x如下图所示,图中数字的单位均为字节:
图1
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;

其中的一个运行结果为:
图2

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(k2)M=[2B,3B1]
然后查找一个 s , s ≥ n / 3 B s,s \geq n/3B s,sn/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=csemodn=(ms)e

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

「已注销」

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值