Reputation: 6037
I have created a signature of a file using the Python cryptography library as per this [1] link. This is the snippet I'm using (I've omitted the part where I serialize the signature to a file.
>>> 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()
... )
Problem is that when I try to verify the signature file using the openssl
CLI, it fails:
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
I'm not sure what else to check here. Assuming I'm doing everything else correctly, the only thing I'm not 100% confident about is whether my openssl
flags are correct. Perhaps they aren't matching the settings of the signing process done in cryptography?
[1] https://cryptography.io/en/latest/hazmat/primitives/asymmetric/rsa/#signing
EDIT: Fix is to either remove -sigopt rsa_pss_saltlen
altogether or set it to -sigopt rsa_pss_saltlen:-2
, which sets the salt length to be based on the PSS block structure (as per https://www.openssl.org/docs/man1.0.2/man1/pkeyutl.html).
Upvotes: 0
Views: 1914
Reputation: 1577
I created the following sign.py script based on the Python crypto library you referenced:
#!/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)
I then created a text file, message.txt, with your message in there and generated the signature as such:
./sign.py message.txt
The output of this script is the signature in the file message.sig
I was able to successfully verify it using the following openssl command:
openssl dgst -sha256 -verify public.pem -signature message.sig -sigopt \
rsa_padding_mode:pss message.txt
Verified OK
Upvotes: 3