当前位置: 首页 > java >正文

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)=(p1)(q1)

(3)计算 d d d在模 ϕ ( n ) \phi(n) ϕ(n)下的逆元,也就是满足 e d ≡ 1 ( m o d ϕ ( n ) ) ed \equiv1\quad(\ \bmod \ \phi(n)) ed1( mod ϕ(n))

(4)选取明文 m , 0 ≤ m < n m, 0 \le m <n m,0m<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)dm( 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)dmed( mod n)
因此我们的证明目标变成了
m e d ≡ m ( m o d n ) m^{ed} \equiv m\quad (\ \bmod\ n) medm( mod n)
已知 e d ≡ 1 ( m o d ϕ ( n ) ) ed \equiv 1 \quad(\ \bmod \phi(n)\ ) ed1( 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)+1m( 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)+1m( mod n)
gcd ⁡ ( m , n ) ≠ 1 \gcd(m,n) \ne 1 gcd(m,n)=1,那么必有 p ∣ m p \mid m pm或者 q ∣ m q \mid m qm; 我们假设 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)+1mϕ(n)m0( 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(p1)(q1)
由于 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) mq11( 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(p1)(q1)(mq1)k(p1)1( mod q)mk(p1)(q1)+1m( 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)+1m( mod p)mkϕ(n)+1m( 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)+1m(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 510 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) ab( mod n)n(ab)。例子 2 2 2 7 7 7 5 5 5同余。 2 ≡ 7 ( m o d 5 ) 2 \equiv 7 \quad (\ \bmod \ 5) 27( 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) ab(a modn)ba(b modn)
    • 如果 a ≡ b ( m o d n ) a \equiv b \quad (\ \bmod\ n) ab( 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±cb±c( mod n)acbc( 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)=1ab( mod m)ab( mod n)ab( mod mn)

  • 费马小定理: 如果 p p p是一个质数,那么
    a p − 1 ≡ 1 ( m o d p ) a^{p-1} \equiv 1\quad (\ \bmod \ p) ap11( 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也像是抄得上面那个网页上的。。。

http://www.xdnf.cn/news/5652.html

相关文章:

  • Python爬虫如何获取JavaScript动态渲染后的网页内容?
  • VUE3基础样式调整学习经验
  • yarn workspace使用指南
  • 配置集群(yarn)
  • 消息队列如何保证消息可靠性(kafka以及RabbitMQ)
  • MySQL全量、增量备份与恢复
  • Qt创建项目
  • 基于千眼狼高速摄像机与三色掩模的体三维粒子图像测速PIV技术
  • 前苹果首席设计官回顾了其在苹果的设计生涯、公司文化、标志性产品的背后故事
  • CentOS下安装MySQL数据库
  • node .js 启动基于express框架的后端服务报错解决
  • WEB安全--RCE--webshell bypass2
  • NestJS 知识框架
  • 区块链大纲笔记
  • 人脸识别deepface相关笔记
  • 物联网无线传感方向专业词汇解释
  • git|gitee仓库同步到github
  • JDK动态代理和CGLIB动态代理的区别?
  • 《Head First 设计模式》第一章 - 笔记
  • 关于nextjs中next-sitemap插件生成文件样式丢失问题及自定义样式处理
  • 开启WSL的镜像网络模式
  • git和gdb
  • 《Flutter社交应用暗黑奥秘:模式适配与色彩的艺术》
  • hashCode()和equals(),为什么使用Map要重写这两个,为什么重写了hashCode,equals也需要重写
  • Decimal.js 的常用方法
  • HNUST软件测试B考前最终复习
  • 密码学--仿射密码
  • 配置文件介绍xml、json
  • (自用)Java学习-5.12(Redis,B2C电商)
  • 【A2A】根据A2A的协议标准,不同架构的2个大模型agent的交互,是否都需要实现和对接 client和server模块?