Monday, 4 November 2013

Asymmetric Key Encryption/Decryption using Keytool



Asymmetric Key Encryption/Decryption using Keytool.
This blog explains how to create keystores, certificates and trustore. It also explains how the handshaking is done between to parties who wan to communicate securely using asymmetric key Encryption/Decryption.


Below video explains secured message passing communication using asymmetric key system.





For asymmetric encryption/decryption both parties need to crate asymmetric keys which has both private and public key. Then the public key is exported from he keystore and given to the other party. The other party then imports the public key(certificate) into a truststore and used that truststore to encrypt the data.

Remember a public key(certificate) can be used to only encrypt data. The data can be only decypted by the private key.


Below commands generate Keystores, Certificate, Trustore for both parties. Both Parties, yes, because this is a bi-directional assymetric key that means both the parties have their set of key-pairs.

Lets first create key-pairs


C:\Users\hunaid.husain\keys>keytool -genkeypair -alias server -keyalg RSA -keysize 1024 -storetype jceks -validity
 365 -keypass password -keystore serverkeystore.jck -storepass password -dname "cn=localhost, ou=Verisign,
 o=MyComp Inc, l=Foster City, st=Calif

C:\Users\hunaid.husain\keys>keytool -genkeypair -alias client -keyalg RSA -keysize 1024 -storetype jceks -validity
 365 -keypass password -keystore clientkeystore.jck -storepass password -dname "cn=localhost, ou=Verisign
, o=MyComp Inc, l=Foster City, st=Calif


So now we have 2 key pairs


Now we can extract certificates(public key/Padlock) from the generated key pairs

C:\Users\hunaid.husain\keys>keytool -export -alias client -storetype jceks -keystore clientkeystore.jck -storepass
 password -file client.crt
Certificate stored in file 

C:\Users\hunaid.husain\keys>keytool -export -alias server -storetype jceks -keystore serverkeystore.jck -storepass
 password -file server.crt
Certificate stored in file 

We have now extracted the public key from their respective key pairs.



This certificates can then be added to other parties truststores. Trust stores are a bucket of Open Pad locks.

C:\Users\hunaid.husain\keys>keytool -importcert -alias server -file server.crt -keystore clienttruststore.jck
 -keypass password -storepass password
Owner: CN=localhost, OU=Verisign, O=MyComp Inc, L=Foster City, ST=California, C=US
Issuer: CN=localhost, OU=Verisign, O=MyComp Inc, L=Foster City, ST=California, C=US
Serial number: 31c71cb5
Valid from: Mon Feb 24 13:49:05 IST 2014 until: Tue Feb 24 13:49:05 IST 2015
Certificate fingerprints:
         MD5:  CE:9B:E2:3E:94:17:2F:C3:87:38:69:5A:CE:9E:3B:2B
         SHA1: FA:FE:2B:93:3B:41:BC:C4:81:FD:44:66:D0:DF:91:87:03:FE:7B:CD
         SHA256: CD:C8:61:85:E6:20:0F:EF:25:7A:11:4C:30:7C:B4:DA:82:C8:FB:21:D3:F5:17:95:8C:BB:01:02:6B:6C:E5:28
         Signature algorithm name: SHA256withRSA
         Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: CF DA 98 82 65 7A 6E 95   EA 99 B6 BD 19 25 1F 49  ....ezn......%.I
0010: E1 1F B6 B5                                        ....
]
]

Trust this certificate? [no]:  yes
Certificate was added to keystore

C:\Users\hunaid.husain\keys>eytool -importcert -alias client -file client.crt -keystore servertruststore.jck -keypass
 password -storepass password
'eytool' is not recognized as an internal or external command,
operable program or batch file.

C:\Users\hunaid.husain\keys>keytool -importcert -alias client -file client.crt -keystore servertruststore.jck -keypass
 password -storepass password
