为了账号安全,请及时绑定邮箱和手机立即绑定

RSA 签名数据验证不起作用 PyCryptodome

RSA 签名数据验证不起作用 PyCryptodome

qq_遁去的一_1 2023-07-05 15:27:55
很抱歉这个非常具体的问题,但我真的要疯了。我正在尝试制作一个模块,以便在需要签名或验证签名时简单地导入,但遇到了问题,无论我输入签名数据还是其他任何内容,验证器都会返回 true,代码如下:RSA_Handler.pyfrom Crypto.PublicKey import RSAfrom Crypto.Hash import SHA256from Crypto.Signature import PKCS1_v1_5import pickledef sign(data, exported_key):    key = RSA.importKey(exported_key)    signed_data = []    signed_data.append(data)    signed_data.append(PKCS1_v1_5.new(key).sign(SHA256.new(pickle.dumps(data))))    return signed_datadef verify(signed_data, exported_key):    data = signed_data[0]    signature = signed_data[1]    key = RSA.importKey(exported_key)    h = SHA256.new(pickle.dumps(data))    try:        PKCS1_v1_5.new(key).verify(h, signature)        return True    except(ValueError, TypeError):        return Falsetest01.pyfrom RSA_Handler import *import pickleimport oswith open("keys.txt", "rb") as rb:    keys = rb.read()signed = sign("hello", keys)trueorfalse = verify(["this will return"," true whatever I enter"], keys)print(trueorfalse)
查看完整描述

2 回答

?
慕容森

TA贡献1853条经验 获得超18个赞

我可以重现该问题(至少对于最新版本的 PyCryptodome,即 3.9.8)。似乎行为取决于填充类型。对于当前在发布的代码中使用的 module ,如果签名无效,PKCS1_v1_5验证不会引发 a ,而是将结果作为返回值返回。ValueError


这意味着您的verify()函数始终返回True,因为即使在签名不匹配的情况下,也不会ValueError引发 a 或计算返回值。


要解决该问题,您的verify()函数必须进行如下更改:


def verify(signed_data, exported_key):

    data = signed_data[0]

    signature = signed_data[1]

    key = RSA.importKey(exported_key)

    h = SHA256.new(pickle.dumps(data))

    return PKCS1_v1_5.new(key).verify(h, signature)

可以用以下方法进行测试:


# Signing

key = RSA.generate(1024)

keyPriv = key.exportKey()

signed = sign(b'Some data', keyPriv)


# Verifying

#signed[0] = b'Some data'             # Succeeds

signed[0] = b'Some other data'        # Fails

keyPub = key.publickey().exportKey()

verified = verify(signed, keyPub)

print(verified)

对于 PSS 填充,即对于模块,在签名无效的情况下将引发pssa 。ValueError即,如果您通过替换切换到此填充


from Crypto.Signature import PKCS1_v1_5


from Crypto.Signature import pss 

并且PKCS1_v1_5在pss其余代码中,verify()函数中的逻辑可以保持不变。


编辑:


正如SquareRootOfTwentyThree 的答案PKCS1_v1_5中所解释的那样,它是一个过时的模块pkcs1_15,必须使用该模块,根据此处的ValueError文档,该模块按预期会在签名无效的情况下生成。


查看完整回答
反对 回复 2023-07-05
?
森栏

TA贡献1810条经验 获得超5个赞

您正在导入过时的模块PKCS1_v1_5,该模块实际上并未记录在 PyCryptodome 中。在您的代码中,您必须改为:

from Crypto.Signature import import pkcs1_15

您正在使用的旧模块(即PKCS1_v1_5)纯粹是为了与 PyCrypto 向后兼容,它的行为方式与您观察到的相同(即没有例外 - 这不是那么好,新模块更好)。


查看完整回答
反对 回复 2023-07-05
  • 2 回答
  • 0 关注
  • 99 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信