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

RSA signed data verification not working PyCryptodome

很抱歉这个非常具体的问题,但我真的快要疯了。 我试图让一个模块在我需要签名或验证签名时简单地导入但是我遇到了一个问题,验证器只是 returns 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)

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

这意味着您的 verify() 函数 always returns True,因为即使签名不匹配,ValueError 不会被提升,也不会评估 returned 值。

要解决此问题,您的 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 填充,即对于模块 pss,如果签名无效,则会引发 ValueError。 IE。如果您通过替换

切换到此填充
from Crypto.Signature import PKCS1_v1_5

from Crypto.Signature import pss 

还有 PKCS1_v1_5pss 在其余代码中,verify() 函数中的逻辑可以保持不变。

编辑:

from SquareRootOfTwentyThree, PKCS1_v1_5 is an outdated module and instead the module pkcs1_15 has to be used, which as expected generates a ValueError in case of an invalid signature, according to the documentation, here 中所述。

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

from Crypto.Signature import import pkcs1_15

PyCryptodome 文档 (https://www.pycryptodome.org/en/latest/src/signature/pkcs1_v1_5.html) 展示了验证 PKCS#1 v1.5 签名的正确方法的示例。

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