第十屆藍橋杯 省賽A組 E RSA 解密

這個題應該是填空題中最難的一個了。

思路很簡單,但是你需要一點python的基礎

講一下本題的思路。

首先我們要對公鑰中的n進行質因子分解,得到p,q。然後根據 d * e %((p - 1) * (q - 1) == 1和擴展歐幾里得

求出e。

RSA是一種不可逆的加密方法,不可逆的原因是公鑰特別大,對它分解質因子時間上會很長,普通計算機大概是

10年左右,量子計算機一星期就可以了,基本不可能在常數時間分解出來;

本題能做的原因是公鑰n特別小(在RSA中,1e18已經算特別小)

1.首先我們要對n進行分解質因數

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define ll long long
#define mmset(a,b) memset(a,b,sizeof(a))  
#define UI64d unsigned __int64
UI64d FastPower(UI64d a , UI64d k);	
UI64d MOD = 1001733993063167141;



int main()
{
	UI64d res = 1001733993063167141;
	for(int i= 2; i * i < 1001733993063167141; i++)
	{
		while(res % i == 0 && res != 1) 
		{
			printf("%I64d %I64d\n",i,res / i);
			res /= i;
		}
	}
		
	
	return 0;
}

可得p = 891234941, q = 1123984201;

2.求解e

令 sum = (p-1) * (q-1) = 1001733991047948000;

那麼可得d * e % sum == 1, 這是一個典型的求解ax=c(mod b)問題。

也就是e*d =1(mod sum),我們可以用擴展歐幾里得算法來求解

爲防止溢出,我用的是python寫的


def computeD(fn, d):
    (x, y, r) = exGCD(fn, d)
   
    if y < 0:
        return fn + y
    return y
 
def exGCD(a, b):

    if b == 0:
        return (1, 0, a)
  
    x1 = 1
    y1 = 0

    x2 = 0
    y2 = 1
    while b != 0:
        q = a / b
    
        r = a % b
        a = b
        b = r
   
        x = x1 - q*x2
        x1 = x2
        x2 = x
   
        y = y1 - q*y2
        y1 = y2
        y2 = y
    return(x1, y1, a)
 
p = 891234941
q = 1123984201
d = 212353
 
sum = (p - 1) * (q - 1)
 
e = computeD(sum, d)
print e

e = 823816093931522017;

3.已知C,e,n,求解X = C^e mod n

   X是原文。

這一步思路很簡單,快速冪就行了,但是我用c++寫溢出了,只能用python

MOD = 1001733993063167141
def FastPower(a,k):
    res = a
    ans = 1
    while k != 0:
        if (k % 2) != 0:
            ans = (ans % MOD) * (res % MOD) % MOD
        res = (res % MOD) * (res % MOD) % MOD
        k = k / 2
    return ans
a = 20190324
k = 823816093931522017
res = FastPower(a1,k1)
print(res)
    

最終答案爲579706994112328949。

我們可以把這個明文帶去求密文的過程驗證一下看寫的對不對

得到密文20190320與題目一致,說明我們沒寫錯

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章