Onleihe LCP license code verification

raw

verify-onleihe-code.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?php
/**
 * Verify that a Onleihe CODE is correct (able to decrypt the .epub file)
 */
$userPassphrase = 'FIXME';//Bitte geben Sie hier Ihren Onleihe CODE ein.
 
$lcplFile = 'example/81f292a0-5989-4d02-8749-398cc0b5057f.lcpl';
$lcpl = json_decode(file_get_contents($lcplFile));
$licenseId = $lcpl->id;
$encLicenseId = $lcpl->encryption->user_key->key_check;
 
if ($lcpl->encryption->user_key->algorithm != 'http://www.w3.org/2001/04/xmlenc#sha256') {
    echo "Unsupported user key hash algorithm\n";
    exit(1);
}
$userKey = hash('sha256', $userPassphrase);
 
if ($lcpl->encryption->content_key->algorithm != 'http://www.w3.org/2001/04/xmlenc#aes256-cbc') {
    echo "Unsupported content key encryption algorithm\n";
    exit(1);
}
 
 
/**
 * https://www.w3.org/TR/xmlenc-core1/#sec-AES
 *
 * [AES] is used in the Cipher Block Chaining (CBC) mode with a 128 bit
 * initialization vector (IV).
 * The resulting cipher text is prefixed by the IV.
 * If included in XML output, it is then base64 encoded.
 */
$encLicenseIdBytes = base64_decode($encLicenseId);
$encIv = substr($encLicenseIdBytes, 0, 128 / 8);
$encLicenseIdBytesData = substr($encLicenseIdBytes, 128 / 8);
 
$decrypted = openssl_decrypt(
    $encLicenseIdBytesData, 'AES-256-CBC',
    hex2bin($userKey),
    OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING,
    $encIv
);
if ($decrypted === false) {
    echo "Decryption failed\n";
    exit(1);
}
$padLength = unpack('C', substr($decrypted, -1))[1];
 
$decrypted = substr($decrypted, 0, -$padLength);
echo "License ID:   $licenseId\n";
echo "Decrypted ID: $decrypted\n";
?>
 
Christian Weiske Christian Weiske
owner

History