AES Encryption Decryption
This post describes how to implement AES encryption decryption in webMethods. This post is divided into different portions.
- Java Cryptography Extension (JCE)
- Information about AES Encryption Decryption
- Java service inputs
- Java Service for KeyGeneration
- Java Service to Decrypt
- Java Service to Encrypt
- Shared Code
Java Cryptography Extension (JCE)
Wikipedia define JCE as The Java Cryptography Extension (JCE) is an officially released Standard Extension to the Java Platform and part of Java Cryptography Architecture. JCE provides a framework and implementation for encryption, key generation and key agreement, and Message Authentication Code (MAC) algorithms. JCE supplements the Java platform, which already includes interfaces and implementations of message digests and digital signatures. Installation is specific to the version of the Java Platform being used, with downloads available for Java 6, Java 7, and Java 8
For AES encryption decryption java code provided in this post to work and to generate keys of 128bit and greater you need to install Unlimited Strength Jurisdiction Policy Files in your environment. Policy files can be downloaded from Oracle website at link
Information about AES Encryption Decryption
Wikipedia defines AES as –
The Advanced Encryption Standard (AES), also known as Rijndael (its original name), is a specification for the encryption of electronic data established by the U.S. National Institute of Standards and Technology (NIST) in 2001.
AES is based on the Rijndael cipher developed by two Belgian cryptographers, Joan Daemen and Vincent Rijmen, who submitted a proposal to NIST during the AES selection process. Rijndael is a family of ciphers with different key and block sizes. More can be read about AES at wikipedia link
AES encryption decryption Java Services provided in this post provides support to generate keys for different block sizes and different message digest algorithm. however we tested entire code only with cipher “AES/CBC/PKCS5Padding”, encryption algorithm “AES” and key block size of 128 and 256 bits. Please test and change code as it suits you.
Java Service Inputs
there are bunch of inputs which are passed to services. for ease and avoid redundancy, i am explaining common one here.
- cipher – a cipher (or cypher) is an algorithm for performing encryption or decryption. Depending on what Cipher Algorithm and mode you want to use value can be different. for our testing purpose we used AES algorithm, CBC mode and PKCS5Padding. value looked like “AES/CBC/PKCS5Padding” Set of values supported by Java 8 can be found here
- keyAlgorithm – Key algorithm refers to the encryption algorithm for generating keys. In current code implementation it doesn’t have any impact other than being a place holder for algorithm. SecretKeySpec class constructor does not check if the given bytes indeed specify a secret key of the specified algorithm. Read more here
- messageDigest – MessageDigest class provides applications the functionality of a message digest algorithm, such as SHA-1 or SHA-256. Message digests are secure one-way hash functions that take arbitrary-sized data and output a fixed-length hash value. Set of values supported by Java 8 can be found here
- encoding – Encoding refers to Character Encoding. default is set to “UTF-8”
- password – Password is choice of alphanumeric string which can be used to generateKey. this can be of any length and it is a mandatory field.
- keySize – key size or key length is the number of bits in a key used by a cryptographic algorithm. Input accepts number of bytes and default is 32bytes (256bits).
Java Service for KeyGeneration
This service generate encryption key and initialization vector in base64 encoded format. Initialization Vector is set to generate only 16bytes (128bits) value. Screenshot below shows inputs and output for service.
JavaCode for generateKey
Below is java code which needs to be put in java service for generation of key. you can create java service name of your own choice and copy paste below code to the body. Code refers to a common class AES which is provided in section of shared code and needed to copied to shared code area of java service.
// pipeline IDataCursor pipelineCursor = pipeline.getCursor(); String messageDigest = IDataUtil.getString( pipelineCursor, "messageDigest" ); String keyAlgorithm = IDataUtil.getString( pipelineCursor, "keyAlgorithm" ); String encoding = IDataUtil.getString( pipelineCursor, "encoding" ); final String password = IDataUtil.getString( pipelineCursor, "password" ); Integer keySize = Integer.parseInt(IDataUtil.getString( pipelineCursor, "keySize" )); if(messageDigest == null || messageDigest.equals("")) messageDigest = "SHA-256"; if(keyAlgorithm == null || keyAlgorithm.equals("")) keyAlgorithm = "AES"; if(encoding == null || encoding.equals("")) encoding = "UTF-8"; if(keySize == null || keySize.equals("")){ keySize = 32; System.out.println("inside integer check"); } //Call key generation function AES.setKey(password, messageDigest, keyAlgorithm, encoding, keySize); IDataUtil.put( pipelineCursor, "generatedKey", AES.getGeneratedKey()); IDataUtil.put( pipelineCursor, "generatedKeyBase64", Base64.getEncoder().encodeToString(AES.getGeneratedKey()) ); IDataUtil.put( pipelineCursor, "ivKey", AES.getIV()); IDataUtil.put( pipelineCursor, "ivKeyBase64", Base64.getEncoder().encodeToString(AES.getIV()) ); //Remove input pipeline variable from pipeline IDataUtil.remove(pipelineCursor, "messageDigest"); IDataUtil.remove(pipelineCursor, "keyAlgorithm"); IDataUtil.remove(pipelineCursor, "encoding"); IDataUtil.remove(pipelineCursor, "password"); IDataUtil.remove(pipelineCursor, "keySize"); pipelineCursor.destroy();
Java Service to Decrypt
This service decrypt encrypted text. it accepts encrypted string, encryption key in base64 format and initialization vector in base64 format. Screenshot below shows inputs and output for service.
JavaCode for decrypt Service
Below is java code which needs to be put in java service for decryption. you can create java service name of your own choice and copy paste below code to the body. Code refers to a common class AES which is provided in section of shared code and needed to copied to shared code area of java service.
// pipeline IDataCursor pipelineCursor = pipeline.getCursor(); final String strToDecrypt = IDataUtil.getString( pipelineCursor, "strToDecrypt" ); final byte[] strKey = Base64.getDecoder().decode(IDataUtil.getString( pipelineCursor, "strKey" )); final byte[] ivBytes = Base64.getDecoder().decode(IDataUtil.getString( pipelineCursor, "ivKey" )); String inputCipher = IDataUtil.getString( pipelineCursor, "cipher" ); String keyAlgorithm = IDataUtil.getString( pipelineCursor, "keyAlgorithm" ); //Perform check on inputs if(strToDecrypt == null || strToDecrypt.equals("")) throw new ServiceException("strToDecrypt field can not be empty"); if(strKey == null || strKey.equals("")) throw new ServiceException("strKey - Encryption Key field can not be empty"); if(ivBytes == null || ivBytes.equals("")) throw new ServiceException("Initialization Vector field can not be empty"); if(keyAlgorithm == null || keyAlgorithm.equals("")) keyAlgorithm = "AES"; if(inputCipher == null || inputCipher.equals("")) inputCipher = "AES/CBC/PKCS5Padding"; //Call common Decrypt function AES.decrypt(strToDecrypt.trim(), inputCipher, keyAlgorithm, strKey, ivBytes); IDataUtil.put( pipelineCursor, "decryptedStr", AES.getDecryptedString() ); //Remove input pipeline variable from pipeline IDataUtil.remove(pipelineCursor, "strToDecrypt"); IDataUtil.remove(pipelineCursor, "strKey"); IDataUtil.remove(pipelineCursor, "ivKey"); IDataUtil.remove(pipelineCursor, "cipher"); IDataUtil.remove(pipelineCursor, "keyAlgorithm"); pipelineCursor.destroy();
Java Service to Encrypt
This service encrypt text. it accepts string which needs encryption, encryption key in base64 format and initialization vector in base64 format. Screenshot below shows inputs and output for service.
JavaCode for encrypt Service
Below is java code which needs to be put in java service for encryption. you can create java service name of your own choice and copy paste below code to the body. Code refers to a common class AES which is provided in section of shared code and needed to copied to shared code area of java service.
// pipeline IDataCursor pipelineCursor = pipeline.getCursor(); final String strToEncrypt = IDataUtil.getString( pipelineCursor, "strToEncrypt" ); final byte[] strKey = Base64.getDecoder().decode(IDataUtil.getString( pipelineCursor, "strKey" )); final byte[] ivBytes = Base64.getDecoder().decode(IDataUtil.getString( pipelineCursor, "ivKey" )); String inputCipher = IDataUtil.getString( pipelineCursor, "cipher" ); String keyAlgorithm = IDataUtil.getString( pipelineCursor, "keyAlgorithm" ); //Perform check on inputs if(strToEncrypt == null || strToEncrypt.equals("")) throw new ServiceException("strToDecrypt field can not be empty"); if(strKey == null || strKey.equals("")) throw new ServiceException("strKey - Encryption Key field can not be empty"); if(ivBytes == null || ivBytes.equals("")) throw new ServiceException("Initialization Vector field can not be empty"); if(keyAlgorithm == null || keyAlgorithm.equals("")) keyAlgorithm = "AES"; if(inputCipher == null || inputCipher.equals("")) inputCipher = "AES/CBC/PKCS5Padding"; //Call common encrypt function AES.encrypt(strToEncrypt.trim(), inputCipher, keyAlgorithm, strKey, ivBytes ); IDataUtil.put( pipelineCursor, "encryptedStr", AES.getEncryptedString()); //Remove input pipeline variable from pipeline IDataUtil.remove(pipelineCursor, "strToEncrypt"); IDataUtil.remove(pipelineCursor, "strKey"); IDataUtil.remove(pipelineCursor, "ivKey"); IDataUtil.remove(pipelineCursor, "cipher"); IDataUtil.remove(pipelineCursor, "keyAlgorithm"); pipelineCursor.destroy();
Shared Code for AES Encryption Decryption
Below code needs to be placed in IS Shared code area. methods in this shared code are called by java service in order to perform aes encryption decryption
Please import below classes in your java service for js to compile without issue.
import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Base64; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec;
AES Encryption Decryption common Class Code
// --- <<IS-BEGIN-SHARED-SOURCE-AREA>> --- public static class AES { private static SecretKeySpec secretKey ; private static byte[] key ; private static byte[] ivGeneratedKey ; private static String decryptedString; private static String encryptedString; public static byte[] setKey(String myKey, String messageDigest, String keyAlgorithm, String encoding, int keySize){ MessageDigest sha = null; try { key = myKey.getBytes(encoding); sha = MessageDigest.getInstance(messageDigest); key = sha.digest(key); secretKey = new SecretKeySpec(key, 0, keySize, keyAlgorithm); // KeySize as per input setGeneratedKey(secretKey.getEncoded()); // Initialize a secure random number generator SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); //Calling nextBytes method to generate Random Bytes ivGeneratedKey = new byte[16]; secureRandom.nextBytes(ivGeneratedKey); setIV(ivGeneratedKey); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnsupportedEncodingException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } public static String getDecryptedString() { return decryptedString; } public static void setDecryptedString(String decryptedString) { AES.decryptedString = decryptedString; } public static byte[] getGeneratedKey() { return key; } public static void setGeneratedKey(byte[] key) { AES.key = key; } public static byte[] getIV() { return ivGeneratedKey; } public static void setIV(byte[] ivGeneratedKey) { AES.ivGeneratedKey = ivGeneratedKey; } public static String getEncryptedString() { return encryptedString; } public static void setEncryptedString(String encryptedString) { AES.encryptedString = encryptedString; } public static String encrypt(String strToEncrypt, String inputCipher, String keyAlgorithm, byte[] secretKey, byte[] ivBytes) { try { Cipher cipher = Cipher.getInstance(inputCipher); SecretKeySpec encryptKey = new SecretKeySpec(secretKey, keyAlgorithm); cipher.init(Cipher.ENCRYPT_MODE, encryptKey, new IvParameterSpec(ivBytes)); setEncryptedString(Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")))); } catch (Exception e) { System.out.println("Error while encrypting: "+e.toString()); } return null; } public static String decrypt(String strToDecrypt, String inputCipher, String keyAlgorithm, byte[] secretKey, byte[] ivBytes) { try { Cipher cipher = Cipher.getInstance(inputCipher); SecretKeySpec decryptKey = new SecretKeySpec(secretKey, keyAlgorithm); cipher.init(Cipher.DECRYPT_MODE, decryptKey, new IvParameterSpec(ivBytes)); setDecryptedString(new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)))); } catch (Exception e) { System.out.println("Error while decrypting: "+e.toString()); } return null; } } // --- <<IS-END-SHARED-SOURCE-AREA>> ---
Creating above mentioned java services should get you going with AES encryption decryption in webMethods Integration Server.
Hope this post will be of some help to you. If you have any questions\comments, please leave a comment below or use Contact Us page to send email. Please also let me know if there is some information which you find wrong. it will help me to improve quality of this post and help more people.
Disclaimer –
- This code for AES Encryption Decryption was originally posted at AESEncryption website. Please contact me through Contact Us, If you are owner of code and i will update post with proper credits. The code posted in this link is converted and changed to use it in webMethods as java service.
- Sample Code was tested in 9.8 Integration server, JDK 1.8 and only with AES Encryption Decryption mode, Cipher Mode CBC, key Size of 128\256 bits and Initialization Vector with 16 bytes. Code is generic and open to accept any encryption mode, cipher mode. please Test it thoroughly before integrating in your code base.
Credits
- http://aesencryption.net/#Java-aes-encryption-example
- https://www.owasp.org/index.php/Using_the_Java_Cryptographic_Extensions#AES_Encryption_and_Decryption
- http://docs.oracle.com/javase/8/docs/api/index.html
Questions? Comments? Suggestions? Let us know!! Like / Subscribe / Follow for more updates.