RSA加解密原理

0x01 前言

其实密码学一直是一个很有趣的领域,加密解密来防止消息被第三者得知。密码学被广泛应用在战争、互联网信息安全、日常生活。从1949年前的古典密码学,到近代密码学,再到现代密码学。密码学的发展,以及在密码学实现对信息的加密解密的背后,其数学原理其实更令人着迷。

0x02 非对称加密

  • 对称加密(Symmetric Cryptography),以 DES,AES,RC4 为代表。

采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。

RSA加解密原理_第1张图片

  • 非对称加密(Asymmetric Cryptography),以 RSA,ElGamal,椭圆曲线加密为代表。

非对称加密算法需要两个密钥: 公开密钥(publickey:简称公钥)和私有密钥(privatekey:简称私钥)。公钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。

RSA加解密原理_第2张图片

RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼	(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。

RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。

在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,由于无法计算出大数n的欧拉函数phi(N),所以不能根据PK计算出SK。

0x03 欧拉定理

欧拉定理得名于瑞士数学家莱昂哈德·欧拉,该定理被认为是数学世界中最美妙的定理之一。欧拉定理实际上是对费马小定理的一个拓展。

  • 费马小定理提出:如果p是一个质数,而整数a不是p的倍数,则有a^(p-1)≡1(mod p)。

也就是等价于

 (a^(p-1)) % p=1
  • 欧拉定理表明 若n,a为正整数,且n,a 互质,则有a^(φ(n))≡1(mod n)。

也就是说

(a^φ(n)) % n=1
  • 对于正整数n,欧拉函数是小于或等于n的正整数中与n互质的数的数目。

在n为质数时,与n互质的数为:1,2,3…n-1

互质的概念就是公约数只有1的两个整数,叫做互质整数。

因为n为质数,φ(n)为欧拉函数

所以得出φ(n)=n-1

也就是

(a^(n-1)) % n=1

所以说其实欧拉函数是费马小定理的一个拓展,将其拓展到了一个更广的适用范围。也就是去除了n为质数这一个条件的,更广的一个使用范围。
再给出欧拉函数的几条推论:

【1】欧拉函数是积性函数 ——若m,n互质,φ(mn)=φ(m)φ(n)

【2】特殊性质:当n为奇质数时,φ(2n)=φ(n)

【3】若n为质数则,φ(n)=n-1

0x04 RSA推导

首先介绍一下RSA实现基本加解密的原理。

  • 假设A要给B发送一条消息m。
  • 那么B要生成一对公钥(n,e)和私钥(n,d)。
  • 加密过程为A使用B的公钥对消息m进行加密,c=(m^e)%n
  • 解密过程为B收到A的密文c,使用私钥进行解密,m=(c^d)%n

n为两个大素数的乘积,d的条件为1

  • 这边提出一点,选取d和e需要满足
e*d≡1(mod φ(n))
也就是:
(e*d)%φ(n)=1

为什么是需要满足这个条件可以实现加解密?
RSA加解密原理_第3张图片

这边首先需要证明

RSA加解密原理_第4张图片

那么满足RSA加解密即需要满足

(m^(ed)) % φ(n)=m

欧拉定理为

(a^φ(n)) % n=1

RSA加解密原理_第5张图片

回到最初我们要证明

(m^(ed))%n =m

所以我们得到了

e*d=k*φ(n)+1

(e*d)%φ(n)=1

所以说选取d、e的条件为(de)≡1(mod φ(n)),也就是说(de)%φ(n)=1
通过上述推导d和e可以得到RSA的加解密本质上是根据欧拉定理得出的。

0x05 加解密Python实现

  • 基础RSA加密脚本
from Crypto.Util.number import *
import gmpy2()()
msg = 'flag is :testflag'
hex_msg=int(msg.encode("hex"),16)
print(hex_msg)
p=getPrime(100)
q=getPrime(100)
n=p*q
e=0x10001
c=pow(hex_msg,e,n)
print("e=",hex(e))
print("n=",hex(n))
print("c=",hex(c))

  • 基础RSA解密脚本
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import binascii
import gmpy2
n=0x80b32f2ce68da974f25310a23144977d76732fa78fa29fdcbf
#这边我用yafu分解了n
p=780900790334269659443297956843
q=1034526559407993507734818408829
e=0x10001
c=0x534280240c65bb1104ce3000bc8181363806e7173418d15762
phi=(p-1)*(q-1)
d=gmpy2.invert(e,phi)
m=pow(c,d,n)
print(hex(m))
print(binascii.unhexlify(hex(m)[2:].strip("L")))

0x06 参考资料

  • 对称加密百度百科:https://baike.baidu.com/item/%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86/2152944?fr=aladdin
  • 非对称加密百度百科:https://baike.baidu.com/item/%E9%9D%9E%E5%AF%B9%E7%A7%B0%E5%8A%A0%E5%AF%86%E7%AE%97%E6%B3%95/1208652?fr=aladdin
  • RSA算法百度百科:https://baike.baidu.com/item/RSA%E7%AE%97%E6%B3%95/263310?fromtitle=RSA&fromid=210678&fr=aladdin
  • RSA的证明:https://blog.csdn.net/desert187/article/details/51123269

你可能感兴趣的:(CTF)