示例#1
0
    def encryptImg(self,img, refkey, mimetype):
        print(mimetype)
        if(mimetype == "audio/wav"):
            derivative = HKDFv3().deriveSecrets(binascii.unhexlify(refkey),
                                            "WhatsApp Audio Keys", 112)
        else:
            derivative = HKDFv3().deriveSecrets(binascii.unhexlify(refkey),
                                            "WhatsApp Image Keys".encode(), 112)
        parts = ByteUtil.split(derivative, 16, 32)
        iv = parts[0]
        cipherKey = parts[1]
        macKey=derivative[48:80]
			
        mac = hmac.new(macKey,digestmod=hashlib.sha256)
        mac.update(iv)
	
        cipher = AES.new(key=cipherKey, mode=AES.MODE_CBC, IV=iv)
        imgEnc = cipher.encrypt(self.pad(img))

        mac.update(imgEnc)
        hash = mac.digest()
        hashKey = ByteUtil.trim(mac.digest(), 10)
	
        finalEnc =  imgEnc + hashKey

        return finalEnc
示例#2
0
def decrypt_file(enc_path, media_key, out_path=""):
    media_key = binascii.hexlify(media_key)
    derivative = HKDFv3().deriveSecrets(binascii.unhexlify(media_key),
                                        binascii.unhexlify(WHATSAPP_KEY), 112)

    splits = ByteUtil.split(derivative, 16, 32)
    iv = splits[0]
    cipher_key = splits[1]

    cipher = AES.new(key=cipher_key, mode=AES.MODE_CBC, IV=iv)

    if (out_path == ""):
        out_path = os.path.splitext(enc_path)[0]

    chunk_size = 4096 * 10
    with open(enc_path, "rb") as in_file:
        with open(out_path, "wb") as out_file:
            while True:
                chunk = in_file.read(chunk_size)
                try:
                    piece = cipher.decrypt(chunk)
                except:
                    # Last chunk most likely to get into here
                    # Because cipher needs a multiple of 16
                    piece = cipher.decrypt(pad(chunk))

                if len(chunk) == 0:
                    break  # end of file

                out_file.write(piece)

    return out_path
    def download_media(self, media_msg, force_download=False):
        if not force_download:
            try:
                if media_msg.content:
                    return BytesIO(b64decode(media_msg.content))
            except AttributeError:
                pass

        file_data = self.download_file(media_msg.client_url)

        if not file_data:
            raise Exception('Impossible to download file')

        media_key = b64decode(media_msg.media_key)
        derivative = HKDFv3().deriveSecrets(
            media_key,
            binascii.unhexlify(media_msg.crypt_keys[media_msg.type]), 112)

        parts = ByteUtil.split(derivative, 16, 32)
        iv = parts[0]
        cipher_key = parts[1]
        e_file = file_data[:-10]

        cr_obj = Cipher(algorithms.AES(cipher_key),
                        modes.CBC(iv),
                        backend=default_backend())
        decryptor = cr_obj.decryptor()
        return BytesIO(decryptor.update(e_file) + decryptor.finalize())
示例#4
0
    def download_media(self, media_msg, force_download=False):
        if not force_download:
            try:
                if media_msg.content:
                    return BytesIO(b64decode(media_msg.content))
            except AttributeError:
                pass

        file_data = self.download_file(media_msg.client_url)

        if not file_data:
            raise Exception('Impossible to download file')

        media_key = b64decode(media_msg.media_key)
        derivative = HKDFv3().deriveSecrets(media_key,
                                            binascii.unhexlify(media_msg.crypt_keys[media_msg.type]),
                                            112)

        parts = ByteUtil.split(derivative, 16, 32)
        iv = parts[0]
        cipher_key = parts[1]
        e_file = file_data[:-10]

        cr_obj = Cipher(algorithms.AES(cipher_key), modes.CBC(iv), backend=default_backend())
        decryptor = cr_obj.decryptor()
        return BytesIO(decryptor.update(e_file) + decryptor.finalize())
