RSA算法详解一:初识RSA
1. 简介
RSA算法是一种比较经典的公钥算法,可用来加解密和签名。
如果你不想从数学证明方面理解这个算法,你只需要知道他利用的是
大质数分解的复杂性就可以了。
当然你也可以简单的看一下,数学描述和证明。
所需要的数学知识就是初等数论的一些基本定理,附在了文后。
2. 算法简单描述
(1) 选定两个质数 p , q p,q p,q, n n n表示为两个质数的乘积 n = p q n=pq n=pq。
(2)选取公钥指数 e e e满足 gcd ( e , ϕ ( n ) ) = 1 \gcd(e, \phi(n))=1 gcd(e,ϕ(n))=1, gcd ( e , ϕ ( n ) ) = 1 \gcd(e, \phi(n))=1 gcd(e,ϕ(n))=1是
为了保证 e e e在模 ϕ ( n ) \phi(n) ϕ(n)下有逆元 d d d; 其中 ϕ ( n ) \phi(n) ϕ(n)是欧拉函数, ϕ ( n ) = ( p − 1 ) ( q − 1 ) \phi(n)=(p-1)(q-1) ϕ(n)=(p−1)(q−1)。
(3)计算 d d d在模 ϕ ( n ) \phi(n) ϕ(n)下的逆元,也就是满足 e d ≡ 1 ( m o d ϕ ( n ) ) ed \equiv1\quad(\ \bmod \ \phi(n)) ed≡1( mod ϕ(n))
(4)选取明文 m , 0 ≤ m < n m, 0 \le m <n m,0≤m<n, 执行加密操作 c = m e m o d n c=m^e \mod n c=memodn
(5)将得到的密文操作 c c c, 执行解密操作 m = c d m o d n m=c^d \mod n m=cdmodn
3. 数学证明
实际上我们需要证明的就是
c d ≡ ( m e m o d n ) d ≡ m ( m o d n ) c^d \equiv(m^e\ \bmod n)^d\equiv m \quad (\ \bmod \ n) cd≡(me modn)d≡m( mod n)
根据同余的性质,我们可以得到
( m e m o d n ) d ≡ m e d ( m o d n ) (m^e\ \bmod n)^d \equiv m^{ed} \quad ( \ \bmod\ n) (me modn)d≡med( mod n)
因此我们的证明目标变成了
m e d ≡ m ( m o d n ) m^{ed} \equiv m\quad (\ \bmod\ n) med≡m( mod n)
已知 e d ≡ 1 ( m o d ϕ ( n ) ) ed \equiv 1 \quad(\ \bmod \phi(n)\ ) ed≡1( modϕ(n) ), 那么 e d ed ed可表示为
e d = k ϕ ( n ) + 1 ed =k\phi(n)+1 ed=kϕ(n)+1
证明等价于
m k ϕ ( n ) + 1 ≡ m ( m o d n ) m^{k\phi(n)+1} \equiv m \quad (\ \bmod \ n) mkϕ(n)+1≡m( mod n)
若 gcd ( m , n ) = 1 \gcd(m,n)=1 gcd(m,n)=1, 根据欧拉定理可得
m ϕ ( n ) ≡ 1 ( m o d n ) m k ϕ ( n ) ≡ 1 ( m o d n ) m k ϕ ( n ) + 1 ≡ m ( m o d n ) m^{\phi(n)} \equiv1\quad( \ \bmod\ n)\\ m^{k\phi(n)} \equiv 1 \quad (\ \bmod\ n)\\ m^{k\phi(n)+1} \equiv m \quad (\ \bmod \ n) mϕ(n)≡1( mod n)mkϕ(n)≡1( mod n)mkϕ(n)+1≡m( mod n)
若 gcd ( m , n ) ≠ 1 \gcd(m,n) \ne 1 gcd(m,n)=1,那么必有 p ∣ m p \mid m p∣m或者 q ∣ m q \mid m q∣m; 我们假设 m = s p m=sp m=sp, 即 p p p整除 m m m。
那么显然有
m k ϕ ( n ) + 1 ≡ m ϕ ( n ) ≡ m ≡ 0 ( m o d p ) m^{k\phi(n)+1} \equiv m^{\phi(n)}\equiv m \equiv 0 \quad (\ \bmod \ p) mkϕ(n)+1≡mϕ(n)≡m≡0( mod p)
将 ϕ ( n ) \phi(n) ϕ(n)展开代入 m ϕ ( n ) m^{\phi(n)} mϕ(n)
m ϕ ( n ) = m ( p − 1 ) ( q − 1 ) m^{\phi(n)}=m^{(p-1)(q-1)} mϕ(n)=m(p−1)(q−1)
由于 gcd ( q , m ) = 1 \gcd(q,m)=1 gcd(q,m)=1,根据欧拉定理或者费马小定理我们有
m q − 1 ≡ 1 ( m o d q ) m^{q-1} \equiv 1 \quad(\ \bmod\ q) mq−1≡1( mod q)
因此
m k ( p − 1 ) ( q − 1 ) ≡ ( m q − 1 ) k ( p − 1 ) ≡ 1 ( m o d q ) m k ( p − 1 ) ( q − 1 ) + 1 ≡ m ( m o d q ) m^{k(p-1)(q-1)} \equiv (m^{q-1})^{k(p-1)}\equiv1 \quad (\ \bmod \ q)\\ m^{k(p-1)(q-1)+1} \equiv m \quad (\ \bmod \ q) mk(p−1)(q−1)≡(mq−1)k(p−1)≡1( mod q)mk(p−1)(q−1)+1≡m( mod q)
由于 gcd ( p , q ) = 1 \gcd(p,q)=1 gcd(p,q)=1, 又有
m k ϕ ( n ) + 1 ≡ m ( m o d p ) m k ϕ ( n ) + 1 ≡ m ( m o d q ) m^{k\phi(n)+1} \equiv m \quad (\ \bmod \ p)\\ m^{k\phi(n)+1} \equiv m \quad (\ \bmod \ q) mkϕ(n)+1≡m( mod p)mkϕ(n)+1≡m( mod q)
因此
m k ϕ ( n ) + 1 ≡ m ( m o d n = p q ) m^{k\phi(n)+1} \equiv m \quad( \bmod \ n=pq) mkϕ(n)+1≡m(mod n=pq)
4. 代码
由于 R S A RSA RSA现在推荐使用的位数已经到了2048位置,所以随机选取 m m m
gcd ( m , n ) ≠ 1 \gcd(m, n) \ne 1 gcd(m,n)=1的概率是非常低的,所以可以忽略不计。
在 p q p\ q p q选取很小的时候,如果 gcd ( m , n ) ≠ 1 \gcd(m,n)\ne1 gcd(m,n)=1时,是容易出现加密后 c = m c=m c=m的情况的。
#include <iostream>using ll = long long;template<typename T>
T gcd(T a,T b)
{while (b) {T tmp = b;b = a % b;a = tmp;}return a;
}
template<typename T>
T fpow(T a, T b, T MOD)
{T base = a;T res = 1;while (b) {if ( b & 1) res = (res * base) % MOD;base = (base * base) % MOD;b >>= 1;}return res;
}
template<typename T>
T exgcd(T a, T b, T &x, T &y) {if ( b == 0) {x = 1;y = 0;return a;}T x_0;T y_0;T d = exgcd( b, a % b, x_0, y_0);x = y_0;y = x_0 - (a / b) * y_0;return d;
}ll choose_e( ll phi_N)
{for ( ll i = 10; i < phi_N; i++) {if ( gcd(phi_N, i) == 1) return i;}return -1;
}
bool get_e_and_d( ll phi_N, ll &e, ll &d)
{for ( ll i = 10; i < phi_N; i++) {if ( gcd(phi_N, i) != 1) continue;ll tmp;exgcd( i, phi_N, d, tmp);if ( d < 0) d += phi_N;e = i;if (i != d) {return true;}else {printf("warning: e = d = %lld\n", e);return true;}}return false;
}
void rsa()
{ll p = 11;ll q = 17;ll N = p * q;ll phi_N = (p - 1) * (q - 1);ll e;ll d;if (!get_e_and_d( phi_N, e, d)) {printf("get e and d failed!!!\n");return;}printf("e: %lld, d: %lld\n", e, d);for ( ll i = 1; i < q; i++) {ll m = i * p;ll c = fpow( m, e, N);printf("plain: %lld\n", m );if ( c == m) {printf("cipher is equal to plain!!!\n");}else {printf("cipher is: %lld\n", c);}ll dc = fpow(c, d, N);printf("decrypt is %lld\n", dc);if ( dc == m) {printf("rsa encode decode success!!!\n");}else {printf("rsa encode decode failed!!!\n");}printf("\n");}}void test_gcd()
{printf("gcd(12, 15) = %d\n", gcd(12, 15));printf("gcd(3,5) = %d\n", gcd( 3, 5));printf("gcd(32, 48) = %d\n", gcd( 32, 48));}int main()
{//test_gcd();rsa() ;return 0;
}
5. 相关数学知识
-
质数: 一个除只能被 1 1 1和本身整除,如 3 5 7 11 13 3\ 5\ 7\ 11\ 13 3 5 7 11 13
-
公因数:能同时整除多个数的数,比如 2 2 2是 4 4 4和 6 6 6的公因数
-
最大公因数:用 gcd ( ) 表示 \gcd()表示 gcd()表示,如 gcd ( 4 , 6 ) = 2 \gcd(4,6)=2 gcd(4,6)=2
-
互质:两个数的的公因数为 1 1 1, gcd ( 5 , 3 ) = 1 \gcd(5,3)=1 gcd(5,3)=1
-
整除: ∣ \mid ∣表示, 一个数是另外一个数的因数。比如 5 ∣ 10 5 \mid 10 5∣10, 2 × 5 = 10 2\times5 =10 2×5=10。
-
取余(模):用 m o d \bmod mod表示,指一个数整除另外一个数余下的数,比如 12 m o d 5 = 2 12 \ \bmod 5 =2 12 mod5=2, 因为 12 = 2 × 5 + 2 12 =2\times5+2 12=2×5+2
-
同余:指两个数模另外一个数余下的数相同,用 ≡ \equiv ≡表示。就是两个数相减是模数的倍数。 a ≡ b ( m o d n ) ⇒ n ∣ ( a − b ) a\equiv b \quad( \ \bmod \ n) \Rightarrow n \mid (a-b) a≡b( mod n)⇒n∣(a−b)。例子 2 2 2和 7 7 7对 5 5 5同余。 2 ≡ 7 ( m o d 5 ) 2 \equiv 7 \quad (\ \bmod \ 5) 2≡7( mod 5)
-
同余性质:
- 取模
a ≡ b ⇔ ( a m o d n ) ≡ b ⇔ a ≡ ( b m o d n ) a\equiv b \Leftrightarrow (a\ \bmod n) \equiv b \Leftrightarrow a \equiv (b\ \bmod n) a≡b⇔(a modn)≡b⇔a≡(b modn) - 如果 a ≡ b ( m o d n ) a \equiv b \quad (\ \bmod\ n) a≡b( mod n) , 那么有
a ± c ≡ b ± c ( m o d n ) a c ≡ b c ( m o d n ) a\pm c \equiv b \pm c \quad (\ \bmod \ n)\\ ac\equiv bc \quad (\ \bmod \ n) a±c≡b±c( mod n)ac≡bc( mod n)
- 取模
-
引理:用作证明的最后一步
gcd ( m , n ) = 1 a ≡ b ( m o d m ) a ≡ b ( m o d n ) ⇒ a ≡ b ( m o d m n ) \gcd(m, n) = 1\\ a \equiv b \quad (\ \bmod\ m)\\ a \equiv b \quad (\ \bmod\ n)\\ \Rightarrow a \equiv b \quad (\ \bmod\ mn) gcd(m,n)=1a≡b( mod m)a≡b( mod n)⇒a≡b( mod mn) -
费马小定理: 如果 p p p是一个质数,那么
a p − 1 ≡ 1 ( m o d p ) a^{p-1} \equiv 1\quad (\ \bmod \ p) ap−1≡1( mod p) -
欧拉函数 ϕ ( n ) \phi(n) ϕ(n):小于等于 n n n的正整数中与 n n n互质的数的个数,比如 ϕ ( 12 ) = 4 \phi(12)=4 ϕ(12)=4, 其中 1 5 7 11 1\ 5\ 7\ 11 1 5 7 11和 12 12 12互质。
-
欧拉定理:费马小定理的升级版,如果 gcd ( a , n ) = 1 \gcd(a, n)=1 gcd(a,n)=1,那么
a ϕ ( n ) ≡ 1 ( m o d n ) a^{\phi(n)} \equiv 1\quad (\ \bmod\ n) aϕ(n)≡1( mod n)
参考
di-mgt
ctf-wiki
感觉ctf-wiki也像是抄得上面那个网页上的。。。