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

很抱歉这个非常具体的问题,但我真的要疯了。我正在尝试制作一个模块,以便在需要签名或验证签名时简单地导入,但遇到了问题,无论我输入签名数据还是其他任何内容,验证器都会返回 true,代码如下:


RSA_Handler.py


from Crypto.PublicKey import RSA

from Crypto.Hash import SHA256

from Crypto.Signature import PKCS1_v1_5

import pickle


def 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_data



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))

    try:

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

        return True


    except(ValueError, TypeError):

        return False

test01.py


from RSA_Handler import *

import pickle

import os



with 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)


qq_遁去的一_1
浏览 150回答 2
2回答

慕容森

我可以重现该问题(至少对于最新版本的 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)可以用以下方法进行测试:# Signingkey = RSA.generate(1024)keyPriv = key.exportKey()signed = sign(b'Some data', keyPriv)# Verifying#signed[0] = b'Some data'             # Succeedssigned[0] = b'Some other data'        # FailskeyPub = 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文档,该模块按预期会在签名无效的情况下生成。

森栏

您正在导入过时的模块PKCS1_v1_5,该模块实际上并未记录在 PyCryptodome 中。在您的代码中,您必须改为:from Crypto.Signature import import pkcs1_15您正在使用的旧模块(即PKCS1_v1_5)纯粹是为了与 PyCrypto 向后兼容,它的行为方式与您观察到的相同(即没有例外 - 这不是那么好,新模块更好)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python