Owner: CN=localhost, OU=Verisign, O=MyComp Inc, L=Foster City, ST=California, C=US
Issuer: CN=localhost, OU=Verisign, O=MyComp Inc, L=Foster City, ST=California, C=US
Serial number: 459f8ae8
Valid from: Mon Feb 24 13:50:20 IST 2014 until: Tue Feb 24 13:50:20 IST 2015
Certificate fingerprints:
         MD5:  E6:C7:BF:CB:8A:65:BB:8D:29:67:AB:D0:B6:DA:E9:6C
         SHA1: C2:26:FF:53:16:13:46:1A:73:8E:87:CF:85:B6:03:93:48:95:9A:70
         SHA256: C5:63:93:C4:2E:61:C7:B0:82:07:DF:7E:EB:EB:A7:F9:B3:FF:C4:0B:9D:FB:E5:59:D8:1D:48:B4:0E:96:28:08
         Signature algorithm name: SHA256withRSA
         Version: 3

Extensions:

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 19 40 04 5A 3A 1A FD 2C   5C 63 19 A5 43 5E D0 6B  .@.Z:..,\c..C^.k
0010: 27 F9 C2 71                                        '..q
]
]

Trust this certificate? [no]:  yes
Certificate was added to keystore

C:\Users\hunaid.husain\keys>





So now we have trust stores which have public key of other party.



Lets write the code to use these keystores and trusstores.

For a maven project you will need the apache-common-codec jar as a dependency or else just download the jar and paste it in the folder which is in the classpath.

Maven dependency:
<dependency>
 <groupId>commons-codec</groupId>
 <artifactId>commons-codec</artifactId>
 <version>1.8</version>
</dependency>

Main Class
package asymmetrickey_bi;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

public class AsymmetricKey_bi {
 public static void main(String[] args) throws KeyStoreException, NoSuchAlgorithmException, CertificateException,
 IOException, UnrecoverableKeyException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException,
 BadPaddingException {

  
  KeyStoreUtil keyStoreUtil = new KeyStoreUtil();

  //Client encrypts data by using server public key which is stored in clients trusstore.
  String clientData="ABC";
  String clientDataEncrypted =keyStoreUtil.encryptclient(clientData.getBytes(), "server");
  
  //Server decrypts data using its own private key
  System.out.println(keyStoreUtil.decryptserver(clientDataEncrypted, "server"));
  
  
  //Server encrypts data by using clients public key which is stored in servers trusstore.
  String serverData="Hello";
  String serverDataEncrypted =keyStoreUtil.encryptserver(serverData.getBytes(), "client");
  
  //Client decrypts data using its own private key
  System.out.println(keyStoreUtil.decryptclientr(serverDataEncrypted, "client"));
  
 }
}




package asymmetrickey_bi;

import java.io.FileInputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.apache.commons.codec.binary.Base64;

public class KeyStoreUtil {

 private static KeyStore clientTrustStore;
 private static KeyStore clientKeyStore;

 private static KeyStore serverTrustStore;
 private static KeyStore serverKeyStore;

 private static String clientKeyStorePass;
 private static String clientStorePassword;

 private static String serverKeyStorePass;
 private static String serverStorePassword;

 private static Cipher dCipher;
 private static Cipher eCipher;

 public KeyStoreUtil() throws KeyStoreException, NoSuchAlgorithmException,
   CertificateException, IOException {

  loadClientTrustStore();
  loadClientKeyStore();
  loadServerTrustStore();
  loadServerKeyStore();
  
 }

 private void loadClientTrustStore() throws KeyStoreException,
   NoSuchAlgorithmException, CertificateException, IOException {
  clientTrustStore = KeyStore.getInstance("JCEKS");
  clientStorePassword = "password";
  // String filePath = wcCryptoConfig.getTrustStoreFileLocation() +
  // File.separator + wcCryptoConfig.getTrustStoreFile();
  FileInputStream stream = new FileInputStream("bi/clienttruststore.jck");
  clientTrustStore.load(stream, clientStorePassword.toCharArray());
 }

 private void loadClientKeyStore() throws KeyStoreException,
   NoSuchAlgorithmException, CertificateException, IOException {
  clientKeyStore = KeyStore.getInstance("JCEKS");
  clientKeyStorePass = "password";
  // String filePath = wcCryptoConfig.getKeyStoreFileLocation() +
  // File.separator + wcCryptoConfig.getKeyStoreFile();
  FileInputStream stream = new FileInputStream("bi/clientkeystore.jck");
  clientKeyStore.load(stream, clientKeyStorePass.toCharArray());

 }

