Esempio n. 1
0
    def pass_decrypt_new(self, encrypted_pwd):
        """ Decrypts a password from ClawsMail. => new version """
        # Everything is explained on the doc / code
        # https://github.com/eworm-de/claws-mail/blob/master/doc/src/password_encryption.txt
        # https://github.com/eworm-de/claws-mail/blob/aca15d9a473bdfdeef4a572b112ff3679d745247/src/password.c#L409

        m = re.match('{(.*),(.*)}(.*)', encrypted_pwd)
        if m:
            # rounds and pbkdf2_rounds should be identical
            mode, rounds, enc_pwd = m.groups()

        masterkey = pbkdf2(self.passcrypt_key, self.salt, int(rounds),
                           self.KEYLEN)

        raw = b64decode(enc_pwd)
        aes = AESModeOfOperationCBC(masterkey, iv='\0' * 16)
        cleartxt = b"".join([
            aes.decrypt(raw[i:i + self.AES_BLOCK_SIZE])
            for i in range(0, len(raw), self.AES_BLOCK_SIZE)
        ])
        plaintext = cleartxt[self.AES_BLOCK_SIZE:]

        try:
            return plaintext.decode()
        except Exception:
            # Password seems not correct
            return plaintext
Esempio n. 2
0
 def chrome_decrypt(self, encrypted_value, key, init_vector):
     encrypted_value = encrypted_value[3:]
     aes = AESModeOfOperationCBC(key, iv=init_vector)
     cleartxt = b"".join([
         aes.decrypt(encrypted_value[i:i + self.AES_BLOCK_SIZE])
         for i in range(0, len(encrypted_value), self.AES_BLOCK_SIZE)
     ])
     return self.remove_padding(cleartxt)
Esempio n. 3
0
    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