📜  ElGamal 加密算法

📅  最后修改于: 2022-05-13 01:57:02.484000             🧑  作者: Mango

ElGamal 加密算法

ElGamal 加密是一种公钥密码系统。它使用非对称密钥加密在两方之间进行通信并加密消息。
该密码系统基于在循环群中找到离散对数的难度,即即使我们知道 g a和 g k ,计算 g ak也是极其困难的。
ElGamal 密码系统的思想
假设 Alice 想与 Bob 通信。

  1. Bob 生成公钥和私钥:
    • Bob 选择一个非常大的数q和一个循环群F q
    • 从循环群F q中,他选择任意元素g并且
      一个元素a满足 gcd(a, q) = 1。
    • 然后他计算 h = g a
    • Bob 发布Fh = g aqg作为他的公钥,并保留a作为私钥。
  2. Alice 使用 Bob 的公钥加密数据:
    • Alice 从循环群F中选择一个元素k
      使得 gcd(k, q) = 1。
    • 然后她计算 p = g k和 s = h k = g ak。
    • 她将 s 与 M 倍数。
    • 然后她发送 (p, M*s) = (g k , M*s)。
  3. Bob 解密消息:
    • Bob 计算 s = p a = g ak
    • 他将 M*s 除以 s '以获得 M 为 s = s '

以下是Python中 ElGamal 密码系统的实现

Python3
# Python program to illustrate ElGamal encryption
 
import random
from math import pow
 
a = random.randint(2, 10)
 
def gcd(a, b):
    if a < b:
        return gcd(b, a)
    elif a % b == 0:
        return b;
    else:
        return gcd(b, a % b)
 
# Generating large random numbers
def gen_key(q):
 
    key = random.randint(pow(10, 20), q)
    while gcd(q, key) != 1:
        key = random.randint(pow(10, 20), q)
 
    return key
 
# Modular exponentiation
def power(a, b, c):
    x = 1
    y = a
 
    while b > 0:
        if b % 2 != 0:
            x = (x * y) % c;
        y = (y * y) % c
        b = int(b / 2)
 
    return x % c
 
# Asymmetric encryption
def encrypt(msg, q, h, g):
 
    en_msg = []
 
    k = gen_key(q)# Private key for sender
    s = power(h, k, q)
    p = power(g, k, q)
     
    for i in range(0, len(msg)):
        en_msg.append(msg[i])
 
    print("g^k used : ", p)
    print("g^ak used : ", s)
    for i in range(0, len(en_msg)):
        en_msg[i] = s * ord(en_msg[i])
 
    return en_msg, p
 
def decrypt(en_msg, p, key, q):
 
    dr_msg = []
    h = power(p, key, q)
    for i in range(0, len(en_msg)):
        dr_msg.append(chr(int(en_msg[i]/h)))
         
    return dr_msg
 
# Driver code
def main():
 
    msg = 'encryption'
    print("Original Message :", msg)
 
    q = random.randint(pow(10, 20), pow(10, 50))
    g = random.randint(2, q)
 
    key = gen_key(q)# Private key for receiver
    h = power(g, key, q)
    print("g used : ", g)
    print("g^a used : ", h)
 
    en_msg, p = encrypt(msg, q, h, g)
    dr_msg = decrypt(en_msg, p, key, q)
    dmsg = ''.join(dr_msg)
    print("Decrypted Message :", dmsg);
 
 
if __name__ == '__main__':
    main()


样本输出:

Original Message : encryption
g used :  5860696954522417707188952371547944035333315907890
g^a used :  4711309755639364289552454834506215144653958055252
g^k used :  12475188089503227615789015740709091911412567126782
g^ak used :  39448787632167136161153337226654906357756740068295
Decrypted Message : encryption

在这个密码系统中,原始消息M通过乘以g ak来掩蔽。要移除掩码,以g k的形式给出线索。除非有人知道a ,否则他将无法检索M 。这是因为在循环组中找到离散对数是困难的,并且简化知道 g a和 g k不足以计算 g ak