Python实现RSA公钥加密算法
RSA公钥加密算法原理
1、RSA公钥加密算法属于非对称密码,因此有一对密钥,公钥和私钥,Ron Rivest, Adi Shamir和Len Adleman于1977年研制并于1978年首次发表;
2、RSA是一种分组密码,其理论基础是一种特殊的可逆模幂运算,其安全性基于分解大整数的困难性,即将两个大素数相乘非常容易,但是想对其乘积进行因式分解是十分困难的,因此将其乘积公开作为加密密钥(公钥)
3、对一个极大的整数做因数分解愈困难,RSA算法越可靠;
4、RSA既可用于加密,又可用于数字签名,已得到广泛采用;
5、RSA加解密过程图解如下:
6、RSA算法流程:
RSA算法的Python实现
PS:求幂次的模拟(mod)为平方乘的方法进行计算,未调用Python中的RSA包
1、程序如下:
import random
import binascii
import argparse # 导入读取命令行参数的模块
import sys
sys.setrecursionlimit(100000) # 设置迭代次数限制
def main():
Build_key() # 生成公钥、密钥
parser = argparse.ArgumentParser(
description="This is a description, it includes the whole file's loactions of RSA algorithm.")
parser.add_argument('-p', required=True, type=argparse.FileType('r'), help='plainfile')
parser.add_argument('-n', required=True, type=argparse.FileType('r'), help='nfile')
parser.add_argument('-e', required=False, type=argparse.FileType('r'), help='efile') # e,d文件不是都要的,只需一个
parser.add_argument('-d', required=False, type=argparse.FileType('r'), help='dfile')
parser.add_argument('-c', required=True, type=argparse.FileType('w+'), help='cipherfile')
args = parser.parse_args() # args里面的成员是一个文件对象,所以后面写入文件的形式和一般的一样
n = int(args.n.read(), 16)
m = args.p.read()
if m == '':
print('No PlainText!')
else:
print("Encrypting......")
e = int(args.e.read(), 16)
cipher = encrypt(m, e, n)
with args.c as f:
f.write(cipher)
print("Encrypted!\r\nThe Cipher is:", cipher)
c = cipher # 读取密文
if c == '':
print("No Cipher!")
else:
print("Decrypting......")
d = int(args.d.read(), 16)
plain = decrypt(c, d, n)
print("Decrypted!\r\nThe PlainText is:", plain)
# 平方—乘法,最后返回结果
def MRF(b, n, m):
a = 1
x = b
y = n
z = m
binstr = bin(n)[2:][::-1] # 通过切片去掉开头的0b,截取后面,然后反转
for item in binstr:
if item == '1':
a = (a * b) % m
b = (b ** 2) % m
elif item == '0':
b = (b ** 2) % m
return a
# 素性检验
def MillerRabin(n):
"利用Miller-Rabin算法检验生成的奇数是否为素数"
m = n - 1
k = 0
while (m % 2 == 0):
m = m // 2 #m整除2
k = k + 1
a = random.randint(2, n)#生成随机数2<=a<=n
# b=a**m%n
b = MRF(a, m, n) #快速乘进行检验
if (b == 1):
return 1
for i in range(k):
if (b == n - 1):
return 1
else:
b = b * b % n
return 0
# 生成大素数,20次MillerRabin算法缩小出错的概率
def BigPrime():
Min = 10 ** 11 #**幂运算
Max = 10 ** 15
p = 0
while (1):
p = random.randrange(Min, Max, 1)#寻找min和max中的随机数p
#生成大素数p
for i in range(20):
if MillerRabin(p) == 0:
break
elif i == 19:
return p
# 加密,传入公钥,通过读取明文文件进行加密
def encrypt(m, e, n):
cipher = ""
nlength = len(str(hex(n))[2:]) # 计算n的16进制长度,以便分组
message = m # 读取明文
for i in range(0, len(message), 8):#8个字节为一组
if i == len(message) // 8 * 8:
m = int(a2hex(message[i:]), 16) # 最后一个分组
m = int(a2hex(message[i:i + 8]), 16)
c = MRF(m, e, n)
cipher1 = str(hex(c))[2:]
if len(cipher1) != nlength:
cipher1 = '0' * (nlength - len(cipher1)) + cipher1 # 每一个密文分组,长度不够,高位补0
cipher += cipher1
return cipher
# 解密,传入私钥,通过文件读写进行解密
def decrypt(c, d, n):
# 加密之后每一个分组的长度和n的长度相同
cipher = c
message = ""
nlength = len(str(hex(n))[2:])
for i in range(0, len(cipher), nlength):
c = int(cipher[i:i + nlength], 16) # 得到一组密文的c
m = MRF(c, d, n)
info = hex2a(str(hex(m))[2:])
message += info
f_write("RSA_decrypted.txt", message)
return message
# 求最大公因子
def gcd(a, b):
if a % b == 0:
return b
else:
return gcd(b, a % b)
# 求逆元欧几里得辗转相乘法计算逆
def Ex_Euclid(x, n):
r0 = n
r1 = x % n
if r1 == 1:
y = 1
else:
s0 = 1
s1 = 0
t0 = 0
t1 = 1
while (r0 % r1 != 0):
q = r0 // r1
r = r0 % r1
r0 = r1
r1 = r
s = s0 - q * s1
s0 = s1
s1 = s
t = t0 - q * t1
t0 = t1
t1 = t
if r == 1:
y = (t + n) % n
return y
# 写入文件
def f_write(filename, message):
f = open(filename, 'w')
f.write(message)
f.close()
return 0
# ascii_to_hex
def a2hex(raw_str):
hex_str = ''
for ch in raw_str:
hex_str += hex(ord(ch))[2:]
return hex_str
# hex_to_ascii
def hex2a(raw_str):
asc_str = ''
for i in range(0, len(raw_str), 2):
asc_str += chr(int(raw_str[i:i + 2], 16))
return asc_str
def Build_key():
# 产生p,q,n,e,d
p = BigPrime()
q = BigPrime()
n = p * q
_n = (p - 1) * (q - 1) # n的欧拉函数
e = 0
while (1):
e = random.randint(1, _n + 1)
if gcd(e, _n) == 1:
break
d = Ex_Euclid(e, _n)
# 写入文件
f_write('p.txt', str(hex(p))[2:])
f_write('q.txt', str(hex(q))[2:])
f_write('n.txt', str(hex(n))[2:])
f_write('e.txt', str(hex(e))[2:])
f_write('d.txt', str(hex(d))[2:])
if __name__ == "__main__":
main()
2、运行截图
3、加解密文件
AES加解密算法实现
AES加解密算法原理
1、AES算法由比利时密码学家Joan Daemen 和 Vincent Rijmen 提出;
2、AES算法的原型是Square算法,其设计策略是宽轨迹策略(Wide Trail Strategy),以针对差分分析和线性分析;
3、AES是迭代分组密码,其分组长度和密钥长度都是可变的;为了满足AES的要求,分组长度为128bit,密码长度为128/192/256bit,相应的轮数r为10/12/14;
4、算法流程图:
AES加解密算法Python实现
1、Python代码如下(PS:AES的实现是调用的Python中的AES包实现)
from Crypto.Cipher import AES
from binascii import b2a_hex
from binascii import a2b_hex
import sys
import binascii
def encrypt(plain, iv, key):
if len(key) != 16 and len(key) != 24 and len(key) != 32:
print("[-] AES key must be 16/24/32 bytes long!")
return False
key = key.encode('utf8')
iv = iv.encode('utf8')
cryptos = AES.new(key, AES.MODE_CBC, iv)
ciphertext = cryptos.encrypt(plain.encode('utf8'))
return ciphertext
def decrypt(ciphertext, iv, key):
key = key.encode('utf8') #string->bytes
iv = iv.encode('utf8')
decrypto = AES.new(key, AES.MODE_CBC, iv)
plaintext = decrypto.decrypt(ciphertext)
return plaintext
if __name__ == "__main__":
plain = 'AESPython_Jody23'
iv = '12345678dc123478'
key = '0CoJUm6Qyw8W8jud'
ciphertext = encrypt(plain,iv,key)
print("Encrypt: ")
print(ciphertext)
plaintext = decrypt(ciphertext,iv,key)
print("Decrypt: ")
print(plaintext.decode('utf8'))
2、运行截图