对于大学的一个项目,我进行了以下设置:
- 公钥(p、g、h)
- 两个密文文件:(c1, c2) & (c3, c4)
- 上述文件的签名文件:(r1, s1) & (r2, s2)
目标是恢复明文。
我从签名文件中认识到,给定的 r 值是相同的(r1 = r2 = r)。这导致重新计算使用的私钥的可能性见。
基本上我需要两种算法:
k ≡ (m1 - m2)(s1 - s2)^-1 mod (p-1)
k ≡ (m1 / (s1 - s2) - m2 / (s1 - s2)) mod (p-1)
接着
x ≡ (m1 − k*s1)r^−1 mod (p−1)
x ≡ (m1 / r - k * s1 / r) mod (p-1)
所以我认为编写一个实现链接中提到的算法的python程序应该不是那么难。但我被卡住了。由于某些原因,我没有从我的计算中得到正确的值。也许有人可以在这里轻推我一下?
import random
import base64
from gmpy2 import *
from Crypto.Util.number import inverse
from binascii import hexlify, unhexlify
g = 262470350957996892686231567...
p = 394020061963944792122790401...
h = 114121123070543781308127611...
def getSign(file):
enc_file = open(file, "rb")
enc_byte = enc_file.read()
r, s = (enc_byte.decode("utf-8")).split()
return r, s
def getMess(file):
enc_file = open(file, "rb")
enc_base64 = enc_file.read()
enc_byte = base64.decodebytes(enc_base64)
c1, c2 = (enc_byte.decode("utf-8")).split()
c1, c2 = int(c1), int(c2)
return c1, c2
def decrypt(c1, c2, a):
df = pow(c1, a, p)
m = (c2 * inverse(df, p)) % p
return m
r1, s1 = getSign("secret1.enc.sig")
c11, c12 = getMess("secret1.enc")
r2, s2 = getSign("secret2.enc.sig")
c21, c22 = getMess("secret2.enc")
if(r1 == r2):
r = int(hexlify(str.encode(r1)), 16)
s1_hex = hexlify(str.encode(s1))
s1_int = int(s1_hex, 16)
s2_hex = hexlify(str.encode(s2))
s2_int = int(s2_hex, 16)
m1 = c12
m2 = c22
ds = s1_int - s2_int
ps = p - 1
k1 = (m1 * inverse(ds, ps)) % ps
k2 = (m2 * inverse(ds, ps)) % ps
k = k1 - k2
print("k = {}".format(k))
x1 = (m1 * inverse(r, ps)) % ps
x21 = k * s1_int
x2 = (x21 * inverse(r, ps)) % ps
x = x1 - x2
dm = decrypt(c21, c22, x)
x = format(dm, 'x')
message = unhexlify(x)
print("g = {}".format(g))
print("p = {}".format(p))
print("h = {}".format(h))
print("r = {}".format(r))
print("k = {}".format(k))
print("x = {}".format(x))
print("Decrypted Hex (x) : {}".format(x))
print("Decrypted Message : {}".format(message))