「信息安全-密码与隐藏技术」RSA加密算法的实现(CPP 实现)

RSA加密算法的实现

第一步,选择密钥

  • 选择两个不同的素数 p、q
  • 计算公开模数r = p x q
  • 计算欧拉函数 φ(r) = (p-1) * (q-1)
  • 选择一个与 φ(r) 互质的量 k,即保证 gcd(φ(r), k) = 1 时,选择 k 。 可以令 sp = kpk = k

因为与 φ(r) 互质的数可能不止一个,所以 k 的值是有选择的。可以先设 k 为一个初值,并且 k < φ(r),然后用试探法求出满足条件 φ(r)k 的最大公约数为 1 的 k,即 gcd(φ(r), k) = 1

注意,如果选一个密钥的值大于 φ(r) 的值,就不能正确求出另一个密钥。

  • 根据 sk * pk ≡ 1 mod φ(r),已知 sk 或 pk,用乘逆算法求 pk 或 sk。

第二步,加密

对明文自乘 pk 次幂或 sk 次幂,再按模 r 求余,就可得到密文。

第三步,解密

与加密过程类型,对密文自乘 pk 次幂或 sk 次幂,再按模 r 求余,就可得到明文。

关键代码:求逆元

// 拓展gcd
void exgcd(ll a,ll b,ll& d,ll& x,ll& y){
    if(!b) { d = a; x = 1; y = 0; }
    else{ exgcd(b, a%b, d, y, x); y -= x*(a/b); }
}
// 求逆元
ll inv(ll a, ll p){
    ll d,x,y;
    exgcd(a,p,d,x,y);
    return d == 1 ? (x+p)%p : -1;
}

关键代码:平方-乘算法

使用 RSA 算法进行加密和解密时需要用到此算法,也就是我们所说的快速幂,下面给出对应模板。

#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a);
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
// ¿ìËÙÃÝ
ll poww(ll a,ll b,ll mod){
    ll ans=1,base=a;
    while(b){
        if(b&1)
            ans = ans*base%mod;
        base = base*base%mod;
        b>>=1;
    }
    return ans;
}
int main(){
    cout<<poww(34,60,51)<<endl; //34
    cout<<poww(345,89,101)<<endl; //34
}

有了上述两段关键代码后,我们的整个加密算法就简单了,下面给出整体实现源码:

实现源码

#include<bits/stdc++.h>
#define mst(a,b) memset(a,b,sizeof(a);
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=1e3+5;
int n,m,t;
typedef long long ll;
// 拓展gcd
void exgcd(ll a,ll b,ll& d,ll& x,ll& y){
    if(!b) { d = a; x = 1; y = 0; }
    else{ exgcd(b, a%b, d, y, x); y -= x*(a/b); }
}
// 求逆元
ll inv(ll a, ll p){
    ll d,x,y;
    exgcd(a,p,d,x,y);
    return d == 1 ? (x+p)%p : -1;
}
// 快速幂
ll poww(ll a,ll b,ll mod){
    ll ans=1,base=a;
    while(b){
        if(b&1)
            ans = ans*base%mod;
        base = base*base%mod;
        b>>=1;
    }
    return ans;
}
// 加密过程
ll encryption(ll pk,ll r,ll num){
    return poww(num,pk,r)%r;
}

// 解密过程
ll decrypt(ll sk,ll r,ll text){
    return poww(text,sk,r)%r;
}
int main(){
    ll prime1,prime2,pk;
    cout<<"请输入测试数据组数:"<<endl;
    cin>>t;
    while(t--){
        cout<<"请输入两个大的素数和公钥"<<endl;
        cin>>prime1>>prime2>>pk;
        // 公开模数
        ll r = prime1 * prime2;
        // 欧拉函数
        ll n = (prime1-1)*(prime2-1);
        cout<<"公开模数r为:"<<r<<endl;
        ll sk = inv(pk,n);
        cout<<"私钥sk为:"<<sk<<endl;
        cout<<"请输入要加密的数字串(输入0结束):"<<endl;
        ll num;
        cin>>num;
        while(num){
            // 密文
            int cipherText = encryption(pk,r,num);
            cout<<"加密后的密文为:"<<cipherText<<endl;
            // 明文
            int plainText = decrypt(sk,r,cipherText);
            cout<<"解密后的明文为:"<<plainText<<endl;
            cin>>num;
        }
    }
    return 0;
}
学如逆水行舟,不进则退
  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

一百个Chocolate

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

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

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

打赏作者

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

抵扣说明:

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

余额充值