网络安全---简单RSA算法的实现(C++)

前言

这是课程学习中的一个作业,把手写过程转成程序实现

题目

4、 已知RSA算法中,素数p=5,q=7,模数n=35,公钥e=5,明文为bed,对明文进行加解密,使用手工完成RSA公开秘钥密码体制算法加密运算。字母数字映射表如下:
1

可以参考, 用实例给新手讲解RSA加密算法
但并不保证网页内容完全正确,请自行判断

解题分析

加解密过程:

  • 设计公私密钥(e,n)和(d,n):
    由题目需求p = 5 ,q = 7,模数n = 35 ,公钥e = 5 得 f(n) = (p-1)*(q-1)=24,e = 5 与f(n) = 24 互素 故e满足要求。
  • 计算密钥d:
    d的计算公式为 d*e ≡ 1(mod f(n)),即 5*d ≡1 mod 24,d值的推导如下表:
de*d = 5*d(e*d)mod(p-1)(q-1)= (5*d) mod 2
155
21010
31515
42020
5251

由此可得d = 5。

  • 得出公钥私钥:
    从上述步骤得出公钥KU = (e,n)=(5,35),私钥KR =(d,n) = (5,35)
  • 英文数字化
    将明文信息数字化,并将每块两个数字分组。假定明文英文字母编码表为按字母顺序排列数值,即:
字母abcdefghijklm
码值01020304050607080910111213
字母nopqrstuvwxyz
码值14151617181920212223242526

明文bed数字化,即为:02,05,04

  • 明文加密
    由加密公式 Y=X^e mod n 得密文:
    Y1 = 2^5 mod 35 = 32 mod 35 = 32
    Y2 = 5^5 mod 35 = 3125 mod 35 = 10
    Y3 = 4^5 mod 35 = 1024 mod 35 = 9
  • 密文解密
    由解密公式 X=Y^d mod n 恢复明文:
    X1 = 32^5 mod 35 = 33554432 mod 35 = 2
    X2 = 10^5 mod 35 = 100000 mod 35 = 5
    X3 = 9^5 mod 35 = 59049 mod 35 = 4
    即恢复明文为bed。

运行截图

1

代码

/*
*
*简单RSA加解密算法
*HB
*需输入p,q,e
*/
#include <iostream>
#include<string.h>
using namespace std;
/*
*判断素数
*/
bool isPrime(int n)
{
    if(n%2==0)return false;
    for(int i= 2;i<n/2+1;i++)
        if(n%i==0)return false;

    return true;
}
//判断互质
bool isMutuality(int e,int fn)
{
    if(e>fn||e<1)return false;
    if(isPrime(e)&&fn%e!=0)return true;
    for(int i = 2;i<=e;i++)
        if(e%i==0&&fn%i==0)return false;
    return true;
}
//计算d
int getTheD(int e,int fn)
{
    for(int i=1;;i++)
        if((e*i)%fn==1)return i;
}
//英文数字化
//英文小写
void charToNum(char *str,int *num,int n)
{
    for(int i=0;i<n;i++)
        num[i]=str[i]-'a'+1;
}
//数字转英文
//英文小写
void numToChar(int *num,char *str,int n)
{

    for(int i=0;i<n;i++)
    {

        str[i]=(num[i]+'a'-1)%256;

    }

}
//模指数n运算
int fMod(int c,int n,int e)
{
    if(c>n)return 0;
    int temp = c;
    //cout<<" "<<endl;
    //cout<<"c="<<c<<" n="<<n<<" e="<<e<<endl;
    for(int i=1;i<e;i++)
    {
        c*=temp;
        c%=n;//防止c过大
    }

    return c;

}
int num[100];//密文数组最长100
void RSA(int p,int q,int e,char *str)
{
    int len = strlen(str);

    if(len<=0) return;
    if(!(isPrime(p)&&isPrime(q)))return;//非素数
    int n = p*q;
    int fn = (p-1)*(q-1);
    if(!isMutuality(e,fn))return;//e和fn不互质
    int d = getTheD(e,fn);//计算d
    cout<<"公钥"<<"("<<e<<","<<n<<")"<<endl;
    cout<<"密钥"<<"("<<d<<","<<n<<")"<<endl;
    charToNum(str,num,len);
    cout<<"密文数组:"<<endl;
    for(int i=0;i<len;i++)
    {
        num[i] = fMod(num[i],n,e);
        cout<<num[i]<<" ";
    }

    cout<<endl;



}
//*arrNum 密文数组
void DeRSA(int p,int q,int e,int len)
{
    cout<<"\n\n-------解密程序--------"<<endl;
    cout<<"当前需要解密的密文数组:"<<endl;
    for(int i=0;i<len;i++)
    {
        cout<<num[i]<<" ";
    }
    cout<<"\n";


    if(len<=0) return;
    if(!(isPrime(p)&&isPrime(q)))return;//非素数
    int n = p*q;
    int fn = (p-1)*(q-1);
    if(!isMutuality(e,fn))return;//e和fn不互质
    int d = getTheD(e,fn);//计算d
    cout<<"公钥"<<"("<<e<<","<<n<<")"<<endl;
    cout<<"密钥"<<"("<<d<<","<<n<<")"<<endl;

    cout<<"解密后明文数组:"<<endl;
    for(int i=0;i<len;i++)
    {
        num[i] = fMod(num[i],n,d);
        cout<<num[i]<<" ";
    }
    cout<<endl;
    char str[100];
    numToChar(num,str,len);
    cout<<"解密后明文:"<<endl;
    cout<<str<<endl;
}
int main()
{
    string strM;
    int p,q,e;

    cout<<"**************************************"<<endl;
    cout<<"*         简单RSA加解密程序          *"<<endl;
    cout<<"*         需输入p,q,e                *"<<endl;
    cout<<"*         p,q为质数,p*q<32767        *"<<endl;
    cout<<"*         e与fn=(p-1)*(q-1)互质      *"<<endl;
    cout<<"**************************************"<<endl;
    cout<<"请输入p:";
    cin>>p;
    while(!isPrime(p))cout<<"p非素数请重新输入:",cin>>p;
    cout<<"请输入q:";
    cin>>q;
    while(!isPrime(q))cout<<"q非素数请重新输入:",cin>>q;
    int fn = (p-1)*(q-1);
    cout<<"fn:"<<fn<<endl;
    cout<<"请输入e:";
    cin>>e;
    while(!isMutuality(e,fn))cout<<"e与fn非互质重新输入:",cin>>e;
    cout<<"请输入需加密的明文:";
    cin>>strM;

    RSA(p,q,e,(char*)strM.c_str());
    DeRSA(p,q,e,strM.length());
    return 0;
}

  • 10
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值