encryptionaeshttp-live-streamingpocofmp4

HLS. Decrypt fmp4 segment (AES-128)


I want to decrypt fmp4 segment. This segment was encrypt with HLS Apple Tools (https://developer.apple.com/documentation/http_live_streaming/about_apple_s_http_live_streaming_tools)

METHOD is AES-128

IV is 1d48fc5dee84b5a3e9a428f055e03c2e

I have a key and IV (you can got the key, and segment in google drive https://drive.google.com/drive/folders/1xF-C9EXFvT8qjI--sBB6QMPn8cNW7L-D?usp=sharing)

To decrypt I use Poco library.

This is my code:

    Poco::Crypto::Cipher::ByteVec readKey(const std::string& uri) {
        Poco::Crypto::Cipher::ByteVec key;

        auto stream = Stream::makeStream(uri);
        if (stream->open(uri, {})) {
            key.resize(KEY_SIZE);
            stream->read((char*)&key[0], KEY_SIZE);
        }

        return key;
    }


std::vector<uint8_t> _key = readKey("./unit-tests/resources/cipher-stream/file.key");

std::string ivSrc = "1d48fc5dee84b5a3e9a428f055e03c2e";
Poco::Crypto::Cipher::ByteVec iv {ivSrc.begin(), ivSrc.end()};
Poco::Crypto::CipherKey key("aes-128-cbc", _key, iv);
Poco::Crypto::Cipher::Ptr cipher = Poco::Crypto::CipherFactory::defaultFactory().createCipher(key);

Poco::FileInputStream src("./unit-tests/resources/cipher-stream/fileSequence1.m4s");
Poco::FileOutputStream dst("./unit-tests/resources/cipher-stream/fileSequence1_dec.m4s");

Poco::Crypto::CryptoOutputStream decryptor(dst, cipher->createDecryptor());
Poco::StreamCopier::copyStream(src, decryptor);

// decryptor.close();
src.close();
dst.close();

Problem description: After decryption I got distorted data. You can see this at the beginning of the file. Please see picture below. On the right side of the image file is distorted. The correct data you can see on the left side.

enter image description here


Solution

  • You're using the wrong IV; that will lead to the first block (16 bytes) being corrupted. Your IV hex value is 1d48fc5dee84b5a3e9a428f055e03c2e, but you're interpreting that as ASCII. It's using the first 16 bytes of your string and ignoring the rest.

    I haven't used Poco in a long time and don't remember if there's a hex parser handy, but that's what you need. Or write the IV directly in hex rather than as an ASCII string.