UNPKG

4.19 kBMarkdownView Raw
1# Support for encrypted resources
2
3## Obfuscated fonts
4
5Both IDPF and Adobe font de-obfuscation schemes are supported.
6
7## LCP DRM
8
9### Demonstration (LCP test/basic profile, not suitable for production/1.0 profile)
10
11Let's consider the SHA256 hash of the user passphrase (or more precisely, the SHA256 digest / hexadecimal representation of the binary buffer / byte array), and its subsequent base64 encoding. For example, user passphrase `dan` becomes `ec4f2dbb3b140095550c9afbbb69b5d6fd9e814b9da82fad0b34e9fcbe56f1cb` (SHA256), which becomes `ZWM0ZjJkYmIzYjE0MDA5NTU1MGM5YWZiYmI2OWI1ZDZmZDllODE0YjlkYTgyZmFkMGIzNGU5ZmNiZTU2ZjFjYg==` (base64).
12
13Now, let's consider the special URL syntax `http://domain.com/pub/*-{LCP_PASS}-*{PUB_ID}/manifest.json`, which references the "webpub manifest" of a particular publication identified by `{PUB_ID}`, and which passes the LCP base64-encoded passphrase into the request, denoted by the delimiters `*-` and `-*` around `{LCP_PASS}`.
14
15Once the above URL request is made, the server stores the LCP passphrase and utilises it for any subsequent requests to resources (e.g. assets such as CSS, HTML, etc.) that belong to the publication identified by `{PUB_ID}`.
16
17Note that this special URL syntax is implemented to enable LCP testing directly from vanilla web browsers. In a real-world application, the underlying programmatic API should be used instead.
18
19Let's look at a concrete example. First, let's reset the LCP passphrase using an incorrect value:
20
21https://readium2.herokuapp.com/pub/*-YmQzZGFlNWZiOTFmODhhNGYwOTc4MjIyZGZkNThmNTlhMTI0MjU3Y2IwODE0ODYzODdjYmFlOWRmMTFmYjg3OQ%3D%3D-*L2FwcC9taXNjL2VwdWJzL3dhc3RlbGFuZC1vdGYtb2JmX0xDUF9kYW4uZXB1Yg%3D%3D/manifest.json/show/all
22
23Let's load the manifest without any LCP passphrase:
24
25https://readium2.herokuapp.com/pub/L2FwcC9taXNjL2VwdWJzL3dhc3RlbGFuZC1vdGYtb2JmX0xDUF9kYW4uZXB1Yg%3D%3D/manifest.json/show/all
26
27Notice that we did not provide the LCP passphrase in the URL, yet the publication's cover image is displayed correctly. That is because cover images are not encrypted in LCP-protected publications. The same principle applies to the navigation document:
28
29https://readium2.herokuapp.com/pub/L2FwcC9taXNjL2VwdWJzL3dhc3RlbGFuZC1vdGYtb2JmX0xDUF9kYW4uZXB1Yg%3D%3D/EPUB/wasteland-nav.xhtml?show=1
30
31Now let's load an encrypted page (it should fail):
32
33https://readium2.herokuapp.com/pub/L2FwcC9taXNjL2VwdWJzL3dhc3RlbGFuZC1vdGYtb2JmX0xDUF9kYW4uZXB1Yg%3D%3D/EPUB/wasteland-content.xhtml?show=1
34
35Now let's set the correct passphrase ("dan"):
36
37https://readium2.herokuapp.com/pub/*-ZWM0ZjJkYmIzYjE0MDA5NTU1MGM5YWZiYmI2OWI1ZDZmZDllODE0YjlkYTgyZmFkMGIzNGU5ZmNiZTU2ZjFjYg%3D%3D-*L2FwcC9taXNjL2VwdWJzL3dhc3RlbGFuZC1vdGYtb2JmX0xDUF9kYW4uZXB1Yg%3D%3D/manifest.json/show/all
38
39...and let's load the encrypted page once again (it should succeed):
40
41https://readium2.herokuapp.com/pub/L2FwcC9taXNjL2VwdWJzL3dhc3RlbGFuZC1vdGYtb2JmX0xDUF9kYW4uZXB1Yg%3D%3D/EPUB/wasteland-content.xhtml?show=1
42
43Note that in this example fonts are obfuscated (IDPF algorithm), therefore they are not encrypted via LCP. Also note that "streaming" of encrypted audio / video content is supported too, but test files are too large to demonstrate here (strictly-speaking, this is not "streaming", but rather: support for HTTP partial byte ranges, random access into the AES-256-CBC resource).
44
45### Implementation status (TypeScript / JavaScript)
46
47Note that TypeScript / JavaScript implementation is just for demonstration purposes, it only supports the LCP profile test/basic (not production/1.0), and it only handles decryption (no license signature checking, no expiration date/time verification, no Certificate Revocation List processing, no support for LSD License Status Document, etc.)
48
49Currently, the Javascript decryption code utilizes the NodeJS native crypto implementation (which is based on OpenSSL). Performance is acceptable, but of course the private decryption key is not protected (it can easily be debugged / reverse-engineered). This architecture is therefore only suitable for the LCP basic/test profile.
50
51Support for LCP 1.0/production profile relies upon a native C++ module, which replaces the Javascript implementation.