Azure / azure-sdk-for-php

Microsoft Azure SDK for PHP
http://azure.microsoft.com/en-us/develop/php/
Apache License 2.0
415 stars 273 forks source link

ContentKey has bad Checksum #982

Open adamhewitt627 opened 6 years ago

adamhewitt627 commented 6 years ago

I'm fairly certain my understanding of this is correct, but:

  1. I'm a .NET guy, not PHP. (I am also the Azure expert internally, hence I'm investigating, but we have a PHP backend so we used this SDK)
  2. I don't even know where to begin to try running this to check my suspicion. (I can create new content keys with REST and the .NET SDK.)
  3. I don't know why I'd be the only one broken.

When creating a new content key with a generated KID, $contentKey = new ContentKey() we see here that $this->_id is used for the checksum, except from the constructor, _id includes "nb:kid:UUID:". The .NET and REST documentation show creating this checksum from the Guid, not the entire entity ID as it would be on Azure.

Example

$protectionKeyId = $restProxy->getProtectionKeyId($contentKeyType);
$protectionKey = $restProxy->getProtectionKey($protectionKeyId);
$contentKey = new ContentKey();
$contentKey->setContentKey($aesKey, $protectionKey);

$restProxy->createContentKey($contentKey);

The end result of this is a 500 error when trying to retrieve a FairPlay license. Everything about the key looks right, but the checksum is different than if I calculate it with .NET. Correct the checksum and the 500 error goes away.

adamhewitt627 commented 6 years ago

For the record, this outputs the same checksum as the .NET SDK

<?php
    $aesKey = array(/* 16 byte key */);
    $encryptionKey = implode(array_map("chr", $aesKey));

    $kid = array(/* the 16 bytes that the UUID represents, C#'s System.Guid.ToByteArray() */);
    $kidStr = implode(array_map("chr", $kid));

    $encrypted = openssl_encrypt($kidStr, "AES-128-ECB", $encryptionKey, 1/*OPENSSL_RAW_DATA*/);
    $checksum = substr($encrypted, 0, 8);

    echo base64_encode($checksum)."\n";
?>