 private void loadServerTrustStore() throws KeyStoreException,
   NoSuchAlgorithmException, CertificateException, IOException {
  serverTrustStore = KeyStore.getInstance("JCEKS");
  serverStorePassword = "password";
  // String filePath = wcCryptoConfig.getTrustStoreFileLocation() +
  // File.separator + wcCryptoConfig.getTrustStoreFile();
  FileInputStream stream = new FileInputStream("bi/servertruststore.jck");
  serverTrustStore.load(stream, serverStorePassword.toCharArray());
 }

 private void loadServerKeyStore() throws KeyStoreException,
   NoSuchAlgorithmException, CertificateException, IOException {
  serverKeyStore = KeyStore.getInstance("JCEKS");
  serverKeyStorePass = "password";
  // String filePath = wcCryptoConfig.getKeyStoreFileLocation() +
  // File.separator + wcCryptoConfig.getKeyStoreFile();
  FileInputStream stream = new FileInputStream("bi/serverkeystore.jck");
  serverKeyStore.load(stream, serverKeyStorePass.toCharArray());

 }

 public String decryptserver(String encryptedString, String keyAlias)
   throws KeyStoreException, UnrecoverableKeyException,
   InvalidKeyException, NoSuchAlgorithmException,
   NoSuchPaddingException, IllegalBlockSizeException,
   BadPaddingException {
  Key key = serverKeyStore.getKey(keyAlias,
    serverKeyStorePass.toCharArray());
  dCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
  dCipher.init(Cipher.DECRYPT_MODE, key);
  return new String(dCipher.doFinal(Base64.decodeBase64(encryptedString
    .getBytes())));
 }

 public String encryptclient(byte[] inputString, String keyAlias)
   throws KeyStoreException, UnrecoverableKeyException,
   InvalidKeyException, NoSuchAlgorithmException,
   NoSuchPaddingException, IllegalBlockSizeException,
   BadPaddingException {
  Key key = null;
  // Key key = scsTrustStore.getKey(keyAlias, scsKeyStorePass);
  if (clientTrustStore.isCertificateEntry(keyAlias)) {
   Certificate cert = clientTrustStore.getCertificate(keyAlias);
   key = cert.getPublicKey();
  } else {
   key = clientTrustStore.getKey(keyAlias,
     clientStorePassword.toCharArray());
  }

  eCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
  eCipher.init(Cipher.ENCRYPT_MODE, key);
  return Base64.encodeBase64String(eCipher.doFinal(inputString));
 }
 
 
 public String decryptclientr(String encryptedString, String keyAlias)
   throws KeyStoreException, UnrecoverableKeyException,
   InvalidKeyException, NoSuchAlgorithmException,
   NoSuchPaddingException, IllegalBlockSizeException,
   BadPaddingException {
  Key key = clientKeyStore.getKey(keyAlias,
    clientKeyStorePass.toCharArray());
  dCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
  dCipher.init(Cipher.DECRYPT_MODE, key);
  return new String(dCipher.doFinal(Base64.decodeBase64(encryptedString
    .getBytes())));
 }

 public String encryptserver(byte[] inputString, String keyAlias)
   throws KeyStoreException, UnrecoverableKeyException,
   InvalidKeyException, NoSuchAlgorithmException,
   NoSuchPaddingException, IllegalBlockSizeException,
   BadPaddingException {
  Key key = null;
  // Key key = scsTrustStore.getKey(keyAlias, scsKeyStorePass);
  if (serverTrustStore.isCertificateEntry(keyAlias)) {
   Certificate cert = serverTrustStore.getCertificate(keyAlias);
   key = cert.getPublicKey();
  } else {
   key = serverTrustStore.getKey(keyAlias,
     serverStorePassword.toCharArray());
  }

  eCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
  eCipher.init(Cipher.ENCRYPT_MODE, key);
  return Base64.encodeBase64String(eCipher.doFinal(inputString));
 }
 



 

}





Java Examples

No comments:

Post a Comment

Share the post