Openssl 签名验证所需的必要信息是什么?

Openssl 签名验证所需的必要信息是什么?,openssl,python,cryptography,rsa,pycrypto,Openssl,Python,Cryptography,Rsa,Pycrypto,我编写了一个基于rsa的签名和验证完整过程的测试演示,它帮助我理解了该过程的逻辑 # https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives.asymmetric import rsa # Preparation phase # Ge

我编写了一个基于rsa的签名和验证完整过程的测试演示,它帮助我理解了该过程的逻辑

# https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa

# Preparation phase
# Generate key pairs
# private_key contains the both private key and public key
private_key = rsa.generate_private_key(
    public_exponent=65537,
    key_size=2048,
    backend=default_backend()
)

# Serilize the keys
from cryptography.hazmat.primitives import serialization

pem = private_key.private_bytes(
   encoding=serialization.Encoding.PEM,
   format=serialization.PrivateFormat.PKCS8,
   encryption_algorithm=serialization.BestAvailableEncryption(b'mypassword')
)
with open('private-key.pem', 'wb') as f:
    f.write(pem)
    f.close()

public_key = private_key.public_key()
pem = public_key.public_bytes(
   encoding=serialization.Encoding.PEM,
   format=serialization.PublicFormat.SubjectPublicKeyInfo
)
with open('public-key.pem', 'wb') as f:
    f.write(pem)
    f.close()

# Signer
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives.asymmetric import utils

with open('private-key.pem', 'rb') as f:
    private_key = serialization.load_pem_private_key(
        f.read(),
        password=b'mypassword',
        backend=default_backend()
    )

    chosen_hash = hashes.SHA256()
    hasher = hashes.Hash(chosen_hash, default_backend())
    hasher.update(b"data & ")
    hasher.update(b"more data")
    digest = hasher.finalize()

    signature = private_key.sign(
        digest,
        padding.PSS(
            mgf=padding.MGF1(hashes.SHA256()),
            salt_length=padding.PSS.MAX_LENGTH
        ),
        utils.Prehashed(chosen_hash)
    )

    with open('signature', 'wb') as f:
        f.write(signature)
        f.close()

# Verifier
chosen_hash = hashes.SHA256()
hasher = hashes.Hash(chosen_hash, default_backend())
hasher.update(b"data & ")
hasher.update(b"more data")
digest = hasher.finalize()

hasher1 = hashes.Hash(chosen_hash, default_backend())
hasher1.update(b"data & more data")
digest1 = hasher1.finalize()
print(digest == digest1)

with open('signature', 'rb') as f:
    signature = f.read()

with open('public-key.pem', 'rb') as f:
    public_key  = serialization.load_pem_public_key(
        f.read(),
        backend=default_backend()
    )

    if isinstance(public_key, rsa.RSAPublicKey):
        public_key.verify(
            signature,
            digest,
            padding.PSS(
                mgf=padding.MGF1(hashes.SHA256()),
                salt_length=padding.PSS.MAX_LENGTH
            ),
            utils.Prehashed(chosen_hash)
        )
问题:

验证时是否必须将填充类型(如PSS)称为输入

但在CLI中

为什么这里没有提到填充物?我认为无论密钥对算法(ECC或RSA)不同与否,(标准?)验证方法的输入参数都应该相同

另一个问题,我在python中看到,
isinstance(public_key,rsa.RSAPublicKey)
可以找到密钥的算法

验证方法是否也需要算法类型

与库内类似,可以使用这样的
ecc\u verify
rsa\u verify
方法

顺便说一句,据我所知,
verify
方法参数(与openssl CLI相同):

  • 公钥
  • 散列类型
  • 签名
验证时是否必须将填充类型(如PSS)称为输入

是的,填充是一个必需的配置参数,应该事先知道

为什么这里没有提到填充物

ECDSA签名验证不需要填充;它与RSA签名生成/验证有很大不同

它只有一个使用的标准,就像之前RSA的情况一样(PKCS#1 v1.5)。PSS只是在2.0版发布后才添加到RSA PKCS#1标准中

验证方法是否也需要算法类型

尽管可能没有直接攻击,但您应该假设验证算法是预先知道的,就像padding方法一样。PKCS#1中描述的RSA至少有两个签名生成函数,其他标准中有更多,尽管这些函数并不常见

顺便说一句,据我所知,验证方法参数(与openssl CLI相同):


正如您已经看到的,RSA PSS使用两个哈希函数,一个用于对输入数据进行哈希运算,另一个用于填充内部MGF1函数。所以这里不是一种散列类型,而是两种。散列类型不一定相同,而且在MGF1散列的确定方式上实现也不同(明确指定它,正如您所做的那样,是最好的)。

谢谢,您应该假设验证算法是预先知道的,因此可以通过
isinstance(public_key,rsa.RSAPublicKey)
?否,验证算法应由协议建立。该密钥可用于任何基于RSA的签名生成算法。
openssl dgst -sha256 -verify public.pem -signature msg.signature.txt msg.digest.txt