公钥密码——RSA和Elgamal

简介

公钥密码算法也叫非对称加密,主要有RSA算法、Elgamal算法、ECC算法。RSA算法是基于大素数难分解这一数学难题而提出的(两个大质数相乘得到的大数难以被因式分解),原理如下:

RSA

  • 秘钥生成
    1. 选取大素数p,q;计算n=pq以及n的欧拉函数φ(n) = φ§ φ(q)=(p-1)(q-1)。关于欧拉函数,大家肯定是学过滴,素数的欧拉函数等于它自己减1,比如φ (3) = 2;φ (5) = 4;另外一个数等于两个素数的积,那么这个数的欧拉函数等于两个素数的欧拉函数的乘积,举个例子:φ (15) = φ (3) *φ (5) .
    2. 选一个e(1<e<φ (n) ),是的e和φ (n)互素(因为ax≡1(modn)的条件是a和n互素,要不然一会怎么求私钥d) 。
    3. 计算d,ed≡1(modφ(n)).继而(n,e)为公钥发送到公钥空间,(n,d)为私钥,自己妥善保存。
加密

假设明文为 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算法

ElGamal加密算法可以定义在任何循环群G上。它的安全性取决于G上的离散对数难题。下面给出ElGamal的一般步骤和算法实现。

一般步骤

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))
  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值