使用 openssl 实用程序签名,使用 python 脚本验证
Sign with openssl utility, verify with python script
我想从 python.
中验证已使用命令行实用程序签名的文件的签名
我的命令行。
openssl pkeyutl -sign -in data.sha256 -inkey device.key -out data-pss.sign -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pss -pkeyopt rsa_pss_saltlen:32 -pkeyopt rsa_mgf1_md:sha256
我的 python 脚本。
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization
# client cert -> get public key
with open('device.pem', 'rb') as fc:
cert = x509.load_pem_x509_certificate(fc.read(), default_backend())
public_key = cert.public_key()
# private key
with open('device.key','rb') as fk:
private_key = serialization.load_pem_private_key(fk.read(), password=None, backend=default_backend())
# data sha256 that has been signed
with open('data.sha256', 'rb') as fd:
data_sha256 = fd.read()
# data signature done by command line
with open('data-pss.sign', 'rb') as fds:
data_sig = fds.read()
public_key.verify(data_sig,
data_sha256,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=32
),
hashes.SHA256())
我得到 cryptography.exceptions.InvalidSignature
。
如果我通过 python 签名 - 没问题 - 验证成功。
data_sig_py = private_key.sign(data_sha256,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=32
),
hashes.SHA256()
)
public_key.verify(data_sig_py,
data_sha256,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=32
),
hashes.SHA256())
在Python代码中,已经散列的数据在RSAPublicKey#verify()
. In this case a Prehashed
instance must be passed in the fourth parameter of RSAPublicKey#verify()
, i.e. specifically utils.Prehashed(hashes.SHA256())
, see also this example的第二个参数中传递。
目前 HashAlgorithm
个实例作为第四个参数传递,即具体 hashes.SHA256()
。这也是可能的,但前提是在第二个参数中传递原始数据(即 非散列数据 )而不是已经散列的数据。在这种情况下,RSAPublicKey#verify()
隐式地 散列 。
即在当前的 Python 代码中,数据在验证时被 double 散列。然而,在 OpenSSL 语句中,只有 single 散列数据被签名。因此,使用 Python 代码的验证失败。
如果签名是使用 Python 代码创建的(如上一个示例),数据也会被散列 两次,从而验证成功。
我想从 python.
中验证已使用命令行实用程序签名的文件的签名我的命令行。
openssl pkeyutl -sign -in data.sha256 -inkey device.key -out data-pss.sign -pkeyopt digest:sha256 -pkeyopt rsa_padding_mode:pss -pkeyopt rsa_pss_saltlen:32 -pkeyopt rsa_mgf1_md:sha256
我的 python 脚本。
from cryptography import x509
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import serialization
# client cert -> get public key
with open('device.pem', 'rb') as fc:
cert = x509.load_pem_x509_certificate(fc.read(), default_backend())
public_key = cert.public_key()
# private key
with open('device.key','rb') as fk:
private_key = serialization.load_pem_private_key(fk.read(), password=None, backend=default_backend())
# data sha256 that has been signed
with open('data.sha256', 'rb') as fd:
data_sha256 = fd.read()
# data signature done by command line
with open('data-pss.sign', 'rb') as fds:
data_sig = fds.read()
public_key.verify(data_sig,
data_sha256,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=32
),
hashes.SHA256())
我得到 cryptography.exceptions.InvalidSignature
。
如果我通过 python 签名 - 没问题 - 验证成功。
data_sig_py = private_key.sign(data_sha256,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=32
),
hashes.SHA256()
)
public_key.verify(data_sig_py,
data_sha256,
padding.PSS(
mgf=padding.MGF1(hashes.SHA256()),
salt_length=32
),
hashes.SHA256())
在Python代码中,已经散列的数据在RSAPublicKey#verify()
. In this case a Prehashed
instance must be passed in the fourth parameter of RSAPublicKey#verify()
, i.e. specifically utils.Prehashed(hashes.SHA256())
, see also this example的第二个参数中传递。
目前 HashAlgorithm
个实例作为第四个参数传递,即具体 hashes.SHA256()
。这也是可能的,但前提是在第二个参数中传递原始数据(即 非散列数据 )而不是已经散列的数据。在这种情况下,RSAPublicKey#verify()
隐式地 散列 。
即在当前的 Python 代码中,数据在验证时被 double 散列。然而,在 OpenSSL 语句中,只有 single 散列数据被签名。因此,使用 Python 代码的验证失败。
如果签名是使用 Python 代码创建的(如上一个示例),数据也会被散列 两次,从而验证成功。