3

I am wondering how software with premium modes, such as Spotify, can operate offline. If a user is not connected to the internet, then they cannot authenticate via a remote server, which has e.g. a database of users and when their accounts expire. The only explanation I can think of is that the software locally stores the account's expiration date and encrypts this file when the user is online. But for this to work offline, the decryption key and method must also be stored locally rather than being retrieved from a server. In this case, it seems that authentication is only secured through obfuscation of the encryption method and key in the machine code.

Is the above the typical way that offline authentication is handled, or is there a better way of achieving this?

1

If it worked that way, then yes you are correct. However that isn't what is needed here.

The client need only verify that a piece of data was made by the server to within some degree of certainty. The contents of the certificate itself can be public knowledge: bearer has access to these resources. The timeout itself is the expiration of the certificate.

This is a solved problem. The most famous implementation you are already using to browse this web-site. The web server sent a certificate to your browser to prove its identify, and justify why it should be trusted to serve data on behalf of a domain name.

The server generates a certificate and asks a signing authority to ratify it. That signing authority uses public key cryptography to generate a signature, that is added to the servers certificate to be sent to the clients of the server.

The signing authority themselves have issued a certificate bearing the public key needed to prove their signature (but cannot be used to generate their signature) and asked another signing authority to sign this certificate.

This is done again and again till we reach a Root CA (usually only two or three hops). The Root CA has a certificate that has already been installed on your machine, and has been given explicit trust by the web browser.

It is difficult to forge a certificate, and computers refuse to trust certificates that expire to far into the future. So a server can reasonably explain the rights in a file, and certify that file with a certificate, that has been validated up a chain of trust.

The client can then verify the file and the certificate at a later point in time at its leisure.

The last piece of the puzzle is that those root ca certificates need to be trustable. This is often achieved by a trusted computing module which either stores the root ca certificate itself, or signs the root ca certificate. Either-way it is very difficult for anyone nefarious or not to force-ably add a certificate to that module, or to forge the signature of the module.

1

You deploy a file with the user account information signed by the server. The public key used to verify the signature can be safely deployed along side. This allows the application to verify the signature, ensuring that the user account information was validated by the server.


Of course, the user could move the application along with all the necessary files and have it work in a different device, is that a concern?

You may want to include as account information some fingerprint of the platform (e.g. volume serial number). That way the application can check if it matches the current platform where it is running.


Of course, the user could trick the software by using a debugger or similar. Is that a concern?

There are solutions to detect if the application is running with a debugger attached (often used by expensive proprietary software).

I am also aware of Joanna Rutkowska work on detecting virtualization software (a.k.a the blue pill). I haven't seen it in the wild. Yet, you might be interested in how that works.


At the end, it all ends in a conditional jump somewhere in the code. All a crack needs to do is flip the conditional (deter with obfuscation), and any invalid credential will grant access. Is that a concern?

Something you can do to mitigate this is to sign the executable. Ern... Yes, the user can still run applications with an invalid signature... hmm...

You can store (premium) components of the application under a cipher, with a custom key derived from a hash of the account information. Then the software would hash the account information, perform the key derivation algorithm, and use the key to decipher the application components.

By doing this, the only way to use the application components is to have the right key. Alright, this is not perfect security either. The cracker would deploy already deciphered components and bypass the routine described above.


Expiration date?

You can store the expiration date along with the account information. That way the user cannot change it without making the signature fail. And (assuming the application has not been modified to do so) the application would reject account information with an invalid signature.

However, the user is in control of the system time. The application needs to check on given events the system time to make sure it is moving forward. Which also means that the application needs to store the last seen system time, so that changing the clock while it is not running does not trick it.

Oh, where does it store the last seen system time? The user could just modify that. If it is under a cipher or with a signature, the key must be on the machine... so, hmm... poker face. Actually, that is probably enough to deter most people.


I do not know what Spotify does. The following is a solution I have come up with. Have the server:

  1. Create a file. Optional: make the initial contents of the file a seed value.
  2. Generate a fixed size value.
  3. Append it to the file.
  4. Sign the content of the file with a private key.
  5. Append the signature to the file.
  6. Repeat from step 2.

You are going to do this a few hundred or thousand iterations. You should have a file of a few megabytes. I will refer to this file as a Cryptographic Countdown™.

Deploy the cryptographic countdown and the public key used to generate it along side the application. Each few minutes (say, 10 minutes of play time) or uses (say, play a song), the application will go to the cryptographic countdown and replace the last valid entry with random values (to make it harder for forensic tools to recover the countdown).

If you are counting time, you might have the server use date-time values (with some random padding) for the step 2. For uses, it can be fully random.

When the application starts, it can verify the Cryptographic Countdown using the public key. The number of valid entries tell you how much is remaining in the trial. It is also possible to store the number of the last valid entry for quick access, then the application can go directly to verify that one.

To prevent this cryptographic countdown from being used by another user, you can derive the seed from the the account information.

Oh, to by pass this, you need to back it up upon installation. When it runs out, restore the cryptographic countdown from your back up (and set back the system time, if it is time based). The application would let you in again. This process can be automated. It would be inconvenient, which is a deterrent.


Please note it is possible (given enough time and resources) to bypass the measures I mention here, creating a cracked version. And you only need one person to make the cracked version and deploy it to everybody.

The only way to truly prevent piracy is to have a server under your control.

1

On iOS, the developer just stores the needed information in the keychain. You can’t modify it, you can delete it (but that is hard) but then you can’t authenticate it, and it won’t work on another device. It survives deleting and re-installing the app.

Checking if your app is running under a debugger is a slightly obscure OS call.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.