Android, JavaScript and Python compatible RSA Encryption.
It’s somewhat complicated to implement RSA Encryption so that data encrypted on either of these platforms can be easily decrypted on the other platforms and even more so for someone like me who had almost zero knowledge of programming using encryption algorithms.
While developing an initial pairing mechanism for Ambient Dynamix, I had already settled on the forge library for javascript because of the availability of symmetric, asymmetric encryption algorithms, password based key derivation functions and hashing algorithms. It also had a fair performance according to this evaluation.
The library also supported decryption using a private key using RSAES-OAEP/SHA-256/MGF1-SHA-256 which is compatible with Java’s RSA/ECB/OAEPWithSHA-256AndMGF1Padding algorithm. Big thumbs up!
The idea was to pick up a public key generated on android and use it to encrypt content in javascript. Android should then be able to successfully decrypt the data using its private key. I also needed to support the whole process in reverse i.e. android encrypting the content using a public key generated on javascript and then javascript decrypting it.
Encrypting content in javascript and decrypting in java.
Generating RSA KeyPair on Android:
To retrieve the public key from the keypair object use the getPublic(); method of the KeyPair class.
Once the keypair is generated, I convert the public key into a String which could be then be used by javascript for encrypting content. For my purpose, the public key is sent back as a response to a simple http request made by javascript.
To convert public key to a String :
Importing a public key in javascript and encryption :
The important thing to note here is that I am using SHA-256 in the mask generation function (the mgf1 parameter). I could have very well used SHA-1 and everything would work. However, when implementing the same algorithm on python, it becomes an issue because the python library uses the same hashing mechanism for the message digest and the mask digest but only lets us specify the message digest algorithm.
So, now, the base64 encoded encrypted string can safely be sent over a non - encrypted connection to java.
Decrypting in java :
I’ll use the private key generated in the first step to decrypt the content. To get the private key use the getPrivate(); method of the KeyPair class.
Encrypting content in java and decrypting in javascript.
Generating RSA KeyPair in javascript:
To convert public key to a String :
The public key pem can easily be transferred over the network.
Importing a public key in java and encryption:
Decrypting cipher text in javascript :
The privateKey used in this step can be retrieved from the keypair generated in the first step.
Use the keypair.privateKey; property.
All the above mentioned code is compatible with the following python code and any of the platforms can be switched. For instance, content encrypted on python can be easily decrypted on java.
For encryption and decryption in python, we’ll use the PyCrypto library.
Generating rsa keypair :
Encrypting content :
When creating the cipher, we use SHA256 as the hash algo. Python automatically uses the same algorithm for the message digest and for the mask function digest as mentioned before.
Decrypting content :
The importKey method is used to import private keys from pem strings. I’ll use the private_key generated in the first step.