示例#5
0
    def decrypt_file(enc_path, media_key, wakey, out_path):
        media_key = binascii.hexlify(media_key)
        derivative = HKDFv3().deriveSecrets(binascii.unhexlify(media_key),
                                            binascii.unhexlify(wakey), 112)

        splits = ByteUtil.split(derivative, 16, 32)
        iv = splits[0]
        cipher_key = splits[1]
        bs = AES.block_size
        cipher = AES.new(key=cipher_key, mode=AES.MODE_CBC, IV=iv)

        chunk_size = 4096 * bs
        with open(enc_path, "rb") as in_file:
            with open(out_path, "wb") as out_file:
                while True:
                    chunk = in_file.read(chunk_size)
                    try:
                        piece = cipher.decrypt(chunk)
                    except:
                        # Last chunk most likely to get into here
                        # Because cipher needs a multiple of 16
                        chunk = chunk[:-10]
                        # assert len(chunk) % bs == 0
                        piece = cipher.decrypt(chunk)
                        padding_len = piece[-1]
                        piece = piece[:-padding_len]
                    if len(chunk) == 0:
                        break  # end of file

                    out_file.write(piece)

        return out_path
示例#6
0
async def download_media(driver: BaseWhalesongDriver,
                         model: MediaMixin) -> BytesIO:
    """
    Download message's attached media file. It will decrypt media file using key on message object.

    :param driver:
    :param model: MediaMixin
    :return: Media stream.
    """
    file_data = (await driver.download_file(model.client_url)).read()

    try:
        media_key = b64decode(model.media_key)
    except Exception:
        media_key = b64decode(model.media_key + ('=' *
                                                 (len(model.media_key) % 3)))

    try:
        derivative = HKDFv3().deriveSecrets(
            media_key, binascii.unhexlify(CRYPT_KEYS[model.type]), 112)
    except KeyError:
        raise ValueError('Invalid message type')

    parts = ByteUtil.split(derivative, 16, 32)
    iv = parts[0]
    cipher_key = parts[1]
    e_file = file_data[:-10]

    cr_obj = Cipher(algorithms.AES(cipher_key),
                    modes.CBC(iv),
                    backend=default_backend())
    decryptor = cr_obj.decryptor()
    return BytesIO(decryptor.update(e_file) + decryptor.finalize())
示例#7
0
    def __init__(self, keyId = None, iteration = None, ciphertext = None, signatureKey = None, serialized = None):
        assert bool(keyId is not None and iteration is not None and ciphertext is not None and signatureKey is not None)\
               ^ bool(serialized),\
            "Either pass arguments or serialized data"

        if serialized:
            try:
                messageParts = ByteUtil.split(serialized, 1, len(serialized)- 1 - self.__class__.SIGNATURE_LENGTH,
                                              self.__class__.SIGNATURE_LENGTH)

                version      = messageParts[0][0]
                message      = messageParts[1]
                signature    = messageParts[2]

                if ByteUtil.highBitsToInt(version) < 3:
                    raise LegacyMessageException("Legacy message: %s" % ByteUtil.highBitsToInt(version))

                if ByteUtil.highBitsToInt(version) > self.__class__.CURRENT_VERSION:
                    raise InvalidMessageException("Unknown version: %s" % ByteUtil.highBitsToInt(version))

                senderKeyMessage = whisperprotos.SenderKeyMessage()
                senderKeyMessage.ParseFromString(message)

                if senderKeyMessage.id is None or senderKeyMessage.iteration is None\
                    or senderKeyMessage.ciphertext is None:
                    raise InvalidMessageException("Incomplete message")

                self.serialized = serialized
                self.messageVersion = ByteUtil.highBitsToInt(version)

                self.keyId          = senderKeyMessage.id
                self.iteration      = senderKeyMessage.iteration
                self.ciphertext     = senderKeyMessage.ciphertext
            except Exception as e:
                raise InvalidMessageException(e)
        else:
            version = [ByteUtil.intsToByteHighAndLow(self.__class__.CURRENT_VERSION, self.__class__.CURRENT_VERSION)]

            message = whisperprotos.SenderKeyMessage()
            message.id = keyId
            message.iteration = iteration
            message.ciphertext = ciphertext
            message = message.SerializeToString()

            signature = self.getSignature(signatureKey, bytes(ByteUtil.combine(version, message)))

            self.serialized       = bytes(ByteUtil.combine(version, message, signature))
            self.messageVersion   = self.__class__.CURRENT_VERSION
            self.keyId            = keyId
            self.iteration        = iteration
            self.ciphertext       = ciphertext
