ElGamal公钥密码算法是在密码协议中有着重要应用的一类公钥密码算法,基于公钥密码体制和椭圆曲线加密体系,其安全性是基于有限域上离散对数学问题的难解性。至今仍是一个安全性良好的公钥密码算法。既可用于加密又可用于数字签名的公钥密码体制。
数字签名就是附加在数据单元上的一些数据,或是对数据单元所作的密码变换。这种数据或变换允许数据单元的接收者用以确认数据单元的来源和数据单元的完整性并保护数据,防止被人(例如接收者)进行伪造。
Elgamal算法具体过程如下:
Alice和Bob生成各自的密钥,并交换彼此的公钥(p,g,y),Alice和Bob之间约定签署的消息m(20240301),Alice签署消息m,将三元组(m,r,s)发给Bob,Bob验证签名。请编写程序完成实验内容。
主要思路是先由系统随机生成素数p和生成元g和密钥对,然后Alice用自己的私钥签署消息m,将签名结果的r和s和消息m一起发给Bob,Bob用Alcie的公钥和Alice发来(m,r,s)验证签名,程序代码如下:
import random
from sympy import isprime, mod_inverse
# 选择一个素数p和生成元g
def generate_prime_and_generator():
while True:
p = random.randint(2 ** 10, 2 ** 11) # p的范围
if isprime(p):
break
while True:
g = random.randint(2, p - 2)
if pow(g, (p - 1), p) == 1:
break
return p, g
# 生成密钥对
def generate_key_pair(p, g):
x = random.randint(2, p - 2)
y = pow(g, x, p)
return x, y
# 签署消息
def sign_message(p, g, x, m):
k = random.randint(1, p - 2)
r = pow(g, k, p)
s = (m - x * r) * mod_inverse(k, p - 1) % (p - 1)
return (r, s)
# 验证签名
def verify_signature(p, g, y, m, r, s):
if not (0 < r < p and 0 < s < p - 1):
return False
left = pow(y, r, p) * pow(r, s, p) % p
right = pow(g, m, p)
return left == right
# 输出签名详细过程
def print_signature_process(p, g, x, m, r, s):
print("--------------------签名过程--------------------")
print(f"签名消息为: {m}")
print(f"私钥x为: {x}")
print(f"随机数k为: {k}")
print(f"签名结果r为: {r}")
print(f"签名结果s为: {s}")
# 主程序
if __name__ == "__main__":
# 生成素数和生成元
p, g = generate_prime_and_generator()
# Alice生成密钥对
x_alice, y_alice = generate_key_pair(p, g)
# 输出参数
print("--------------------参数生成过程--------------------")
print(f"素数p为: {p}")
print(f"生成元g为: {g}")
print(f"Alice的公钥y为: {y_alice}")
# Alice签署消息
message = 20240301
k = random.randint(1, p - 2)
r, s = sign_message(p, g, x_alice, message)
# 输出签名详细过程
print_signature_process(p, g, x_alice, message, r, s)
# 用户输入签名
print("--------------------验证签名过程--------------------")
user_r = int(input("请输入r的值: "))
user_s = int(input("请输入s的值: "))
# 验证签名
if verify_signature(p, g, y_alice, message, user_r, user_s):
print("签名有效")
else:
print("签名无效")
运行结果