Showing posts with label RSA. Show all posts
Showing posts with label RSA. Show all posts

Thursday, August 27, 2015

Encryption/Decryption in Android - Asymmetric

As previously explained about the Asymmetric encryption in the post here, lets look into implementing Asymmetric Encryption in Android.

Among the various asymmetric algorithms present, the most widely used algorithm is the RSA Algorithm.
Since this is asymmetric, we need to generate a public/private key pair and remember that public key is used for encryption, however private key is used for decryption.So whoever is  having "Public Key", can encrypt the message, but it can only be decrypted by the person who is having the "Private Key".

We need  following in order to perform encryption/decryption:-

a. KeyPair (java.security), which contains the Public/Private key pair
b.  KeyPairGenerator (java.security), to generate the KeyPair
c. Algorithm type:- to be used by KeyGenerator to generate SecretKey(RSA)
d. Key_Length :- The size of the key in bits


Generating a Public/Private KeyPair


KeyPair generateRSAKey() {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048) ;//key length as 2048 bit
return keyPairGenerator.generateKeyPair()
}

so Public key can be obtained by keyPair.getPublic();
and Private key by keyPair.getPrivate();
Again it is recommended to save the keys in encoded byte[] form using
keyPair.getPublic().getEncoded() -------------------Public Key
keyPair.getPrivate().getEncoded()-------------------Private Key


Regenerating the Keys from encoded byte[]


PublicKey decodePublicKey(byte[] encodedKey) {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey) ;
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
return keyFactory.generatePublic(keySpec);
}

PublicKey decodePrivateKey(byte[] encodedKey) {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey) ;
KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
return keyFactory.generatePrivate(keySpec);
}

Encrypting Message using RSA Public Key


byte[] performRSAEncryption(PublicKey publicKey , byte[] message) {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE , publicKey);
return cipher.doFinal(message);


Decrypting Message using RSA Private Key


byte[] performRSADecryption(PrivateKey privateKey , byte[] message) {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE , publicKey);
return cipher.doFinal(message);
}

Encryption/Decryption in Android - Symmetric

We all have at some point in our life, have used encryption to prevent the misuse/illegal access of some confidential data.
Encryption is basically the process of encoding the data in such a way that only some authorized parties can decode it and read/process it.

There are two basic techniques of encrypting information:-
  • Symmetric Encryption

  • Asymmetric Encryption


What is Symmetric encryption?

Symmetric encryption is the oldest technique used for encrypting data, where a "SecretKey" is used to modify the original data in such a way that it can be recreated using the same SecretKey.
 The SecretKey could be any random set of characters, or numbers.

What is asymmetric encryption?

The problem with "Symmetric encryption" is that, the SecretKey needs to be kept in a safe place, or else if it is leaked, anyone can easily decrypt the information that you were trying to hide.
Suppose you wanted to encrypt a piece of information like your bank details using a SecretKey and you have to transfer this information to your family. Then while exchanging these information(encrypted message + SecretKey) over internet, you need to make sure that they dont fall into the hands of wrong people, or else they can easily get the actual piece of information you were trying to hide.So how do we prevent such cases?
Asymmetric encryption is the answer to such questions.
In Asymmetric encryption,  a pair of keys is used(public/private).
The public key is used for just encrypting the data and the private key is used for decrypting the data.So whoever has the public key can encrypt any piece of information using it, but only the person who has the private key, can decrypt the message.


 In this post we will deep dive into performing symmetric encryption in Android.


We need  following in order to perform encryption/decryption:-
a. SecretKey (javax.crypto), which is needed to perform both encryption and decryption
b.  KeyGenerator (javax.crypto), to generate the SecretKey
c. Algorithm type:- to be used by KeyGenerator to generate SecretKey(such as AES/DES)
d. Key_Length :- The size of the key in bits



Generate a SecretKey


SecretKey generateSecretKey() {
 SecureRandom secureRandom = new SecureRandom();
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256 , secureRandom);//use key size as 256

//generate the secretkey from the keygenerator
return  keyGenerator.generateKey();
}

The above function returns the SecretKey of 256 bit length, using AES algorithm.
Once the SecretKey is generated, save it to some secure storage.
However, in practice, the secretkey is not directly saved, rather its byte[] encoded form is saved.The byte[] encoded secret key by using the below method :-

byte[] generateSecretKey() {
 SecureRandom secureRandom = new SecureRandom();
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256 , secureRandom);//use key size as 256

//generate the secretkey from the keygenerator
SecretKey secretKey =  keyGenerator.generateKey();
return secretKey.getEncoded();
}

So this way, save the encoded secret key to a file and we will see now how to encrypt data using this generated SecretKey.But before that, we need to regenerate the SecretKey from its byte[] encoded form.This can be done by creating a SecretKeySpec object and using the same algorithm type, which was used during key generation.Following code illustrates this :-

byte[] encodedSecretKey = generateSecretKey();
SecretKey secretKey = new SecretKeySpec(encodedSecretKey , "AES");


Encrypting Data using SecretKey

Encryption/Decryption is perfomed using Cipher(javax.crypto).

byte[] encryptData(SecretKey secretKey ,  byte[] originalData) {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE , secretKey);
return cipher.doFinal();
}


Decrypting Data using SecretKey


byte[] decryptData(SecretKey secretKey ,  byte[] modifedData) {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE , secretKey);
return cipher.doFinal();
}



Summary


Encrypting data :-

byte[] secretKey = generateKey();
byte[] encryptedMessage = encryptData(secretKey , "secret message".getBytes())


Decrypting data:-

byte[] secretKey = getSavedEncodedSecretKey();
byte[] decryptedMessage = decryptData(secretKey , encryptedMessage);