示例#8
0
 def decrypt(self, encaud, refkey):
     derivative = HKDFv3().deriveSecrets(refkey, binascii.unhexlify(self.cryptKeys), 112)
     parts = ByteUtil.split(derivative, 16, 32)
     iv = parts[0]
     cipherKey = parts[1]
     e_aud = encaud[:-10]
     AES.key_size = 128
     cr_obj = AES.new(key=cipherKey, mode=AES.MODE_CBC, IV=iv)
     return cr_obj.decrypt(e_aud)
 def decrypt(self, encimg, refkey):
     derivative = HKDFv3().deriveSecrets(refkey, binascii.unhexlify(self.cryptKeys), 112)
     parts = ByteUtil.split(derivative, 16, 32)
     iv = parts[0]
     cipherKey = parts[1]
     e_img = encimg[:-10]
     AES.key_size=128
     cr_obj = AES.new(key=cipherKey,mode=AES.MODE_CBC,IV=iv)
     return cr_obj.decrypt(e_img)
示例#10
0
 def decrypt(self, encimg, refkey):
     derivative = HKDFv3().deriveSecrets(
         refkey,
         binascii.unhexlify("576861747341707020496d616765204b657973"), 112)
     parts = ByteUtil.split(derivative, 16, 32)
     iv = parts[0]
     cipherKey = parts[1]
     e_img = encimg[:-10]
     AES.key_size = 128
     cr_obj = AES.new(key=cipherKey, mode=AES.MODE_CBC, IV=iv)
     return cr_obj.decrypt(e_img)
示例#11
0
    def verifySignature(self, signatureKey):
        """
        :type signatureKey: ECPublicKey
        """
        try:
            parts = ByteUtil.split(self.serialized, len(self.serialized)- self.__class__.SIGNATURE_LENGTH, self.__class__.SIGNATURE_LENGTH)

            if not Curve.verifySignature(signatureKey, parts[0], parts[1]):
                raise InvalidMessageException("Invalid signature!")
        except InvalidKeyException as e:
            raise InvalidMessageException(e)
    def __init__(self, id = None, iteration = None, chainKey = None, signatureKey = None, serialized = None):
        """
        :type id: int
        :type iteration: int
        :type chainKey: bytearray
        :type signatureKey: ECPublicKey
        """


        assert bool(id is not None and iteration is not None and chainKey is not None and signatureKey is not None)\
               ^ bool(serialized),\
            "Either pass arguments or serialized data"

        if serialized:
            try:
                messageParts = ByteUtil.split(serialized, 1, len(serialized)- 1)
                version      = messageParts[0][0]
                message      = messageParts[1]


                if ByteUtil.highBitsToInt(version) < 3:
                    raise LegacyMessageException("Legacy message: %s" % ByteUtil.highBitsToInt(version))

                if ByteUtil.highBitsToInt(version) > self.__class__.CURRENT_VERSION:
                    raise InvalidMessageException("Unknown version: %s" % ByteUtil.highBitsToInt(version))


                distributionMessage = whisperprotos.SenderKeyDistributionMessage()
                distributionMessage.ParseFromString(message)

                if distributionMessage.id is None or distributionMessage.iteration is None\
                    or distributionMessage.chainKey is None or distributionMessage.signingKey is None:
                    raise InvalidMessageException("Incomplete message")

                self.serialized = serialized

                self.id           = distributionMessage.id
                self.iteration    = distributionMessage.iteration
                self.chainKey     = distributionMessage.chainKey
                self.signatureKey = Curve.decodePoint(bytearray(distributionMessage.signingKey), 0)

            except Exception as e:
                raise InvalidMessageException(e)
        else:
            version = [ByteUtil.intsToByteHighAndLow(self.__class__.CURRENT_VERSION, self.__class__.CURRENT_VERSION)]
            self.id = id
            self.iteration = iteration
            self.chainKey = chainKey
            self.signatureKey = signatureKey
            message = whisperprotos.SenderKeyDistributionMessage()
            message.id = id
            message.iteration = iteration
            message.chainKey= bytes(chainKey)
            message.signingKey = signatureKey.serialize()
            message = message.SerializeToString()
            self.serialized = bytes(ByteUtil.combine(version, message))
