一个简单地C语言程序展示RSA加密原理

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>

//质数判定函数
intlong IsPrime(intlong n)
{
 int i=2;
 int m=sqrt(n);
 if(n<=1)
 {
   return 0;
 }
 for(i=2;i<=m;i++)
 {
   if(n%i==0)
   {
     break;
   }
 }
 if(i>m)
 {
   return 1;
 }
 else
 {
   return 0;
 }
}

int main()
{
//------------step1:随机生成两个质数-------------------------
 srand(time(NULL));
 intlong a=rand()%1000001+1000000;
 int i;
 for(i=0;;i++)
 {
   if(IsPrime(a))
   {
     break;
   }
   else
   {
     a=rand()%1000001+1000000;//生成一个1000000到2000000之间的质数
   }
  }

  for(i=0;i<1000000000;i++){}//防止产生两个同样的质数

  srand(time(NULL));

  intlong b=rand()%1000001+1000000;

 for(i=0;;i++)
 {
   if(IsPrime(b))
   {
     break;
   }
   else
   {
    b=rand()%1000001+1000000;
   }
  }
  printf("a:%ld\nb:%ld\n",a,b);

//------------step2:生成两个随机数的积n与n的欧拉函数m-------------------------
  long long n;
  n=a*b;//此数位数越大,破解难度会指数上升 
  
  printf("n:%lld\n",n);
    
  long long m;            //生成n的欧拉函数  
  m=(a-1)*(b-1);          //公式1
    
  printf("m:%lld\n",m);

//------------step3:生成公钥e-------------------------
  long long e;
    
  for(i=0;i<1000000000;i++){}

  srand(time(NULL));
  e=rand()%m+1;           //公式2
  for(i=0;;i++)
  {
   if(IsPrime(e))
   {
     break;
   }
   else
   {
    e=rand()%m+1;
   }
  }

  printf("e:%lld\n",e);
//------------step4:生成私钥d-------------------------  
  long long d;

  for(d=0;;d++)         //用一个for循环代替欧几里得扩展算法
  {
    if((e*d)%m==1)      //公式3       
    {
      break;
    }
  }

  printf("d:%lld\n",d);
//------------step5:用n与公钥e加密message-------------------------  
  long int Message=888; //明文消息
  long int CodedMessage;//加密后消息
  long int DecodedMessage//解密后消息
  CodedMessage=pow(Message,e)%n //加密

//------------测试1:合法的用n与私钥d解密加密后消息-------------------------  
  DecodedMessage=pow(CodedMessage,d)%n      

//------------测试2:在无私钥d的情况下,遍历穷举尝试将n分解求ab,进而代回Step2中的公式2求出m,m代回step3公式2求出e,m和e代回公式4求出私钥d,以达到非法破解-------------------------  


  int long try_a,try_b;

  for(try_a=2;a1<n;try_a++)
  {
    for(try_b=2;try_b<n;try_b++)
    {
      if(IsPrime(try_b))
      {
        if(IsPrime(try_a))
        {
          if(try_a*try_b==n)
          {
            printf("a=%ld,b=%ld,n=%ld",try_a,try_b,try_a*try_b);  //将n分解为两个质数,只可能有一个解,到这里既已经找到了ab
            return;                                               
          }
        }
        else
        {
          continue;
        }
      }
      else
      {
        continue;
      }
    }
  }
  return 0;
 }

此加密算法的安全性就是建立在将n分解为两个质因数的耗时性上,以上面测试二中的代码为例,a*b结果的取值范围在1 000 000 000 000~4 000 000 000 000, 1万亿~4万亿,也既是for循环的次数。一个主频4GHz的cpu每秒震荡40亿次,假设ab相乘一次(try_a*try_b==n)的指令需要4个周期(cpu4次震荡)完成,对于一个乱序cpu可以简单的优化一下代码,使用循环展开多路并行计算达到1个周期相乘一次,如果cpu支持SIMD可以最快达到0.5个周期,既需2万亿次震荡,既是只算ab不断的连续相乘也需要500秒,而这只是该函数循环中最不耗时最可优化的部分,另外4万亿这个数字对于64位int来讲还是很小的一个数(无符号64位int最大值大于10的19次方,1万亿是10的12次方,只通过放大ab取值范围,很轻松的就可以将破解难度上升百万倍)。所以一个万位长度秘钥的商业级的rsa加密,即使用优化的算法顶级的算力,破解时间也需以百年计。

===================================================

维护日志:

2018-7-24:review

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值