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 fileC:\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
- With Keytool
- Without Keytool
No comments:
Post a comment