示例#13
0
    def decrypt(self, encimg, refkey, tipo="image"):
        cryptKeys = self.getCryptKeys(tipo)
        refkey = base64.b64decode(refkey)

        derivative = HKDFv3().deriveSecrets(refkey,
                                            binascii.unhexlify(cryptKeys), 112)
        parts = ByteUtil.split(derivative, 16, 32)
        iv = parts[0]
        cipherKey = parts[1]
        e_img = encimg[:-10]
        cr_obj = AES.new(key=cipherKey, mode=AES.MODE_CBC, IV=iv)
        return cr_obj.decrypt(e_img)
示例#14
0
    def __init__(self, iteration, seed):
        """
        :type iteration: int
        :type seed: bytearray
        """
        derivative = HKDFv3().deriveSecrets(seed, "WhisperGroup".encode(), 48)
        parts = ByteUtil.split(derivative, 16, 32)

        self.iteration = iteration
        self.seed = seed
        self.iv = parts[0]
        self.cipherKey = parts[1]
    def encryptImg(self, img, refkey):
        derivative = HKDFv3().deriveSecrets(binascii.unhexlify(refkey),
                                            binascii.unhexlify(WHATSAPP_KEY),
                                            112)
        parts = ByteUtil.split(derivative, 16, 32)
        iv = parts[0]
        cipherKey = parts[1]
        macKey = derivative[48:80]

        mac = hmac.new(macKey, digestmod=hashlib.sha256)
        mac.update(iv)

        cipher = AES.new(key=cipherKey, mode=AES.MODE_CBC, IV=iv)
        imgEnc = cipher.encrypt(self.pad(img))

        mac.update(imgEnc)
        hash = mac.digest()
        hashKey = ByteUtil.trim(mac.digest(), 10)

        finalEnc = imgEnc + hashKey
        return finalEnc
示例#16
0
    def test_split(self):
        okm = HexUtil.decodeHex('02a9aa6c7dbd64f9d3aa92f92a277bf54609dadf0b00828acfc61e3c724b84a7bfbe5efb603030526742e3ee89c7024e884e' \
                 '440f1ff376bb2317b2d64deb7c8322f4c5015d9d895849411ba1d793a827')

        data = [i for i in range(0, 80)]
        a_data = [i for i in range(0, 32)]
        b_data = [i for i in range(32, 64)]
        c_data = [i for i in range(64, 80)]

        a,b,c = ByteUtil.split(data, 32, 32, 16)

        self.assertEqual(a, a_data)
        self.assertEqual(b, b_data)
        self.assertEqual(c, c_data)
示例#17
0
    def encrypt(self, plaintext, ref_key, media_info):
        derived = HKDFv3().deriveSecrets(ref_key, media_info, 112)
        parts = ByteUtil.split(derived, 16, 32)
        iv = parts[0]
        key = parts[1]
        mac_key = derived[48:80]

        cipher_encryptor = Cipher(
            algorithms.AES(key), modes.CBC(iv), backend=default_backend()
        ).encryptor()
        ciphertext = cipher_encryptor.update(plaintext) + cipher_encryptor.finalize()

        mac = hmac.new(mac_key, digestmod=hashlib.sha256)
        mac.update(iv)
        mac.update(ciphertext)

        return ciphertext + mac.digest()[:10]
