This mega-post is intended to overview on how the ADEPT protocol works, as discovered by my own efforts and those of Grégory Soutadé and Florian Bach. It will be periodically updated to contain new information.
For the uninitiated, ADEPT is the protocol that Adobe’s flagship DRM product, Adobe Digital Editions (ADE), uses to communicate with both Eden2 (Adobe Digital Edition activation service) and with Adobe Content Server (ACS) instances run by book distributors.
On it’s most basic level, the ADEPT protocol consists of two main parts: Activation and Fulfilment.
In order to fulfill books, your device needs to be “activated”. There are several methods of going about this, but the simplest is activating anonymously.
Warning: Because anonymous activations are, well, anonymous, they cannot be used across multiple devices: if you lose the device, your purchases are gone forever.
The first step of activation involves signing into your account. This process sets up a bunch of keys and other things that we will use later.
The first thing you need to do is generate the keys you are going to use for your device. These include:
The Device Key, which is simply 16 random bytes
The License Key, which is a 1024-bit RSA keypair
The Authentication Key, which is a 1024-bit RSA keypair
Save these in a safe place, as you will need them later.
Constructing Sign-In Data
Now, you need to construct a buffer containing the sign in data, which looks like this:
DEVICE_KEY + len(USERNAME) + USERNAME + len(PASSWORD) + PASSWORD
The device key is the same one you generated earlier, while the username and password are empty. Thus, for an anonymous account, it should actually look something like this:
You then need to encrypt this whole buffer with the Authentication Certificate.
For simplicity, you can assume the Authentication Certificate will be:
Encrypting Private Keys
In order to securly send the Authentication and License keypairs to Adobe, we must encrypt their private keys.
Export the private key as PKCS#8
Encrypt the exported data with the Device Key using
Base64-encode the result
For the public keys, all you need to do is export them as plain PKCS#1 keys, and then Base64-encode them.
Sending the Sign-in Request
The sign in request is formatted like this, replacing the placeholders with the data we just generated:
<?xml version="1.0"?> <adept:signIn xmlns:adept="http://ns.adobe.com/adept" method="anonymous"> <adept:signInData>(Encrypted Sign-in Data)</adept:signInData> <adept:publicAuthKey>(Public Authentication Key)</adept:publicAuthKey> <adept:encryptedPrivateAuthKey>(Encrypted Private Authentication Key)</adept:encryptedPrivateAuthKey> <adept:publicLicenseKey>(Public License Key)</adept:publicLicenseKey> <adept:encryptedPrivateLicenseKey>(Encrypted Private License Key)</adept:encryptedPrivateLicenseKey> </adept:signIn>
Then, make a POST request to
https://adeactivate.adobe.com/adept/SignInDirect with a Content-Type of
application/vnd.adobe.adept+xml. If everything went as planned, the reponse should contain a license key, a license certificate, a user ID, a username, and a PKCS#12 archive. Save these things for later.
Note: If the (decrypted) license key returned by the server does not match the license key you sent, this means that there was already a license key associated with the account. Make sure to replace the key you generated by the one returned by the server. This should never happen with an anonymous account.
Now for the actual activation!
When activating a device, Adobe collects a whole bunch of information about it. Adobe actually recognizes two separate devices during this phase. The first is the device communicating the Activation Request. The second is the “target device” that is being activated. For most use-cases, these will be identical.
A unique fingerprint. (e.g.
An OS name (e.g.
A locale (e.g.
A type (e.g.
A target Hobbes version (e.g.
A client software version (e.g.
A product name (e.g.
Adobe Digitial Editions)
Constructing the request
For now, this is all the post contains. I’ll update it with the rest of the process at some further time.