Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClearKey Decryption Error #4075

Closed
adamhewitt627 opened this issue Apr 3, 2018 · 10 comments
Closed

ClearKey Decryption Error #4075

adamhewitt627 opened this issue Apr 3, 2018 · 10 comments
Assignees
Labels

Comments

@adamhewitt627
Copy link

Issue description

When attempting to play a protected file with DRM encryption, I get the a decryption error. I am able to play successfully except when the base64 key contains a /. I have tried all of the following in my offline key:

  • "...\"k\":\"sqvlkIJdgicc/AYGBjyBmQ\"..."
  • "...\"k\":\"sqvlkIJdgicc\\/AYGBjyBmQ\"..."
  • "...\"k\":\"sqvlkIJdgicc_AYGBjyBmQ\"..."

All three produce the following error: ('+'/'-' seems to work fine)

E/ExoPlayerImplInternal: Renderer error.
    com.google.android.exoplayer2.ExoPlaybackException
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.feedInputBuffer(MediaCodecRenderer.java:765)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:568)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:518)
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:301)
        at android.os.Handler.dispatchMessage(Handler.java:98)
        at android.os.Looper.loop(Looper.java:154)
        at android.os.HandlerThread.run(HandlerThread.java:61)
    Caused by: android.media.MediaCodec$CryptoException: Decryption Error
        at android.media.MediaCodec.native_queueSecureInputBuffer(Native Method)
        at android.media.MediaCodec.queueSecureInputBuffer(MediaCodec.java:2480)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.feedInputBuffer(MediaCodecRenderer.java:756)
        at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:568) 
        at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:518) 
        at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:301) 
        at android.os.Handler.dispatchMessage(Handler.java:98) 
        at android.os.Looper.loop(Looper.java:154) 
        at android.os.HandlerThread.run(HandlerThread.java:61) 

Reproduction steps

final byte[] keyResponse = "{\"type\":\"temporary\",\"keys\":[{\"kid\":\"nrQFDeRLSAKTLifXUIPiZg\",\"k\":\"sqvlkIJdgicc\\/AYGBjyBmQ\",\"kty\":\"oct\"}]}".getBytes("UTF-8");

DrmSessionManager<FrameworkMediaCrypto> drmSessionManager = DefaultDrmSessionManager.newFrameworkInstance(C.CLEARKEY_UUID, new LocalMediaDrmCallback(keyResponse), new HashMap<String, String>(), null, null);

Version of ExoPlayer being used

ExoPlayer 2.7.0

Device(s) and version(s) of Android being used

6.0.0 Visual Studio Emulator
7.1.1 Nexus 6

@ojw28
Copy link
Contributor

ojw28 commented Apr 3, 2018

I don't think / is valid in the key. Keys are supposed to be base64url encoded, which is not quite the same as regular base64 encoding. In particular, see: https://www.w3.org/TR/encrypted-media/#using-base64url

Does that answer your question? Thanks.

@ojw28 ojw28 added the question label Apr 3, 2018
@adamhewitt627
Copy link
Author

Yes, I recognize that. Note that the 3rd of my shown attempts would be the base64url encoding of that slash. (Though I do see that the "reproduction" I copied over was an attempt to maintain the slash.) Of note, however, is that having a + in the key does not break the decryption.

@ojw28
Copy link
Contributor

ojw28 commented Apr 3, 2018

Ah, got it! I'm not sure we should spend much time wondering about the behavior when using +. It's probably valid for the underlying CDM to handle or not handle incorrect encoding :).

Focusing on the / issue, what's the original unencoded key? Does the content play successfully on other devices, when using correct base64url encoding? If it's just the Visual Studio emulator that has the issue, you should probably file a bug on whoever maintains that.

@adamhewitt627
Copy link
Author

As reported, the same failure occurs on a Nexus 6 running 7.1.1. The original key is:

0xB2, 0xAB, 0xE5, 0x90, 0x82, 0x5D, 0x82, 0x27, 0x1C, 0xFC, 0x06, 0x06, 0x06, 0x3C, 0x81, 0x99

@ojw28
Copy link
Contributor

ojw28 commented Apr 4, 2018

It looks like you're not encoding the key correctly. Isn't the base64url encoding of that key kTQZUWlrXhuiMkOezsHxKg? Which seems to work for me for the test stream provided.

@adamhewitt627
Copy link
Author

String key = Base64.encodeToString(new byte[]{(byte)0xB2, (byte)0xAB, (byte)0xE5, (byte)0x90, (byte)0x82, (byte)0x5D, (byte)0x82, (byte)0x27, (byte)0x1C, (byte)0xFC, (byte)0x06, (byte)0x06, (byte)0x06, (byte)0x3C, (byte)0x81, (byte)0x99}, Base64.URL_SAFE);

//key == "sqvlkIJdgicc_AYGBjyBmQ==\n"

While the encryption error does go away using your key, I also don't get any audio. Using 00000000000000000000 as the key has the same effect.

@ojw28
Copy link
Contributor

ojw28 commented Apr 4, 2018

Thanks for your patience! I was able to get the content to play successfully. The correct key to use is sqvlkIJdgicc_AYGBjyBmQ (i.e. base64url encoding, as per spec).

I think the problem is in ClearKeyUtil.adjustResponseData, which re-writes the response to accommodate the fact that the underlying CDM incorrectly expected base64 rather than base64url prior to O-MR1. It converts _ into /, and also escapes / as \/ as per the JSON spec. It seems the underlying CDM does not expect or handle the escaping. If the escaping is removed then the content is able to play successfully.

Do you agree with the above diagnosis? If so I can push a fix. Thanks!

@adamhewitt627
Copy link
Author

My sense was that there was an issue in that escaping, but I wasn't able to debug/bypass it myself. I hadn't heard of that requirement in JSON, and searching online suggests it's optional. PowerShell, for one, doesn't include it:

@{"test"="value/text"} | ConvertTo-Json -Compress  # {"test":"value/text"}

@ojw28
Copy link
Contributor

ojw28 commented Apr 4, 2018

Heh, yeah, it appears the only non-optional escaping is of \ or ". adjustResponseData using JSONObject, which does escape /. Which is fine except that the underlying CDM doesn't handle it.

@ojw28 ojw28 added bug and removed question labels Apr 4, 2018
ojw28 added a commit that referenced this issue Apr 8, 2018
Issue: #4075

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=191872512
@ojw28 ojw28 closed this as completed Apr 8, 2018
@ojw28
Copy link
Contributor

ojw28 commented Apr 8, 2018

Should be fixed in dev-v2.

@google google locked and limited conversation to collaborators Aug 10, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants