3

I have a javascript code from a page that looks like

var link = '{"ct":"AAQz1rUDqp849MRxu0tqGRGvPcLzVG24xa5zbYxpwVHH6Z2p95xPPzNhMIRMcaTPvijE71RQU1X3cQhtnXdRScA6UBiLWNs9vMul2gldnMTpT92sDYHl+hKBGy2dR22Un7ElToipSqeqRrwhEK8T9ROMChrBw8i7JOICpOYoVhqDB72BH2RG\/PqjRqsKittES5BVhTTY9cs+zQI0rM+FQA62bVCL57P3RD+E+aWJJLjUvoXBqct6Jc5W7li9mk9udgn9rPKkCbXSCvwIxcWS5C1kw4uSO7y0IlovaTWLAIw5nY0l4REjbC1wPWrtxDWLlr8J+\/sQdDF+P61VHz6yiC+w56QLDjVwz4kBl3r3uP\/VZ7kUuLwWHSHnbmmXv31f","iv":"feae762ac889376169708872d9676319","s":"9b2328e8a4ee2717"}';
var msg = "f12c8b59265dc1e898135211cc30be49";    
var finalUrl = JSON.parse(CryptoJS.AES.decrypt(link, msg, {format: CryptoJSAesJson}).toString(CryptoJS.enc.Utf8));

I figure that ct is encrypted msg, s is for Salt and iv is iv

I am trying to decode the finalUrl with python.

AES = AESDecrypter()
decryptor = AES.new(s, AES.MODE_CBC, IV=iv)
dec = decryptor.decrypt(ct)

I know it is not going to work as I can't figure how to use

var msg = "f12c8b59265dc1e898135211cc30be49"

in Python. Also figured that CryptoJSAesJson may have some extra function. Someone please show me steps how I can retrieve the finalUrl with Python with the data given here. Any suggestion is really appreciated. Apology for my poor coding knowledge.

evandrix
  • 6,041
  • 4
  • 27
  • 38
Shawon Md
  • 195
  • 1
  • 2
  • 12
  • link to the definition of [`CryptoJSAesJson`](https://raw.githubusercontent.com/meetio/cryptojs-aes/master/aes-json-format.js) – evandrix Sep 10 '22 at 06:59

1 Answers1

3

The actual AES key is derived by the following procedure (derived from https://stackoverflow.com/a/27582253/5722339):

  1. Required libraries.

    import base64;
    import hashlib;
    from Crypto.Cipher import AES;
    
  2. Decode the provided inputs to raw bytes from hex or base64 string.

    ct = base64.b64decode("AAQz1rUDqp849MRx ... bmmXv31f");
    iv = bytes.fromhex("feae762ac889376169708872d9676319");
    salt = bytes.fromhex("9b2328e8a4ee2717");
    
    # In your case, the pass phrase is NOT a hex-encoded byte array.
    #  It is directly used as bytes.
    pass_phrase = b"f12c8b59265dc1e898135211cc30be49";
    
  3. Hash the pass phrase and the salt with MD5 digest to derive the first 128 bits (16 bytes) of the key.

    md = hashlib.md5();
    md.update(pass_phrase);
    md.update(salt);
    cache0 = md.digest();
    
  4. Hash the previously derived 16 bytes, followed by the pass phrase and the salt with MD5 digest again to derive the latter 128 bits (16 bytes) of the key.

    md = hashlib.md5();
    md.update(cache0);
    md.update(pass_phrase);
    md.update(salt);
    cache1 = md.digest();
    
  5. Concatenate the two byte arrays to acquire the 256 bits AES key.

    key = cache0 + cache1;
    
  6. Finally, decrypt the cipher text using 256 bits AES with CBC mode.

    cipher = AES.new(key, AES.MODE_CBC, iv);
    result = cipher.decrypt(ct);
    

    The decrypted data is now stored in the result as a byte array.

Please node that while the cipher text ct in your sample input is base64 encoded, and the salt and iv are both hex encoded, the pass phrase is NOT hex encoded (although it looks like that).

Also you might need to un-pad the output first before using it. The un-pad function can be achieved by using lambda: (solution from https://stackoverflow.com/a/12525165/5722339)

unpad = lambda s : s[:-ord(s[len(s)-1:])];

The output of your sample input is: http:\/\/pmd.dittotv3.com.edgesuite.net\/draco\/shows\/Zee_Bangla\/Dweep_Jwele_Jai\/July\/19072016\/Webisode\/Dweep_Jwele_Jai_Webisode_19072016_100.mp4?key1=ozee.com&hdnea=st=1469018324~exp=1469020124~acl=%2F%2A~hmac=07e8cf2b49f51899f60b129f3a99eb792f45e779fbdae94d4a70215398fc590d