def decrypt_3des(decoded_item, master_password, global_salt): """ User master key is also encrypted (if provided, the master_password could be used to encrypt it) """ # See http://www.drh-consultancy.demon.co.uk/key3.html pbeAlgo = str(decoded_item[0][0][0]) if pbeAlgo == '1.2.840.113549.1.12.5.1.3': # pbeWithSha1AndTripleDES-CBC entry_salt = decoded_item[0][0][1][0].asOctets() cipher_t = decoded_item[0][1].asOctets() # See http://www.drh-consultancy.demon.co.uk/key3.html hp = sha1(global_salt + master_password).digest() pes = entry_salt + convert_to_byte('\x00') * (20 - len(entry_salt)) chp = sha1(hp + entry_salt).digest() k1 = hmac.new(chp, pes + entry_salt, sha1).digest() tk = hmac.new(chp, pes, sha1).digest() k2 = hmac.new(chp, tk + entry_salt, sha1).digest() k = k1 + k2 iv = k[-8:] key = k[:24] return triple_des(key, CBC, iv).decrypt(cipher_t) # New version elif pbeAlgo == '1.2.840.113549.1.5.13': # pkcs5 pbes2 assert str(decoded_item[0][0][1][0][0]) == '1.2.840.113549.1.5.12' assert str( decoded_item[0][0][1][0][1][3][0]) == '1.2.840.113549.2.9' assert str( decoded_item[0][0][1][1][0]) == '2.16.840.1.101.3.4.1.42' # https://tools.ietf.org/html/rfc8018#page-23 entry_salt = decoded_item[0][0][1][0][1][0].asOctets() iteration_count = int(decoded_item[0][0][1][0][1][1]) key_length = int(decoded_item[0][0][1][0][1][2]) assert key_length == 32 k = sha1(global_salt + master_password).digest() key = pbkdf2_hmac('sha256', k, entry_salt, iteration_count, dklen=key_length) # https://hg.mozilla.org/projects/nss/rev/fc636973ad06392d11597620b602779b4af312f6#l6.49 iv = b'\x04\x0e' + decoded_item[0][0][1][1][1].asOctets() # 04 is OCTETSTRING, 0x0e is length == 14 encrypted_value = decoded_item[0][1].asOctets() aes = AESModeOfOperationCBC(key, iv=iv) cleartxt = b"".join([ aes.decrypt(encrypted_value[i:i + AES_BLOCK_SIZE]) for i in range(0, len(encrypted_value), AES_BLOCK_SIZE) ]) return cleartxt
def decrypt_3des(global_salt, master_password, entry_salt, encrypted_data): """ User master key is also encrypted (if provided, the master_password could be used to encrypt it) """ # See http://www.drh-consultancy.demon.co.uk/key3.html hp = sha1(global_salt + convert_to_byte(master_password)).digest() pes = entry_salt + convert_to_byte('\x00') * (20 - len(entry_salt)) chp = sha1(hp + entry_salt).digest() k1 = hmac.new(chp, pes + entry_salt, sha1).digest() tk = hmac.new(chp, pes, sha1).digest() k2 = hmac.new(chp, tk + entry_salt, sha1).digest() k = k1 + k2 iv = k[-8:] key = k[:24] return triple_des(key, CBC, iv).decrypt(encrypted_data)
def decrypt_3des(global_salt, master_password, entry_salt, encrypted_data): """ User master key is also encrypted (if provided, the master_password could be used to encrypt it) """ # See http://www.drh-consultancy.demon.co.uk/key3.html hp = sha1(global_salt + master_password.encode()).digest() pes = entry_salt + convert_to_byte('\x00') * (20 - len(entry_salt)) chp = sha1(hp + entry_salt).digest() k1 = hmac.new(chp, pes + entry_salt, sha1).digest() tk = hmac.new(chp, pes, sha1).digest() k2 = hmac.new(chp, tk + entry_salt, sha1).digest() k = k1 + k2 iv = k[-8:] key = k[:24] return triple_des(key, CBC, iv).decrypt(encrypted_data)
def decrypt(self, key, iv, ciphertext): """ Decrypt ciphered data (user / password) using the key previously found """ data = triple_des(key, CBC, iv).decrypt(ciphertext) return self.remove_padding(data)
def decrypt(self, key, iv, ciphertext): """ Decrypt ciphered data (user / password) using the key previously found """ data = triple_des(key, CBC, iv).decrypt(ciphertext) return self.remove_padding(data)