droidcon london 2014 - running your own software licensing system
DESCRIPTION
This talks takes you through the steps you should think about when running a software licensing system and provides some code examples of the cryptographic methods you may want to use to create and read secure license informationTRANSCRIPT
![Page 1: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/1.jpg)
Funky Android Ltd.http://www.funkyandroid.com/
Running your own software licensing system
![Page 2: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/2.jpg)
www.funkyandroid.com
Why?
• Give your users cross-store purchases
• Provision purchases from other channels
• Isolate yourself from any single sales channel
![Page 3: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/3.jpg)
www.funkyandroid.com
Things to remember
• Perfect security isn’t currently feasible
• The aim is to make the cost of cracking greater than the value gained from the crack
• It’s up to you how much you want any cracker to have to “pay” to crack your app
![Page 5: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/5.jpg)
www.funkyandroid.com
What are we doing?
Securing information between two places
![Page 6: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/6.jpg)
www.funkyandroid.com
What are we doing?
Securing information between two places
Validate Contents?
![Page 7: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/7.jpg)
www.funkyandroid.com
Validate Contents
• Make sure this is a current, valid license.
• Replay attacks; Old data getting a second, third, fourth, ….. outing.
• Add a timestamp to both request and response and reject “old” responses.
• Add a random one-time ID in the request which the server adds to the response.
![Page 8: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/8.jpg)
www.funkyandroid.com
What are we doing?
Securing information between two places
Verify Sender?Validate Contents?
![Page 9: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/9.jpg)
www.funkyandroid.com
Verify Sender
• SSL - one option, but has to be done securely (e.g. certificate pinning)
• Asymmetric Crypto - Public/Private key
• If the keys don’t match then the data won’t decrypt correctly.
![Page 14: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/14.jpg)
www.funkyandroid.com
License Source
• Could be a server.
• Could be your desktop.
• Could even be an Android device.
• It’s all about capacity!
![Page 15: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/15.jpg)
www.funkyandroid.com
A key pair
• Asymmetric Cryptography.
• The private key is…. well…. private.
• The public key is in your application.
• Use the private key to encrypt the license, and the public key can decrypt it.
![Page 16: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/16.jpg)
www.funkyandroid.com
A standard format
• Create one yourself
• You can use multiple forms of cryptography
• You can checksum blocks
![Page 17: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/17.jpg)
www.funkyandroid.com
Hidden decryption
• In-App license verification code shouldn’t be easy to find.
• The more effort you put into hiding it, the harder it is to crack
• Think about using time limited licenses that need refreshing.
![Page 18: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/18.jpg)
www.funkyandroid.com
Hidden decryption
Evading Pirates and Stopping Vampires
http://www.youtube.com/watch?v=TnSNCXR9fbY
![Page 19: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/19.jpg)
www.funkyandroid.com
Long licenses• Asymmetric Cryptography tends to be
relatively slow, so may not make sense for lots of data
• Asymmetrically Encrypt a “session key” - A key for that license
• Asymmetrically Encrypt a checksum of the data encrypted using the session data
• Use AES encryption for speed.
![Page 21: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/21.jpg)
www.funkyandroid.com
Key Generation
import java.security.*;
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048, new SecureRandom());
KeyPair keys = kpg.generateKeyPair();
![Page 22: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/22.jpg)
www.funkyandroid.com
Key -> byte[ ]
PrivateKey privateKey = keys.getPrivate();
byte[] privBytes = privateKey.getEncoded();
PublicKey publicKey = keys.getPublic();
byte[] pubBytes = publicKey.getEncoded();
![Page 23: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/23.jpg)
www.funkyandroid.com
byte[ ] -> Private Key
PKCS8EncodedKeySpec skeySpec = new PKCS8EncodedKeySpec(privBytes);
KeyFactory keyFactory = KeyFactory.getInstance(“RSA”);
PrivateKey privateKey = keyFactory.generatePrivate(skeySpec);
![Page 24: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/24.jpg)
www.funkyandroid.com
Encrypt License
Cipher cipher = Cipher.getInstance(“RSA”);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] encryptedLicense = cipher.doFinal(licenseBytes);
![Page 25: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/25.jpg)
www.funkyandroid.com
byte[ ] -> Public Key
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pubBytes);
KeyFactory factory = KeyFactory.getInstance(“RSA");
PublicKey publicKey = factory.generatePublic(keySpec);
![Page 26: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/26.jpg)
www.funkyandroid.com
Decrypt License
Cipher cipher = Cipher.getInstance(“RSA”);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] licenseBytes = cipher.doFinal(encryptedLicense);
![Page 27: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/27.jpg)
www.funkyandroid.com
“Session Key”import java.security.*;
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey key = keyGen.generateKey();
* 128 bit key because that’s Oracle’s default maximum AES key length.
![Page 28: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/28.jpg)
www.funkyandroid.com
key -> byte [ ]
byte[] sessionKeyBytes = key.getEncoded()
![Page 29: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/29.jpg)
www.funkyandroid.com
byte[ ] -> key
SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyBytes, "AES");
![Page 30: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/30.jpg)
www.funkyandroid.com
AES/CBC/PKCS5Padding
• AES - Can encrypt blocks of data (1 block is 128 bits - 16 bytes)
• CBC - Cipher Block Chaining - One block relies on the previous block
• PKCS5Padding - Ensure blocks of data are the right size to be chained.
![Page 31: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/31.jpg)
www.funkyandroid.com
Encrypt Data
Cipher cipher = Cipher.getInstance(“AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encryptedData = cipher.doFinal(data);
byte[] initialisationVector = cipher.getIV();
![Page 32: Droidcon London 2014 - Running Your Own Software Licensing System](https://reader034.vdocuments.us/reader034/viewer/2022052622/5594af431a28ab8e4b8b462b/html5/thumbnails/32.jpg)
www.funkyandroid.com
Decrypt DataCipher cipher = Cipher.getInstance(“AES/CBC/PKCS5Padding");
cipher.init( Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec( initialisationVector ) );
byte[] data = cipher.doFinal(encryptedData);