RSA算法简介
RSA是一种非对称算法,也称公钥密码算法。所谓公钥密码算法,是指加密和解密使用不同的密码的方式,因此公钥密码通常也称为非对称密码。
RSA于1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA算法的地位:是现今使用最广泛的公钥密码算法,普遍认为是目前最优秀的公钥方案之一。
RSA算法在我国的现状:
- 由于RSA算法1024位密钥面临严重的安全威胁,为保障电子认证服务安全应用,2016年12月5日,上海市密码管理局在其官方网站上发布公告,称从2017年1月1日起停止提供RSA算法1024位密钥对服务,并配合电子认证服务机构和应用单位做好应对措施,确保平稳过渡。
- 在国密改造过程中,被SM2取代。
RSA算法特点:
- 是一种公钥密码算法,也称非对称密码算法。
- 密钥包括公钥和私钥,公钥可以对外公开,私钥不公开。公钥和私钥不相同。公钥用于加密,私钥用于解密。
- 由已知加密密钥(公钥)推导出解密密钥在计算上是不可行的。
- 加密算法和解密算法也都是公开的。
- RSA允许你选择公钥的大小。512位的密钥被视为不安全的;768位的密钥不用担心受到除了国家安全管理(NSA)外的其他事物的危害。
- 应用广泛。RSA在一些主要产品内部都有嵌入,像 Windows、网景 Navigator、 Quicken和 Lotus Notes。
- 同样的公钥,同样的数据,两次加密的结果是不相同的,但是,并不影响解密。
- 常见的非对称加密: RSA, DSA, SM2。
RSA加密算法原理:
RSA公开密钥密码体制的原理是:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
公钥: (E,N)
私钥 :(D,N)
密钥对: (E,D,N)
加密:
密文=明文EmodN密文=明文EmodN
解密:
明文=密文DmodN明文=密文DmodN
这个过程可以描述为:
(1)任意选取两个不同的大素数p和q计算乘积 ;
(2)任意选取一个大整数e,满足 ,整数e用做加密钥(注意:e的选取是很容易的,例如,所有大于p和q的素数都可用);
(3)确定的解密钥d,满足 ,即 是一个任意的整数;所以,若知道e和,则很容易计算出d ;
(4)公开整数n和e,秘密保存d ;
(5)将明文m(m<n是一个整数)加密成密文c
(6)将密文c解密为明文m
然而只根据n和e(注意:不是p和q)要计算出d是不可能的。因此,任何人都可对明文进行加密,但只有授权用户(知道d)才可对密文解密。
利用python进行RSA加密和解密
密钥对的生成
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto import Random
import base64
#创建非对称密钥
def create_key():
random_generator = Random.new().read
rsakey = RSA.generate(1024,random_generator)
#保存公钥到文件
with open("public_rsa.pem", mode="wb") as f:
f.write(rsakey.publickey().exportKey())
#保存私钥到文件
with open("private_rsa.pem", mode="wb") as f:
f.write(rsakey.exportKey())```
加密与解密
def rsa_encode(data):
with open("public_rsa.pem", mode="r") as f:
key = f.read()
pub_key = RSA.importKey(key)
rsa = PKCS1_v1_5.new(pub_key)
result = rsa.encrypt(data.encode("utf-8"))
# 处理成b64方便传输
b64_result = base64.b64encode(result).decode("utf-8")
print(b64_result)
def rsa_decode(cipher_data):
# 解密
with open("private_rsa.pem", mode="r") as f:
key = f.read()
pri_key = RSA.importKey(key)
rsa = PKCS1_v1_5.new(pri_key)
result = rsa.decrypt(base64.b64decode(cipher_data), 0)
print(result.decode("utf-8"))
# main
if __name__ == '__main__':
#print("rsa create key begin");
#create_key();
data = "有年终奖么?"
rsa_encode(data);
cipher_data = "rVRWaQqCJI0bWzrqv+UumdswKBrt9GIcUhxDl0R8Al54x6yDq+YBewlArygk/kGx972M2iWElQm3OXKLOwY6+Jwc6mZY2yzWzhYcxUDRgMNI9c35w1ZYAQgCGPmwo+DuprH0ieUwz57sOxgTY5Ac9e4Ua2krmG6fUW6OAIiFkDhBNdgyHqyzNoM7tpgo5oXk1VM5IuA6Lf64i3OTeB+8DO5sHeyyZmSUv19TfKivLhrF+Ee5d8MMaF49eQscLuPJCg1zhLINQzZkk9mxl64pi1EVd0p4Sy7Bypi8ywMBTErxlUVkWc4jqYIPNZps2cqrDL5MFZktIzh+SQk50gAS7A=="
rsa_decode();
运行结果:
rVRWaQqCJI0bWzrqv+UumdswKBrt9GIcUhxDl0R8Al54x6yDq+YBewlArygk/kGx972M2iWElQm3OXKLOwY6+Jwc6mZY2yzWzhYcxUDRgMNI9c35w1ZYAQgCGPmwo+DuprH0ieUwz57sOxgTY5Ac9e4Ua2krmG6fUW6OAIiFkDhBNdgyHqyzNoM7tpgo5oXk1VM5IuA6Lf64i3OTeB+8DO5sHeyyZmSUv19TfKivLhrF+Ee5d8MMaF49eQscLuPJCg1zhLINQzZkk9mxl64pi1EVd0p4Sy7Bypi8ywMBTErxlUVkWc4jqYIPNZps2cqrDL5MFZktIzh+SQk50gAS7A==
有年终奖么?