summaryrefslogtreecommitdiff
path: root/rsa/pkcs1.py
diff options
context:
space:
mode:
authorJustin Simon <jls5177@gmail.com>2017-05-07 04:39:47 -0500
committerSybren A. Stüvel <sybren@stuvel.eu>2017-05-07 11:39:47 +0200
commit425eb24854f1c3397aaaba61fa1cf71c76b27c4b (patch)
tree824a0e34f6bc4e88bbbb6bfa7e2f7a80d5399aa3 /rsa/pkcs1.py
parent000e84a97a8ab25a5d9b4185a2e02efc033f7e8a (diff)
downloadrsa-git-425eb24854f1c3397aaaba61fa1cf71c76b27c4b.tar.gz
Support signing a pre-calculated hash (#87)
* Split the hashing out of the sign method This code change adds support to split the hashing of a message and the actual signing of the message. * Updating unit test and documentation This commit updates the unit test and usage docs. In addition, This change removes a redundant error check inside rsa.sign(). * Refactore unit tests and code comments Removed the print statements from the unit test and refactored a few code comments to improve readability. * Rename hash function The new hash function had the same name as a function in the standard library. This commit changes the name to avoid conflicts. * Rename hash function to compute_hash() This commit renames the hash function to compute_hash().
Diffstat (limited to 'rsa/pkcs1.py')
-rw-r--r--rsa/pkcs1.py50
1 files changed, 34 insertions, 16 deletions
diff --git a/rsa/pkcs1.py b/rsa/pkcs1.py
index 41f543c..323bf48 100644
--- a/rsa/pkcs1.py
+++ b/rsa/pkcs1.py
@@ -245,17 +245,16 @@ def decrypt(crypto, priv_key):
return cleartext[sep_idx + 1:]
-def sign(message, priv_key, hash):
- """Signs the message with the private key.
+def sign_hash(hash_value, priv_key, hash_method):
+ """Signs a precomputed hash with the private key.
Hashes the message, then signs the hash with the given key. This is known
as a "detached signature", because the message itself isn't altered.
-
- :param message: the message to sign. Can be an 8-bit string or a file-like
- object. If ``message`` has a ``read()`` method, it is assumed to be a
- file-like object.
+
+ :param hash_value: A precomputed hash to sign (ignores message). Should be set to
+ None if needing to hash and sign message.
:param priv_key: the :py:class:`rsa.PrivateKey` to sign with
- :param hash: the hash method used on the message. Use 'MD5', 'SHA-1',
+ :param hash_method: the hash method used on the message. Use 'MD5', 'SHA-1',
'SHA-256', 'SHA-384' or 'SHA-512'.
:return: a message signature block.
:raise OverflowError: if the private key is too small to contain the
@@ -264,15 +263,12 @@ def sign(message, priv_key, hash):
"""
# Get the ASN1 code for this hash method
- if hash not in HASH_ASN1:
- raise ValueError('Invalid hash method: %s' % hash)
- asn1code = HASH_ASN1[hash]
-
- # Calculate the hash
- hash = _hash(message, hash)
+ if hash_method not in HASH_ASN1:
+ raise ValueError('Invalid hash method: %s' % hash_method)
+ asn1code = HASH_ASN1[hash_method]
# Encrypt the hash with the private key
- cleartext = asn1code + hash
+ cleartext = asn1code + hash_value
keylength = common.byte_size(priv_key.n)
padded = _pad_for_signing(cleartext, keylength)
@@ -283,6 +279,28 @@ def sign(message, priv_key, hash):
return block
+def sign(message, priv_key, hash_method):
+ """Signs the message with the private key.
+
+ Hashes the message, then signs the hash with the given key. This is known
+ as a "detached signature", because the message itself isn't altered.
+
+ :param message: the message to sign. Can be an 8-bit string or a file-like
+ object. If ``message`` has a ``read()`` method, it is assumed to be a
+ file-like object.
+ :param priv_key: the :py:class:`rsa.PrivateKey` to sign with
+ :param hash_method: the hash method used on the message. Use 'MD5', 'SHA-1',
+ 'SHA-256', 'SHA-384' or 'SHA-512'.
+ :return: a message signature block.
+ :raise OverflowError: if the private key is too small to contain the
+ requested hash.
+
+ """
+
+ msg_hash = compute_hash(message, hash_method)
+ return sign_hash(msg_hash, priv_key, hash_method)
+
+
def verify(message, signature, pub_key):
"""Verifies that the signature matches the message.
@@ -305,7 +323,7 @@ def verify(message, signature, pub_key):
# Get the hash method
method_name = _find_method_hash(clearsig)
- message_hash = _hash(message, method_name)
+ message_hash = compute_hash(message, method_name)
# Reconstruct the expected padded hash
cleartext = HASH_ASN1[method_name] + message_hash
@@ -358,7 +376,7 @@ def yield_fixedblocks(infile, blocksize):
break
-def _hash(message, method_name):
+def compute_hash(message, method_name):
"""Returns the message digest.
:param message: the signed message. Can be an 8-bit string or a file-like