RSA密码初探

1 篇文章 0 订阅

RSA密码初探

一。 RSA公私钥生成
1.随机选定两个大素数p, q.
2.计算公钥和私钥的公共模数 n = pq .
3.计算模数n的欧拉函数 φ(n) .
4.选定一个正整数e,使1 < e < φ(n) ,且e与φ(n)互质.(e取最小)
5.计算d,满足 de ≡ 1  (mod φ(n) )(d取最小)
6.n与e决定公钥, n与d决定私钥.
二。加解密
该过程为L给Z发消息,公钥为Z的公钥(n & e), 私钥为Z的私钥(n & d).
1.L欲给Z发一个消息M,他先把M转换为一个大数m < n, 然后用Z的公钥(n & e)把m加密为另一个大数: c = m^e mod n
2.Z收到L发来的大数c,着手解密.通过自己的私钥(n & d),得到原来的大数m: 
 m = c^d mod n
3.再把m转换为M, Z即得到L的原始消息.
这个过程之所以能通过,是因为有如下等式:
 c^d ≡(m^e)^d ≡ m ^(ed) (mod n)
  
若给出p,q,和密文整数序列a[m] ,求解公钥n,e,私钥n,d以及解出明文序列b[m]
1)令x = φ(n) = φ(p) * φ(q) = (p-1)(q-1) (p,q互质且p,q都是质数)
2)e是与x互质的最小正整数,枚举即可
3)de ≡ 1  (mod φ(n) ) ,d最小,枚举,或者逆元(扩欧几里得求逆元,非快速幂,因为φ(n)不一定是质数)4)b[i] = ( a[i] ^ d ) % n (也就是过程2(快速幂取模即可)(有时候可能爆精度快速幂中嵌套快速乘)

例题:
密码破译

描述
近日来勒索病毒的事件频繁发生,小Y对它的加密原理非常感兴趣,研究了一番相关知识之后,他就来给你看他的加密程序,并给你一段密文,和你炫耀说就算把程序给你看你也破解不出来。

你扫了一眼代码发现加密的公式为b =a ^ e%m,其中e是质数。

进一步分析发现m=p∗q,p和q都为质数,p!=q,

作为一个计算机高手,你早就对加密算法烂熟于心,一眼就看出这个程序的算法和原理,找到了破解的方法,发现小Y疏忽在与给了你一个不够大的m。

你知道解密的公式与加密对称,为a=b^d%m。

但是你仍然无法心算解出这个d,因此你需要借助计算机来将密文破解。

输入
第一行有一个整数T表示数据组数。(T<=100)
接着有T组数据,每组数据两行。
第一行有四个数e、p、q和n,其中e、p、q如题所描述,n表示需要解密的数字序列长度。
第二行是需要解密的数字序列a1…an。
1<p,q,e<=108,p、q、e为质数且p!=q。
0<= ai 保证解密的结果即原数列的值小于min(p,q)并大于等于0
1<=n<=100
保证m有且仅有两个不同的质因数p和q,并且一定存在一个题中描述的参数d使得解密公式能够无损解密出所有0~min(p,q)−1范围之间的数字。

输出
对于每组数据输出一行,表示解密后的数字序列,数字之间以空格隔开。

样例输入1
1
5 19 29 3
335 440 514
样例输出1
65 67 77

提示
对于样例,存在d=101使得解密公式成立。
注意m和ai的大小可能超过int的范围

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100 + 5;
typedef long long ll;

ll exgcd(ll a, ll b,ll &x,ll &y){
    if(!b){
        return x = 1, y = 0, a;
    }
    ll d = exgcd(b , a % b, x, y);
    ll t = x;
    x = y, y = t - (a / b) * y;
    return d;
}

ll get_inv(ll a,ll mod){
    ll x,y;
    exgcd(a,mod,x,y);
    return (x % mod + mod)%mod;
}

ll mul(ll a,ll b,ll mod){
    ll res = 0;
    while(b){
        if(b&1) res = (res + a) % mod;
        a = a * 2 % mod;
        b >>= 1;
    }
    return res;
}

ll fast_pow(ll a,ll b,ll mod){
    ll res = 1;
    while(b){
        if(b&1) res = mul(res,a,mod);
        a = mul(a,a,mod);
        b >>= 1;
    }
    return res;
}

ll a[maxn];

int main(){
    ll p,q,e;
    int T,n;
    scanf("%d",&T);
    while(T--){
        scanf("%lld%lld%lld%d",&e,&p,&q,&n);
        for(int i = 0; i < n; ++i){
            scanf("%lld",&a[i]);
        }
        ll m = p * q;
        ll d = get_inv(e,(p - 1) * (q - 1));
        for(int i = 0; i < n; ++i){
            printf("%lld",fast_pow(a[i],d,m));
            putchar((i == n - 1)?'\n':' ');
        }
    }
    return 0;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是用Python实现RSA密码的示例代码: ```python import random import math def generate_key(p, q): # 计算n和欧拉函数φ(n) n = p * q phi_n = (p - 1) * (q - 1) # 随机选择一个整数e,且1 < e < φ(n),且e与φ(n)互质 e = random.randrange(1, phi_n) gcd = math.gcd(e, phi_n) while gcd != 1: e = random.randrange(1, phi_n) gcd = math.gcd(e, phi_n) # 计算e的模反元素d d = mod_inverse(e, phi_n) # 返回公钥和私钥 return (e, n), (d, n) def mod_inverse(a, m): # 扩展欧几里得算法求a在模m下的逆元素 g, x, y = egcd(a, m) if g != 1: raise ValueError('modular inverse does not exist') return x % m def egcd(a, b): if a == 0: return (b, 0, 1) else: g, y, x = egcd(b % a, a) return (g, x - (b // a) * y, y) def encrypt(plaintext, public_key): # 加密明文 e, n = public_key ciphertext = [pow(ord(char), e, n) for char in plaintext] return ciphertext def decrypt(ciphertext, private_key): # 解密密文 d, n = private_key plaintext = ''.join([chr(pow(char, d, n)) for char in ciphertext]) return plaintext # 示例使用 p = 61 q = 53 public_key, private_key = generate_key(p, q) print('公钥:', public_key) print('私钥:', private_key) plaintext = 'Hello, RSA!' ciphertext = encrypt(plaintext, public_key) print('密文:', ciphertext) decrypted_text = decrypt(ciphertext, private_key) print('解密结果:', decrypted_text) ``` 在示例中,我们首先使用`generate_key`函数生成RSA加密的公钥和私钥。然后,我们使用`encrypt`函数将明文加密为密文,使用`decrypt`函数将密文解密为明文。在示例中,我们将字符串'Hello, RSA!'作为明文进行加密和解密。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值