为什么 openssl 无法验证由 Python 密码库创建的签名?
Why can't openssl verify signature created by Python cryptography library?
我已经根据此 [1] link 使用 Python 加密库创建了一个文件签名。这是我正在使用的片段(我省略了将签名序列化到文件的部分。
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.asymmetric import padding
>>> message = b"A message I want to sign"
>>> signature = private_key.sign(
... message,
... padding.PSS(
... mgf=padding.MGF1(hashes.SHA256()),
... salt_length=padding.PSS.MAX_LENGTH
... ),
... hashes.SHA256()
... )
问题是,当我尝试使用 openssl
CLI 验证签名文件时,它失败了:
openssl dgst -sha256 \
> -signature sig.sha256 \
> -verify pubkey.pem \
> -sigopt rsa_padding_mode:pss \
> -sigopt rsa_pss_saltlen:-1 \
> -sigopt rsa_mgf1_md:sha256 \
> myfile
Verification Failure
我不确定这里还有什么要检查的。假设我做的其他一切都正确,我唯一不能 100% 确信的是我的 openssl
标志是否正确。也许它们与密码学中完成的签名过程的设置不匹配?
[1] https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/#signing
编辑:修复是完全删除 -sigopt rsa_pss_saltlen
或将其设置为 -sigopt rsa_pss_saltlen:-2
,这将盐长度设置为基于 PSS 块结构(根据 https://www.openssl.org/docs/man1.0.2/man1/pkeyutl.html) .
我根据您引用的 Python 加密库创建了以下 sign.py 脚本:
#!/usr/bin/env python
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
import sys
import os
with open("./private.pem", "rb") as key_file:
private_key = serialization.load_pem_private_key( key_file.read(),
password=None, backend=default_backend())
with open(sys.argv[1], "r") as file_to_sign:
message = file_to_sign.read()
message = message.encode()
signature = private_key.sign( message, padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())
sigfile = "%s.%s" % (os.path.splitext(sys.argv[1])[0] , "sig")
with open(sigfile, "wb") as to_sig_file:
to_sig_file.write(signature)
然后我创建了一个文本文件 message.txt,其中包含您的消息并生成了这样的签名:
./sign.py message.txt
此脚本的输出是文件中的签名 message.sig
我能够使用以下 openssl 命令成功验证它:
openssl dgst -sha256 -verify public.pem -signature message.sig -sigopt \
rsa_padding_mode:pss message.txt
Verified OK
我已经根据此 [1] link 使用 Python 加密库创建了一个文件签名。这是我正在使用的片段(我省略了将签名序列化到文件的部分。
>>> from cryptography.hazmat.primitives import hashes
>>> from cryptography.hazmat.primitives.asymmetric import padding
>>> message = b"A message I want to sign"
>>> signature = private_key.sign(
... message,
... padding.PSS(
... mgf=padding.MGF1(hashes.SHA256()),
... salt_length=padding.PSS.MAX_LENGTH
... ),
... hashes.SHA256()
... )
问题是,当我尝试使用 openssl
CLI 验证签名文件时,它失败了:
openssl dgst -sha256 \
> -signature sig.sha256 \
> -verify pubkey.pem \
> -sigopt rsa_padding_mode:pss \
> -sigopt rsa_pss_saltlen:-1 \
> -sigopt rsa_mgf1_md:sha256 \
> myfile
Verification Failure
我不确定这里还有什么要检查的。假设我做的其他一切都正确,我唯一不能 100% 确信的是我的 openssl
标志是否正确。也许它们与密码学中完成的签名过程的设置不匹配?
[1] https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/#signing
编辑:修复是完全删除 -sigopt rsa_pss_saltlen
或将其设置为 -sigopt rsa_pss_saltlen:-2
,这将盐长度设置为基于 PSS 块结构(根据 https://www.openssl.org/docs/man1.0.2/man1/pkeyutl.html) .
我根据您引用的 Python 加密库创建了以下 sign.py 脚本:
#!/usr/bin/env python
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
import sys
import os
with open("./private.pem", "rb") as key_file:
private_key = serialization.load_pem_private_key( key_file.read(),
password=None, backend=default_backend())
with open(sys.argv[1], "r") as file_to_sign:
message = file_to_sign.read()
message = message.encode()
signature = private_key.sign( message, padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256())
sigfile = "%s.%s" % (os.path.splitext(sys.argv[1])[0] , "sig")
with open(sigfile, "wb") as to_sig_file:
to_sig_file.write(signature)
然后我创建了一个文本文件 message.txt,其中包含您的消息并生成了这样的签名:
./sign.py message.txt
此脚本的输出是文件中的签名 message.sig
我能够使用以下 openssl 命令成功验证它:
openssl dgst -sha256 -verify public.pem -signature message.sig -sigopt \
rsa_padding_mode:pss message.txt
Verified OK