示例#18
0
async def download_media(driver, model):
    file_data = (await driver.download_file(model.client_url)).read()

    media_key = b64decode(model.media_key)
    try:
        derivative = HKDFv3().deriveSecrets(media_key,
                                            binascii.unhexlify(CRYPT_KEYS[model.type]),
                                            112)
    except KeyError:
        raise ValueError('Invalid message type')

    parts = ByteUtil.split(derivative, 16, 32)
    iv = parts[0]
    cipher_key = parts[1]
    e_file = file_data[:-10]

    cr_obj = Cipher(algorithms.AES(cipher_key), modes.CBC(iv), backend=default_backend())
    decryptor = cr_obj.decryptor()
    return BytesIO(decryptor.update(e_file) + decryptor.finalize())
示例#19
0
def decrypt(Url,MediaKey,filename,tipo):
	try:
		CipherData = urlopen(Url).read()
		CipherImage = CipherData[:-10]
		cryptKeys = getCryptKeys(tipo)

	#	SecretsRaw = HKDFv3().deriveSecrets(MediaKey, "WhatsApp Image Keys", 112)
		SecretsRaw = HKDFv3().deriveSecrets(MediaKey, binascii.unhexlify(cryptKeys), 112)
		Secrets = ByteUtil.split(SecretsRaw, 16, 32)
		iv = Secrets[0]
		CipherKey = Secrets[1]
		AES.key_size=128
		AESInstance = AES.new(key=CipherKey, mode=AES.MODE_CBC, IV=iv)
		PlainImage = AESInstance.decrypt(CipherImage)

		with open(filename, 'wb') as f:
			f.write(PlainImage)
			f.close()
		return "success";
	except:
		return;
示例#20
0
    def decrypt(self, ciphertext, ref_key, media_info):
        derived = HKDFv3().deriveSecrets(ref_key, media_info, 112)
        parts = ByteUtil.split(derived, 16, 32)
        iv = parts[0]
        key = parts[1]
        mac_key = derived[48:80]
        media_ciphertext = ciphertext[:-10]
        mac_value = ciphertext[-10:]

        mac = hmac.new(mac_key, digestmod=hashlib.sha256)
        mac.update(iv)
        mac.update(media_ciphertext)

        if mac_value != mac.digest()[:10]:
            raise ValueError("Invalid MAC")

        cipher_decryptor = Cipher(
            algorithms.AES(key), modes.CBC(iv), backend=default_backend()
        ).decryptor()

        return cipher_decryptor.update(media_ciphertext) + cipher_decryptor.finalize()
示例#21
0
    def encrypt(self, plaintext, ref_key, media_info):
        derived = HKDFv3().deriveSecrets(ref_key, media_info, 112)
        parts = ByteUtil.split(derived, 16, 32)
        iv = parts[0]
        key = parts[1]
        mac_key = derived[48:80]

        cipher_encryptor = Cipher(
            algorithms.AES(key), modes.CBC(iv), backend=default_backend()
        ).encryptor()
        if len(plaintext) % 16 != 0:
            padder = padding.PKCS7(128).padder()
            padded_plaintext = padder.update(plaintext) + padder.finalize()
        else:
            padded_plaintext = plaintext
        ciphertext = cipher_encryptor.update(padded_plaintext) + cipher_encryptor.finalize()

        mac = hmac.new(mac_key, digestmod=hashlib.sha256)
        mac.update(iv)
        mac.update(ciphertext)

        return ciphertext + mac.digest()[:10]
示例#22
0
    def download_media(self, media_msg):
        try:
            if media_msg.content:
                return BytesIO(b64decode(self.content))
        except AttributeError:
            pass

        file_data = self.download_file(media_msg.client_url)

        media_key = b64decode(media_msg.media_key)
        derivative = HKDFv3().deriveSecrets(
            media_key,
            binascii.unhexlify(media_msg.crypt_keys[media_msg.type]), 112)

        parts = ByteUtil.split(derivative, 16, 32)
        iv = parts[0]
        cipher_key = parts[1]
        e_file = file_data[:-10]

        AES.key_size = 128
        cr_obj = AES.new(key=cipher_key, mode=AES.MODE_CBC, IV=iv)

        return BytesIO(cr_obj.decrypt(e_file))
