公钥密码算法也叫非对称加密,主要有RSA算法、Elgamal算法、ECC算法。RSA算法是基于大素数难分解这一数学难题而提出的(两个大质数相乘得到的大数难以被因式分解),原理如下:
假设明文为 m ,则密文为c,c = me mod n.
假设明文c,则密文为m,m=cd mod n.
def ex_gcd(a,b):
'''
扩展欧几里德算法
'''
if b == 0:
return 1,0
else:
q = a // b
r = a % b
s,t = ex_gcd(b,r)
s,t = t,s-q*t
return [s,t]
#快速幂算法
def fast_expmod(a,e,n):
"""
快速幂
"""
d = 1
while e !=0:
if(e&1) == 1:
d = (d * a) % n
e >>= 1
a = a * a % n
return d
def make_key(p,q,e):
"""
生成公私钥
参数1:大素数p
参数2:大素数q
参数3:随机生成e,满足 gcd(e,fin)
返回值:[公钥,私钥]-------[[n,e],[n,d]]
"""
n = p * q
fin = (p-1) * (q-1)
d = ex_gcd(e,fin)[0] #辗转相除法求逆(广义欧几里得)
while d < 0:
d = (d+fin)%fin
return [[n,e],[n,d]]
def encryption(key,data):
"""
加密
参数1:列表[n,e]----公钥
参数2:待价密数据
返回值:密文
"""
n,e = key
plaintext = list(data)
ciphertext=[]
for item in plaintext:
ciphertext.append(fast_expmod(ord(item),e,n))
return ciphertext
def decrypt(key,ciphertext):
"""
解密
参数1:key为私钥
参数2:密文数据
返回值:明文
"""
n,d = key
plaintext = ''
for item in ciphertext:
plaintext += (chr(fast_expmod(item,d,n)))
return plaintext
def make_p_q_e():
"""
返回值:[p,q,e]
"""
p=33478071698956898786044169848212690817704794983713768568912431388982883793878002287614711652531743087737814467999489
q=36746043666799590428244633799627952632279158164343087642676032283815739666511279233373417143396810270092798736308917
e = 65537
return [p,q,e]
def test():
p,q,e = make_p_q_e()
#获取数据
plaintext = input("待加密数据:")
#公钥、私钥
public_key,private_key=make_key(p,q,e)
#加密
ciphertext = encryption(public_key,plaintext)
print("加密后的数据:",ciphertext)
#解密
plaintext = decrypt(private_key,ciphertext)
print("解密后的数据:",plaintext)
test()
ElGamal加密算法可以定义在任何循环群G上。它的安全性取决于G上的离散对数难题。下面给出ElGamal的一般步骤和算法实现。
"""
name: Elgamal算法
Author:duanqiao
time:2020/5/1
Knowledge points:
- 群:一个集合G,一个运算".",运算满足 "封闭性"、"结合律"、"有单位元"、"有逆元",则它俩一同被称为群。
- 循环群:循环群的所有元素都是生成元 g 的"指数"(此指数非彼指数,定义的一种运算)元素的来的。
- 生成元:
- 加密:r = g^k mod p;s = x*beta^k mod p;
- 解密:x = s(r^a)^-1 mod p
"""
'''
秘钥生成
'''
def make_key():
#p是一个大素数
p=150001
# g为模p的简化剩余系的生成元
g = 7
# a 属于循环群
alpha = 113
beta = pow(g,alpha)%p
#p,g,beta为公钥;alpha为私钥
return p,g,alpha,beta
'''
加密
(a + b) % p = (a % p + b % p) % p
(a - b) % p = (a % p - b % p) % p
(a * b) % p = (a % p * b % p) % p
'''
#扩展欧几里德算法
def ex_gcd(a,b):
if b == 0:
return 1,0
else:
q = a // b
r = a % b
s,t = ex_gcd(b,r)
s,t = t,s-q*t
return [s,t]
#快速幂算法
def fast_expmod(a,e,n):
"""
快速幂
"""
d = 1
while e !=0:
if(e&1) == 1:
d = (d * a) % n
e >>= 1
a = a * a % n
return d
#加密
def encryption(encrypt_para_list):
"""
参数为列表形式,依次为:明文x、秘密数k、大素数p、生成元g、beta
"""
x,k,p,g,beta = encrypt_para_list
r = fast_expmod(g,k,p)
s = ((x%p)*fast_expmod(beta,k,p))%p
return [r,s]
'''
解密
'''
def decrypt(decrypt_para_list):
"""
参数:列表形式,依次为:r,s,alpha,p
返回值:int明文
"""
r,s,alpha,p = decrypt_para_list
temp = ex_gcd(pow(r,alpha),p)[0] #逆
x = (s%p) * (temp%p) % p
return x
print(make_key())
x = 809 #明文
k = 1000 #私密数 2 <= k <= p-2
p ,g,alpha,beta=make_key()
#加密
encrypt_para_list=[x,k,p,g,beta]
r,s=encryption(encrypt_para_list)
print("加密后(r,s)=({},{})".format(r,s))
#解密
decrypt_para_list=[r,s,alpha,p]
x = decrypt(decrypt_para_list)
print("解密后x={}".format(x))
https://www.duanqyt.xyz