密码学:用例子和程序说明RSA算法过程

原文链接:http://blog.csdn.net/ddk3001/article/details/54585854

1 目的说明

本文用两个简单的例子说明RSA算法过程:
1、如何计算公钥和私钥?
2、如何对消息进行加密和解密?

这两个例子都可以用计算器进行验证,目的是了解RSA算法的基本过程。
本文不对RSA算法的严格描述和证明做深入解释,有兴趣的读者请看参考链接。

最后给出了一个实现RSA算法的C语言程序。

参考:
http://www.cnblogs.com/hykun/p/RSA.html
http://blog.csdn.net/sunmenggmail/article/details/11994013
http://www.360doc.com/content/14/0517/19/7385274_378568902.shtml

2 计算公钥和私钥

RSA算法:

1、选择两个质数p和q,计算:

  • N = p * q
  • r = (p-1)(q-1)

2、计算模反元素:

模反元素:如果两个正整数e和r互质,那么一定能找到整数d,使得 ed%r=1 ,即 (ed-1)%r=0,则称d为e的模反元素。
  • 随机选择一个整数e : 1 < e < r,且e与r互质
  • 计算e关于模r的模反元素d : (ed-1)/r=k 或 ed-kr=1(k为任意正整数)
  • 将e和r的值代入,得到一个二元一次方程。对它求解,求得一组解(d和k)即可。

3、把 p 和 q 扔掉
4、公钥是 (N,e),私钥是 (N,d)

【例1】

1、p = 3 , q = 11

  • N = pq = 33
  • r = (p-1)(q-1) = (3-1)(11-1) = 20

2、计算模反元素:

  • r=20,选择e=3,得到二元一次方程:3d-20k=1
  • 获得一组解:d=7,k=1

3、因此,公钥是 (N, e) = (33, 3),私钥是 (N, d) = (33, 7)。

【例2】

1、p = 13 , q = 5

  • N = pq = 65
  • r = (p-1)(q-1) = (13-1)(5-1) = 48

2、计算模反元素:

  • r=48,选择e=5,得到二元一次方程:5d-48k=1
  • 获得一组解:d=29,k=3

3、因此,公钥是 (N, e) = (65, 5),私钥是 (N, d) = (65, 29)。

3 加密消息

RSA算法:

  • 公钥:(N,e)
  • 明文转换:
    • 将消息m转换为一个整数n ( n < N )
    • 如果消息很长,则将消息分成多段,将每段转换为一个整数n ( n < N )
  • 加密公式:c = (n^e)%N
明文转换的例子:
将明文中的每一个字转换为这个字的Unicode码,然后将这些Unicode码连在一起组成一个数字n。
反之,将n划分为Unicode码串,每个Unicode码还原为一个字,这样就得到了原来的明文。

【例1】

  • 公钥: (N, e) = (33, 3)
  • 明文:消息m转换为整数24
  • 计算:c = (24^3)%33 = 30
  • 因此:24被加密为30

【例2】

  • 公钥: (N, e) = (65, 5)
  • 明文:消息m转换为整数3
  • 计算:c = (3^5)%65 = 48
  • 因此:3被加密为48

4 解密消息

RSA算法:

  • 私钥: (N,e)
  • 解密公式:n = (c^d)%N
  • 将整数n转换为消息m

【例1】

  • 私钥: (N, d) = (65, 29)
  • 密文:c=48
  • 计算:n = (48^29)%65 = 3
  • 因此:48被解密为3

【例2】

  • 私钥是 (N, d) = (33, 7)
  • 密文是:c=30
  • 计算:n = (30^7)%33 = 24
  • 这样,30被解密为24

5 一点说明

RSA算法使用两个素数p和q计算N=pq,然后再经过一些计算得到公钥(N,e)和私钥(N,d)。

根据RSA加解密公式,使用公钥加密后只能使用私钥解密,使用私钥加密后只能使用公钥解密。

因为公钥是公开的,如果能破解出私钥,就能够解密密文消息,而破解需要把N分解为两个素数p和q,如果p和q足够大,则很难分解,类似于单向函数。

6 编程实现

说明:此C语言程序非本人所写,网上找到的。

/*********************************************/
// RSA
/*********************************************/
#include<stdio.h>

// 数据处理函数,实现幂的取余运算
int candp(int a, int b, int c) 
{
   int r = 1;
   b = b + 1;

   while(b != 1) 
   {
       r = r * a;
       r = r % c;
       b--;
   }

   printf("%d\n", r);
   return r;
}

// 公钥e与t的互素判断
int fun(int x, int y) 
{
   int t;
   while(y) 
   {
       t = x;
       x = y;
       y = t % y;
   }

   if(x == 1)
       return 0;    // x与y互素时返回0
   else
       return 1;    // x与y不互素时返回1
}

// 主函数  
int main( )
{
   int p, q, e, d, m, n, t, c, r;

   printf("请输入两个素数p,q:");
   scanf("%d%d", &p, &q);

   n= p * q;
   printf("计算得n为%3d\n", n);

   // 求n的欧拉数
   t= (p - 1) * (q - 1);  
   printf("计算得t为%3d\n", t);

   printf("请输入公钥e:");
   scanf("%d", &e);
   if(e < 1 || e > t || fun(e, t)) 
   {
      // e<1 或 e>t 或 e与t不互素时,重新输入
       printf("e不合要求,请重新输入:");
       scanf("%d", &e);
   }

   d= 1;
   // 由公钥e求出私钥d
   while(((e * d) % t) != 1)
       d++;             
   printf("经计算d为%d\n", d);

   // 加密或解密选择
   printf("加密请输入1\n");  
   printf("解密请输入2\n");
   scanf("%d", &r);

   switch( r ) 
   {
   case 1:
       printf("请输入明文m:");   // 输入要加密的明文数字
       scanf("%d", &m);
       c = candp(m, e, n);
       printf("密文为%d\n", c);
       break;

   case 2:
       printf("请输入密文c:");   // 输入要解密的密文数字
       scanf("%d", &c);
       m = candp(c, d, n);
       printf("明文为%d\n", m);
       break;

   default:
       ;
    }

   return 0;
}
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值