示例#23
0
    def decrypt(self, ciphertext, ref_key, media_info):
        derived = HKDFv3().deriveSecrets(ref_key, media_info, 112)
        parts = ByteUtil.split(derived, 16, 32)
        iv = parts[0]
        key = parts[1]
        mac_key = derived[48:80]
        media_ciphertext = ciphertext[:-10]
        mac_value = ciphertext[-10:]

        mac = hmac.new(mac_key, digestmod=hashlib.sha256)
        mac.update(iv)
        mac.update(media_ciphertext)

        if mac_value != mac.digest()[:10]:
            raise ValueError("Invalid MAC")

        cipher_decryptor = Cipher(
            algorithms.AES(key), modes.CBC(iv), backend=default_backend()
        ).decryptor()

        decrypted = cipher_decryptor.update(media_ciphertext) + cipher_decryptor.finalize()
        unpadder = padding.PKCS7(128).unpadder()
        return unpadder.update(decrypted) + unpadder.finalize()
示例#24
0
    def __init__(self, messageVersion = None, sequence = None, flags=None,
                 baseKey = None, baseKeySignature = None,
                 ratchetKey = None,
                 identityKey = None,
                 serialized = None):
        """
        :type messageVersion: int
        :type  sequence: int
        :type flags:int
        :type baseKey: ECPublicKey
        :type baseKeySignature: bytearray
        :type ratchetKey: ECPublicKey
        :type identityKey: IdentityKey
        :type serialized: bytearray
        """
        if serialized:
            try:
                parts                 = ByteUtil.split(serialized, 1, len(serialized)- 1)
                self.version          = ByteUtil.highBitsToInt(parts[0][0])
                self.supportedVersion = ByteUtil.lowBitsToInt(parts[0][0])
                if self.version <= CiphertextMessage.UNSUPPORTED_VERSION:
                    raise LegacyMessageException("Unsupportmessageed legacy version: %s" % self.version)
                if self.version > CiphertextMessage.CURRENT_VERSION:
                    raise InvalidVersionException("Unkown version: %s" % self.version)
                message = whisperprotos.KeyExchangeMessage()
                message.ParseFromString(bytes(parts[1]))

                if not message.HasField("id") or not message.HasField("baseKey")\
                    or not message.HasField("ratchetKey") or not message.HasField("identityKey")\
                    or (self.version >= 3 and not message.HasField("baseKeySignature")):
                    raise InvalidMessageException("Some required fields are missing!")

                self.sequence = message.id >> 5
                self.flags = message.id & 0x1f
                self.serialized = serialized
                self.baseKey = Curve.decodePoint(bytearray(message.baseKey), 0)
                self.baseKeySignature = message.baseKeySignature
                self.ratchetKey = Curve.decodePoint(bytearray(message.ratchetKey), 0)
                self.identityKey = IdentityKey(message.identityKey, 0)

            except InvalidKeyException as e:
                raise InvalidMessageException(e)
        else:

            self.supportedVersion = CiphertextMessage.CURRENT_VERSION
            self.version          = messageVersion
            self.sequence         = sequence
            self.flags            = flags
            self.baseKey          = baseKey
            self.baseKeySignature = baseKeySignature
            self.ratchetKey       = ratchetKey
            self.identityKey      = identityKey

            version = [ByteUtil.intsToByteHighAndLow(self.version, self.supportedVersion)]
            keyExchangeMessage = whisperprotos.KeyExchangeMessage()
            keyExchangeMessage.id = (self.sequence << 5) | self.flags
            keyExchangeMessage.baseKey = baseKey.serialize()
            keyExchangeMessage.ratchetKey = ratchetKey.serialize()
            keyExchangeMessage.identityKey = identityKey.serialize()

            if messageVersion >= 3:
                keyExchangeMessage.baseKeySignature = baseKeySignature

            self.serialized = ByteUtil.combine(version, keyExchangeMessage.SerializeToString())