;iM?2UdZddlZddlZddlZddlZddlmZddlmZm Z m Z m Z ej rej ZnejZdddd d d d Zejejejejejejd Zejeejgeffed < ejdkrAeddddeejejej dGdde!Z"Gdde"Z#Gdde"Z$de%de&de%fdZ'de%de&de%fdZ(de%de j)de%fdZ*d e%d!e j+de%fd"Z,d#e%d!e j+d$ede%fd%Z-de%d!e j+d$ede%fd&Z.de%d'e%de j)defd(Z/d'e%de j)defd)Z0d*ej1d+e&dej2e%fd,Z3dej4e%ej1fd-ede%fd.Z5d/e%defd0Z6gd1Z7e8d2krYe9d3ddl:Z:e;d4D]1Z<e:j=\Z>Z?e>rne>> block = _pad_for_encryption(b'hello', 16) >>> len(block) 16 >>> block[0:2] b'\x00\x02' >>> block[-6:] b'\x00hello' ;%i bytes needed for message, but there is only space for %irr N)len OverflowErrorosurandomreplacejoin)rr max_msglength msglengthpaddingpadding_length needed_bytes new_paddings r_pad_for_encryptionr0^s"B&MG I=   (-8 9   G"Y.2N g,, ' '%G 4 j!122 !))'377 K  66 g,, ' ' w<<> ) ) ) ) 88['7G< = ==rc|dz }t|}||krtd||fz||z dz }dd|dzd|gS)ajPads the message for signing, returning the padded message. The padding is always a repetition of FF bytes. :return: 00 01 PADDING 00 MESSAGE >>> block = _pad_for_signing(b'hello', 16) >>> len(block) 16 >>> block[0:2] b'\x00\x01' >>> block[-6:] b'\x00hello' >>> block[2:-6] b'\xff\xff\xff\xff\xff\xff\xff\xff' rr r rsr")r$r%r))rrr*r+r-s r_pad_for_signingr3sy&"B&MG I=   (-8 9   #Y.2N 88[.7":GWM N NNrpub_keyctj|j}t||}t j|}t j||j|j}t j ||}|S)aEncrypts 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 = b'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 ) r byte_sizenr0r bytes2intr encrypt_inte int2bytes)rr4 keylengthpaddedpayload encryptedblocks rencryptrAsd, ++I ) 4 4F!&))G ')WY??I   9 5 5E Lrcryptopriv_keyctj|j}tj|}||}tj||}t||krtdt|ddd }| dd}|dk}||z} | rtd||dzdS)aaDecrypts 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(b'hello', pub_key) >>> decrypt(crypto, priv_key) b'hello' And with binary data: >>> crypto = encrypt(b'\x00\x00\x00\x00\x01', pub_key) >>> decrypt(crypto, priv_key) b'\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(b'hello', pub_key) >>> crypto = crypto[0:5] + b'X' + crypto[6:] # change a byte >>> decrypt(crypto, priv_key) Traceback (most recent call last): ... rsa.pkcs1.DecryptionError: Decryption failed zDecryption failedNr#r" r) rr6r7rr8blinded_decryptr;r$rrfind) rBrC blocksizer? decrypted cleartextcleartext_marker_badsep_idx sep_idx_bad anything_bads rdecryptrPsf ,,I#F++I((33I#Iy99I  6{{Y1222 .im[IIInnWa((GB,K'+5L31222 Wq[]] ##r hash_value hash_methodc.|tvrtd|zt|}||z}tj|j}t ||}t j|}||}t j ||} | S)abSigns 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 hash_value: A precomputed hash to sign (ignores message). :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-224', 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. Invalid hash method: %s) HASH_ASN1 ValueErrorrr6r7r3rr8blinded_encryptr;) rQrCrRasn1coderKr<r=r>r?r@s r sign_hashrYs")##2[@AAA%H:%I ,,I i 3 3F!&))G((11I   9 5 5E LrcDt||}t|||S)aSigns 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-224', 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. ) compute_hashrY)rrCrRmsg_hashs rsignr]@s%$G[11H Xx 5 55r signaturectj|j}tj|}t j||j|j}tj||}t|}t||}t||z} t| |} t||krtd| |krtd|S)aJVerifies 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. :returns: the name of the used hash. Verification failed)rr6r7rr8r decrypt_intr:r;_find_method_hashr[rUr3r$r) rr^r4r<r?rJclearsig method_name message_hashrKexpecteds rverifyrgVs ++I#I..I GIwyAAI"9i88H$H--K55L+&5I 955H 9~~"" 56668 5666 rctj|j}tj|}t j||j|j}tj||}t|S)aReturns 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. ) rr6r7rr8rrar:r;rb)r^r4r<r?rJrcs rfind_signature_hashri|s^ ++I#I..I GIwyAAI"9i88H X & &&rinfilerIc#zK ||}t|}|dkrdS|V||krdS9)zGenerator, yields each block of ``blocksize`` bytes in the input file. :param infile: file to read and separate in blocks. :param blocksize: block size in bytes. :returns: a generator that yields the contents of each block TrN)readr$)rjrIr@ read_bytess ryield_fixedblocksrnsS  I&&ZZ ?? E  ! ! E rrdc|tvrtd|zt|}|}t|tr||nOt |drt |jdsJt|dD]}|||S)a>Returns the message digest. :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 method_name: the hash method, must be a key of :py:const:`rsa.pkcs1.HASH_METHODS`. rTrl__call__i) r rV isinstancebytesupdatehasattrrlrndigest)rrdmethodhasherr@s rr[r[s,&&2[@AAA + &F VXXF'5!!! gw''MGGL*,M,MMMM&w55 ! !E MM% ==??rrccntD] \}}||vr|cStd)zFinds the hash method. :param clearsig: full padded ASN1 and hash. :return: the used hash method. :raise VerificationFailed: when the hash method cannot be found r`)rUitemsr)rchashnamerXs rrbrbsL!* 1 18 x  OOO  1 2 22r)rArPr]rgrrr__main__z'Running doctests 1000x or until failureidz%i timesz Doctests done)@rhashlibr&systypinghmacrrrrr TYPE_CHECKING_HashHashTypeAnyrUmd5sha1sha224sha256sha384sha512r DictstrCallable__annotations__ version_inforssha3_256sha3_384sha3_512 Exceptionrrrrrintr0r3 PublicKeyrA PrivateKeyrPrYr]rgriBinaryIOIteratorrnUnionr[rb__all__rprintdoctestrangecounttestmodfailurestestsrrrrs    ************ }HHzH W L^^^^     ; \~~~~ AA fk#vr8|<<=.v ggg  (((  88888)888(((((k(((***** ****>*>s*>u*>*>*>*>ZOeOCOEOOOOBUS]u@P$EP$S^P$P$P$P$P$f%3>PUB6%63>666666,#E#e#cm#####L'5'3='S''''&fo#&/RWBX*&,ufo'=>SUZ8 3 3# 3 3 3 3    z E 3444NNNt&&+GO--5   E 3;!    E*u$ % % % E/r