Skip to content

Commit 395b8d6

Browse files
committed
Feature request sybrenstuvel#78: Expose function to find the hash method of a signature
I've not used the name "find_method_hash" suggested in sybrenstuvel#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.
1 parent a478d4c commit 395b8d6

File tree

4 files changed

+33
-3
lines changed

4 files changed

+33
-3
lines changed

doc/reference.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ Functions
1515

1616
.. autofunction:: rsa.verify
1717

18+
.. autofunction:: rsa.find_signature_hash
19+
1820
.. autofunction:: rsa.newkeys(keysize)
1921

2022

rsa/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
from rsa.key import newkeys, PrivateKey, PublicKey
2727
from rsa.pkcs1 import encrypt, decrypt, sign, verify, DecryptionError, \
28-
VerificationError
28+
VerificationError, find_signature_hash
2929

3030
__author__ = "Sybren Stuvel, Barry Mead and Yesudeep Mangalapilly"
3131
__date__ = "2016-03-29"

rsa/pkcs1.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@ def verify(message, signature, pub_key):
294294
:param signature: the signature block, as created with :py:func:`rsa.sign`.
295295
:param pub_key: the :py:class:`rsa.PublicKey` of the person signing the message.
296296
:raise VerificationError: when the signature doesn't match the message.
297+
:returns: the name of the used hash.
297298
298299
"""
299300

@@ -314,7 +315,26 @@ def verify(message, signature, pub_key):
314315
if expected != clearsig:
315316
raise VerificationError('Verification failed')
316317

317-
return True
318+
return method_name
319+
320+
321+
def find_signature_hash(signature, pub_key):
322+
"""Returns the hash name detected from the signature.
323+
324+
If you also want to verify the message, use :py:func:`rsa.verify()` instead.
325+
It also returns the name of the used hash.
326+
327+
:param signature: the signature block, as created with :py:func:`rsa.sign`.
328+
:param pub_key: the :py:class:`rsa.PublicKey` of the person signing the message.
329+
:returns: the name of the used hash.
330+
"""
331+
332+
keylength = common.byte_size(pub_key.n)
333+
encrypted = transform.bytes2int(signature)
334+
decrypted = core.decrypt_int(encrypted, pub_key.e, pub_key.n)
335+
clearsig = transform.int2bytes(decrypted, keylength)
336+
337+
return _find_method_hash(clearsig)
318338

319339

320340
def yield_fixedblocks(infile, blocksize):

tests/test_pkcs1.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,15 @@ def test_sign_verify(self):
7676
message = b'je moeder'
7777
signature = pkcs1.sign(message, self.priv, 'SHA-256')
7878

79-
self.assertTrue(pkcs1.verify(message, signature, self.pub))
79+
self.assertEqual('SHA-256', pkcs1.verify(message, signature, self.pub))
80+
81+
def test_find_signature_hash(self):
82+
"""Test happy flow of sign and find_signature_hash"""
83+
84+
message = b'je moeder'
85+
signature = pkcs1.sign(message, self.priv, 'SHA-256')
86+
87+
self.assertEqual('SHA-256', pkcs1.find_signature_hash(signature, self.pub))
8088

8189
def test_alter_message(self):
8290
"""Altering the message should let the verification fail."""

0 commit comments

Comments
 (0)