summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSybren A. Stüvel <sybren@stuvel.eu>2017-04-10 12:12:29 +0200
committerSybren A. Stüvel <sybren@stuvel.eu>2017-04-10 12:12:29 +0200
commit395b8d661566f15632b0fb0e36fb8ea453ad9bf3 (patch)
treec200069ad7eeca8868244fbea2f5a979c0f98ed8
parenta478d4c23a75c76f1e5587b3c08b1f3a1f2cbf8e (diff)
downloadrsa-git-395b8d661566f15632b0fb0e36fb8ea453ad9bf3.tar.gz
Feature request #78: Expose function to find the hash method of a signature
I've not used the name "find_method_hash" suggested in #78, as it's a bit vague. It's ok-ish for a private function `_find_method_hash`, but I thought `find_signature_hash` would be more descriptive.
-rw-r--r--doc/reference.rst2
-rw-r--r--rsa/__init__.py2
-rw-r--r--rsa/pkcs1.py22
-rw-r--r--tests/test_pkcs1.py10
4 files changed, 33 insertions, 3 deletions
diff --git a/doc/reference.rst b/doc/reference.rst
index d81f742..9da7c6b 100644
--- a/doc/reference.rst
+++ b/doc/reference.rst
@@ -15,6 +15,8 @@ Functions
.. autofunction:: rsa.verify
+.. autofunction:: rsa.find_signature_hash
+
.. autofunction:: rsa.newkeys(keysize)
diff --git a/rsa/__init__.py b/rsa/__init__.py
index e69bbf3..95cd3fd 100644
--- a/rsa/__init__.py
+++ b/rsa/__init__.py
@@ -25,7 +25,7 @@ prevent repetitions, or other common security improvements. Use with care.
from rsa.key import newkeys, PrivateKey, PublicKey
from rsa.pkcs1 import encrypt, decrypt, sign, verify, DecryptionError, \
- VerificationError
+ VerificationError, find_signature_hash
__author__ = "Sybren Stuvel, Barry Mead and Yesudeep Mangalapilly"
__date__ = "2016-03-29"
diff --git a/rsa/pkcs1.py b/rsa/pkcs1.py
index bb08f4d..41f543c 100644
--- a/rsa/pkcs1.py
+++ b/rsa/pkcs1.py
@@ -294,6 +294,7 @@ def verify(message, signature, pub_key):
:param signature: the signature block, as created with :py:func:`rsa.sign`.
:param pub_key: the :py:class:`rsa.PublicKey` of the person signing the message.
:raise VerificationError: when the signature doesn't match the message.
+ :returns: the name of the used hash.
"""
@@ -314,7 +315,26 @@ def verify(message, signature, pub_key):
if expected != clearsig:
raise VerificationError('Verification failed')
- return True
+ return method_name
+
+
+def find_signature_hash(signature, pub_key):
+ """Returns the hash name detected from the signature.
+
+ If you also want to verify the message, use :py:func:`rsa.verify()` instead.
+ It also returns the name of the used hash.
+
+ :param signature: the signature block, as created with :py:func:`rsa.sign`.
+ :param pub_key: the :py:class:`rsa.PublicKey` of the person signing the message.
+ :returns: the name of the used hash.
+ """
+
+ keylength = common.byte_size(pub_key.n)
+ encrypted = transform.bytes2int(signature)
+ decrypted = core.decrypt_int(encrypted, pub_key.e, pub_key.n)
+ clearsig = transform.int2bytes(decrypted, keylength)
+
+ return _find_method_hash(clearsig)
def yield_fixedblocks(infile, blocksize):
diff --git a/tests/test_pkcs1.py b/tests/test_pkcs1.py
index 2116284..a8afea7 100644
--- a/tests/test_pkcs1.py
+++ b/tests/test_pkcs1.py
@@ -76,7 +76,15 @@ class SignatureTest(unittest.TestCase):
message = b'je moeder'
signature = pkcs1.sign(message, self.priv, 'SHA-256')
- self.assertTrue(pkcs1.verify(message, signature, self.pub))
+ self.assertEqual('SHA-256', pkcs1.verify(message, signature, self.pub))
+
+ def test_find_signature_hash(self):
+ """Test happy flow of sign and find_signature_hash"""
+
+ message = b'je moeder'
+ signature = pkcs1.sign(message, self.priv, 'SHA-256')
+
+ self.assertEqual('SHA-256', pkcs1.find_signature_hash(signature, self.pub))
def test_alter_message(self):
"""Altering the message should let the verification fail."""