def encrypt(message, pub_key): '''Encrypts the given message using PKCS#1 v1.5 :param message: the message to encrypt. Must be a byte string no longer than ``k-11`` bytes, where ``k`` is the number of bytes needed to encode the ``n`` component of the public key. :param pub_key: the :py:class:`rsa.PublicKey` to encrypt with. :raise OverflowError: when the message is too large to fit in the padded block. >>> from rsa import key, common >>> (pub_key, priv_key) = key.newkeys(256) >>> message = 'hello' >>> crypto = encrypt(message, pub_key) The crypto text should be just as long as the public key 'n' component: >>> len(crypto) == common.byte_size(pub_key.n) True ''' keylength = byte_size(pub_key.n) padded = _pad_for_encryption(message, keylength) payload = boomCryptConvLib.bytes2int(padded) encrypted = encrypt_int(payload, pub_key.e, pub_key.n) block = boomCryptConvLib.int2bytes(encrypted, keylength) return block
def verify(signature, pub_key): '''Verifies that the signature matches the message. The hash method is detected automatically from the signature. :param message: the signed message. 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 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. .. warning:: Never display the stack trace of a :py:class:`rsa.pkcs1.VerificationError` exception. It shows where in the code the exception occurred, and thus leaks information about the key. It's only a tiny bit of information, but every bit makes cracking the keys easier. ''' blocksize = byte_size(pub_key.n) encrypted = boomCryptConvLib.bytes2int(signature) decrypted = decrypt_int(encrypted, pub_key.e, pub_key.n) clearsig = boomCryptConvLib.int2bytes(decrypted, blocksize) # Find the 00 separator between the padding and the payload try: sep_idx = clearsig.index(boomCryptConvLib.b('\x00'), 2) except ValueError: raise DecryptionError('Verification failed') return clearsig[sep_idx + 1:]
def verify(signature, pub_key): '''Verifies that the signature matches the message. The hash method is detected automatically from the signature. :param message: the signed message. 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 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. .. warning:: Never display the stack trace of a :py:class:`rsa.pkcs1.VerificationError` exception. It shows where in the code the exception occurred, and thus leaks information about the key. It's only a tiny bit of information, but every bit makes cracking the keys easier. ''' blocksize = byte_size(pub_key.n) encrypted = boomCryptConvLib.bytes2int(signature) decrypted = decrypt_int(encrypted, pub_key.e, pub_key.n) clearsig = boomCryptConvLib.int2bytes(decrypted, blocksize) # Find the 00 separator between the padding and the payload try: sep_idx = clearsig.index(boomCryptConvLib.b('\x00'), 2) except ValueError: raise DecryptionError('Verification failed') return clearsig[sep_idx+1:]
def sign(message, priv_key): keylength = byte_size(priv_key.n) padded = _pad_for_encryption(message, keylength) payload = boomCryptConvLib.bytes2int(padded) encrypted = encrypt_int(payload, priv_key.d, priv_key.n) block = boomCryptConvLib.int2bytes(encrypted, keylength) return block
def decrypt(crypto, priv_key): r'''Decrypts the given message using PKCS#1 v1.5 The decryption is considered 'failed' when the resulting cleartext doesn't start with the bytes 00 02, or when the 00 byte between the padding and the message cannot be found. :param crypto: the crypto text as returned by :py:func:`rsa.encrypt` :param priv_key: the :py:class:`rsa.PrivateKey` to decrypt with. :raise DecryptionError: when the decryption fails. No details are given as to why the code thinks the decryption fails, as this would leak information about the private key. >>> import rsa >>> (pub_key, priv_key) = rsa.newkeys(256) It works with strings: >>> crypto = encrypt('hello', pub_key) >>> decrypt(crypto, priv_key) 'hello' And with binary data: >>> crypto = encrypt('\x00\x00\x00\x00\x01', pub_key) >>> decrypt(crypto, priv_key) '\x00\x00\x00\x00\x01' Altering the encrypted information will *likely* cause a :py:class:`rsa.pkcs1.DecryptionError`. If you want to be *sure*, use :py:func:`rsa.sign`. .. warning:: Never display the stack trace of a :py:class:`rsa.pkcs1.DecryptionError` exception. It shows where in the code the exception occurred, and thus leaks information about the key. It's only a tiny bit of information, but every bit makes cracking the keys easier. >>> crypto = encrypt('hello', pub_key) >>> crypto = crypto[0:5] + 'X' + crypto[6:] # change a byte >>> decrypt(crypto, priv_key) Traceback (most recent call last): ... DecryptionError: Decryption failed ''' blocksize = byte_size(priv_key.n) encrypted = boomCryptConvLib.bytes2int(crypto) decrypted = decrypt_int(encrypted, priv_key.d, priv_key.n) cleartext = boomCryptConvLib.int2bytes(decrypted, blocksize) # If we can't find the cleartext marker, decryption failed. if cleartext[0:2] != boomCryptConvLib.b('\x00\x02'): raise DecryptionError('Decryption failed 1') # Find the 00 separator between the padding and the message try: sep_idx = cleartext.index(boomCryptConvLib.b('\x00'), 2) except ValueError: raise DecryptionError('Decryption failed 2') return cleartext[sep_idx+1:]
def decrypt(crypto, priv_key): r'''Decrypts the given message using PKCS#1 v1.5 The decryption is considered 'failed' when the resulting cleartext doesn't start with the bytes 00 02, or when the 00 byte between the padding and the message cannot be found. :param crypto: the crypto text as returned by :py:func:`rsa.encrypt` :param priv_key: the :py:class:`rsa.PrivateKey` to decrypt with. :raise DecryptionError: when the decryption fails. No details are given as to why the code thinks the decryption fails, as this would leak information about the private key. >>> import rsa >>> (pub_key, priv_key) = rsa.newkeys(256) It works with strings: >>> crypto = encrypt('hello', pub_key) >>> decrypt(crypto, priv_key) 'hello' And with binary data: >>> crypto = encrypt('\x00\x00\x00\x00\x01', pub_key) >>> decrypt(crypto, priv_key) '\x00\x00\x00\x00\x01' Altering the encrypted information will *likely* cause a :py:class:`rsa.pkcs1.DecryptionError`. If you want to be *sure*, use :py:func:`rsa.sign`. .. warning:: Never display the stack trace of a :py:class:`rsa.pkcs1.DecryptionError` exception. It shows where in the code the exception occurred, and thus leaks information about the key. It's only a tiny bit of information, but every bit makes cracking the keys easier. >>> crypto = encrypt('hello', pub_key) >>> crypto = crypto[0:5] + 'X' + crypto[6:] # change a byte >>> decrypt(crypto, priv_key) Traceback (most recent call last): ... DecryptionError: Decryption failed ''' blocksize = byte_size(priv_key.n) encrypted = boomCryptConvLib.bytes2int(crypto) decrypted = decrypt_int(encrypted, priv_key.d, priv_key.n) cleartext = boomCryptConvLib.int2bytes(decrypted, blocksize) # If we can't find the cleartext marker, decryption failed. if cleartext[0:2] != boomCryptConvLib.b('\x00\x02'): raise DecryptionError('Decryption failed 1') # Find the 00 separator between the padding and the message try: sep_idx = cleartext.index(boomCryptConvLib.b('\x00'), 2) except ValueError: raise DecryptionError('Decryption failed 2') return cleartext[sep_idx + 1:]