RSA ,python

非对称的加密算法,能够保证加密数据的机密性

why?

RSA算法的难解性取决于大素数的分解难度,在有限算力的情况下是不能破解的。

how?

一、密钥的产生


1 选取两个保密的大素数 p 和 q

2 计算 n=pq , fai(n) = (p-1)(q-1)

3 选一整数 e, 满足 1<e<fai(n), gcd(fai(n),e)=1

4 计算d, 满足 d.e=1 mod fai(n)

二、加密


1 将明文比特串分组,使得每个分组对应的十进制数小于n(分组长度< \(log_2n\))

\[c=m^c mod n \]

三、解密


解密运算 \(m=c^d mod n\)

填充模式

1、RSA_PKCS1_PADDING 填充模式(常用)

要求

INPUT:必须必模长(e)短至少11个字节,即 RSA_size(rsa) – 11。如果输入的明文过长,必须切割,然后进行填充。

OUTPUT: 与模(e)一样长

据此要求:

对于512bit的密钥, 填充的长度为 512/8-11=53字节

对于1024bit的密钥, 填充的长度为 1024/8-11=117字节

对于2048bit的密钥, 填充的长度为 2048/8-11=245字节

对于4096bit的密钥, 填充的长度为 4096/8-11=501字节

2、RSA_PKCS1_OAEP_PADDING

要求

INPUT:RSA_size(rsa) – 41

OUTPUT: 与模(e)一样长

3、for RSA_NO_PADDING 不填充

INPUT:可以和RSA钥模长一样长,如果输入的明文过长,必须切割, 然后填充

OUTPUT:和模(e)一样长

代码

#/usr/bin/env python
# -*- coding: utf-8 -*-

#----rsa 算法 ------#
"""
1 选取两个保密的大素数 p 和 q
2 计算 n=p*q , fai(n) = (p-1)*(q-1)
3 选一整数 e, 满足 1<e<fai(n), gcd(fai(n),e)=1
4 计算d, 满足 d.e=1 mod fai(n)
=> (e,n)为公钥 ; (d,n)为私钥

e : 模数默认情况下为65537(HEX:10001)

"""
import rsa
import sys
import base64
# 打印 python 版本 与 windows 系统编码
print("---- 1 ----")
print(sys.version)
print(sys.getdefaultencoding())
print(sys.getfilesystemencoding())
# 先生成一对密钥,然后保存.pem格式文件,当然也可以直接使用
print("---- 2 ----")
(pubkey, privkey) = rsa.newkeys(1024) # 随机生成1024bit的公私钥
pub = pubkey.save_pkcs1()
print(type(pub))
pubfile = open('public.pem','w+')
pubfile.write(pub.decode('utf-8'))
pubfile.close()
print("---- 3 ----")
pri = privkey.save_pkcs1()
print(type(pri))
prifile = open('private.pem','w+')
prifile.write(pri.decode('utf-8'))
prifile.close()
# load公钥和密钥
print("---- 4 ----")
message = 'helloxpp'
print('message:',type(message))
with open('public.pem') as publickfile:
 p = publickfile.read()
 print(type(p))
 pubkey = rsa.PublicKey.load_pkcs1(p.encode('utf-8')) #pkcs1_padding
with open('private.pem') as privatefile:
 p = privatefile.read()
 print(type(p))
 privkey = rsa.PrivateKey.load_pkcs1(p.encode('utf-8')) # pkcs1_padding
# 用公钥加密、再用私钥解密
crypto = rsa.encrypt(message.encode('utf-8'),pubkey)
print(crypto)
print("---- 5 ----")
print('crypto:',type(crypto))
print('cry_base64:',base64.encodebytes(crypto))
print('cry_base64_utf8:',base64.encodebytes(crypto).decode('utf-8'))
# 保存到本地文件
cry_file = open('cry_file.txt','w+')
cry_file.write(base64.encodebytes(crypto).decode('utf-8'))
cry_file.close()
print("---- 6 ----")
# 从本地文件读取
cry_file = open('cry_file.txt','r')
cry_text = ''
for i in cry_file.readlines():
 cry_text += i
print('cry_text_type:',type(cry_text))
print('cry_text:',cry_text)
print('cry_base64:',cry_text.encode('utf-8'))
crypto_tra = base64.decodebytes(cry_text.encode('utf-8'))
print("---- 7 ----")
assert crypto == crypto_tra
print(crypto)
print("---- 8 ----")
plaintext = rsa.decrypt(crypto,privkey)
assert message == plaintext.decode('utf-8')
print(plaintext.decode('utf-8'))