def mydecrypt(password, data): ''' Decrypt some data. Input must be bytes. @param password: The secret value used as the basis for a key. This should be as long as varied as possible. Try to avoid common words. @param data: The data to be decrypted, typically as bytes. @return: The decrypted data, as bytes. If the original message was a string you can re-create that using `result.decode('utf8')`. ''' simplecrypt._assert_not_unicode(data) simplecrypt._assert_header_prefix(data) print "mydecrypt -- 1" version = simplecrypt._assert_header_version(data) print "mydecrypt -- 1.1" simplecrypt._assert_decrypt_length(data, version) print "mydecrypt -- 1.2" raw = data[simplecrypt.HEADER_LEN:] salt = raw[:simplecrypt.SALT_LEN[version]//8] print "mydecrypt -- 2" hmac_key, cipher_key = simplecrypt._expand_keys(password, salt) hmac = raw[-simplecrypt.HASH.digest_size:] hmac2 = simplecrypt._hmac(hmac_key, data[:-simplecrypt.HASH.digest_size]) simplecrypt._assert_hmac(hmac_key, hmac, hmac2) print "mydecrypt -- 3" counter = simplecrypt.Counter.new(simplecrypt.HALF_BLOCK, prefix=salt[:simplecrypt.HALF_BLOCK//8]) cipher = simplecrypt.AES.new(cipher_key, simplecrypt.AES.MODE_CTR, counter=counter) r = cipher.decrypt(raw[simplecrypt.SALT_LEN[version]//8:-simplecrypt.HASH.digest_size]) print "[%s] %d" % (r,len(r)) return r
def test_header(self): ctext = bytearray(encrypt('password', 'message')) assert ctext[:HEADER_LEN] == HEADER[LATEST] for i in range(len(HEADER)): ctext2 = bytearray(ctext) ctext2[i] = 1 try: _assert_header_prefix(ctext2) _assert_header_version(ctext2) assert False, 'expected error' except DecryptionException as e: assert 'bad header' in str(e), e if i > 1: assert 'more recent version of simple-crypt' in str(e), e else: assert 'not generated by simple-crypt' in str(e) ctext2 = bytearray(ctext) ctext2[len(HEADER)] = 1 try: decrypt('password', ctext2) assert False, 'expected error' except DecryptionException as e: assert 'format' not in str(e), e