Created
April 29, 2025 10:55
-
-
Save mayconvm/1b7b5aa82d6a6e7b81458c725f5e0e0d to your computer and use it in GitHub Desktop.
Decode file from Whatsapp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "crypto/aes" | |
| "crypto/cipher" | |
| "crypto/hmac" | |
| "crypto/sha256" | |
| "encoding/base64" | |
| "errors" | |
| "fmt" | |
| "strings" | |
| ) | |
| //ref: https://github.com/sostenesapollo/baileys-decode-enc-by-url/blob/master/decode.py | |
| func HKDF(key []byte, length int, appInfo []byte) []byte { | |
| zeroSalt := make([]byte, 32) | |
| h := hmac.New(sha256.New, zeroSalt) | |
| h.Write(key) | |
| prk := h.Sum(nil) | |
| keyStream := make([]byte, 0, length) | |
| keyBlock := make([]byte, 0) | |
| blockIndex := uint8(1) | |
| for len(keyStream) < length { | |
| h := hmac.New(sha256.New, prk) | |
| h.Write(keyBlock) | |
| h.Write(appInfo) | |
| h.Write([]byte{blockIndex}) | |
| keyBlock = h.Sum(nil) | |
| blockIndex++ | |
| keyStream = append(keyStream, keyBlock...) | |
| } | |
| return keyStream[:length] | |
| } | |
| func AESUnpad(padded []byte) ([]byte, error) { | |
| if len(padded) == 0 { | |
| return nil, errors.New("empty padded data") | |
| } | |
| padLen := int(padded[len(padded)-1]) | |
| if padLen > len(padded) || padLen == 0 { | |
| return nil, errors.New("invalid padding") | |
| } | |
| for i := len(padded) - padLen; i < len(padded); i++ { | |
| if padded[i] != byte(padLen) { | |
| return nil, errors.New("invalid padding") | |
| } | |
| } | |
| return padded[:len(padded)-padLen], nil | |
| } | |
| func AESDecrypt(key, ciphertext, iv []byte) ([]byte, error) { | |
| block, err := aes.NewCipher(key) | |
| if err != nil { | |
| return nil, err | |
| } | |
| if len(ciphertext) < aes.BlockSize || len(ciphertext)%aes.BlockSize != 0 { | |
| return nil, errors.New("ciphertext is not a multiple of the block size") | |
| } | |
| if len(iv) != aes.BlockSize { | |
| return nil, errors.New("IV length must equal block size") | |
| } | |
| mode := cipher.NewCBCDecrypter(block, iv) | |
| plaintext := make([]byte, len(ciphertext)) | |
| copy(plaintext, ciphertext) | |
| mode.CryptBlocks(plaintext, plaintext) | |
| return AESUnpad(plaintext) | |
| } | |
| func cleanBase64String(s string) string { | |
| s = strings.ReplaceAll(s, " ", "") | |
| s = strings.ReplaceAll(s, "\n", "") | |
| s = strings.ReplaceAll(s, "\r", "") | |
| return s | |
| } | |
| func DecryptMessage(mediaData []byte, mediaKeyBase64, typeMessageToDecode string) ([]byte, error) { | |
| decodedMediaKey, err := base64.URLEncoding.DecodeString(cleanBase64String(mediaKeyBase64)) | |
| if err != nil { | |
| return nil, fmt.Errorf("erro ao decodificar mediaKey: %w", err) | |
| } | |
| appInfo := []byte(typeMessageToDecode) | |
| mediaKeyExpanded := HKDF(decodedMediaKey, 112, appInfo) | |
| key := mediaKeyExpanded[16:48] | |
| ciphertext := mediaData[:len(mediaData)-10] | |
| iv := mediaKeyExpanded[:16] | |
| return AESDecrypt(key, ciphertext, iv) | |
| } | |
| // DecryptMessage("file.enc", "<mediaKeyBase64>", "WhatsApp Audio Keys") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment