How can I encrypt a string in Java just like it is encrypted in ColdFusion?

I have data encrypted in ColdFusion that I should be able to decrypt and encrypt the exact same value using Java. I was hoping someone could help me. I will indicate everything that is used in ColdFusion, except for the actual PasswordKey, which I have to keep secret for security purposes. Password length is 23 characters. It uses uppercase and lowercase letters, numbers and + and = signs. I know this is a lot to ask, but any help would be greatly appreciated.

I tried using the Java encryption example, which I found online and simply replaced the line below 23 characters used in our CF application:

private static final byte[] keyValue = new byte[] {'T', 'h', 'i', 's', 'I', 's', 'A', 'S', 'e', 'c', 'r', 'e', 't', 'K', 'e', 'y' };` 

But I get the error:

 java.security.InvalidKeyException: Invalid AES key length: 23 bytes 

CF Code:

 Application.PasswordKey = "***********************"; Application.Algorithm = "AES"; Application.Encoding = "hex"; <cffunction name="encryptValue" access="public" returntype="string"> <cfargument name="strEncryptThis" required="yes"> <cfreturn Encrypt(TRIM(strEncryptThis), Application.PasswordKey, Application.Algorithm, Application.Encoding)> </cffunction> <cffunction name="decryptValue" access="public" returntype="string"> <cfargument name="strDecryptThis" required="yes"> <cfreturn Decrypt(TRIM(strDecryptThis), Application.PasswordKey, Application.Algorithm, Application.Encoding)> </cffunction> 
+4
source share
4 answers

Thank you all for your help. I wanted to publish my final solution to other users. I include all of my encryption code code minus a special password key (again for security). This code creates the same sixth line as the CF code indicated in the question and decrypts it back to the correct English text string.

I found the bytesToHex and hexStringToByteArray in another stackoverflow question, so thanks to my users, perhaps WeeouldStealAVan and Dave L. respectively. I think I will look at the other 64 encoders / decoders in case one of them is never available, but it definitely works. Thanks again.

 package encryptionpackage; import java.security.*; import java.security.spec.InvalidKeySpecException; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import sun.misc.*; public class encryption { // Note: The full CF default is "AES/ECB/PKCS5Padding" private static final String ALGORITHM = "AES"; // The 24 character key from my CF app (base64 encoded) // typically generated with: generateSecretKey("AES") private static final String passKey = "***********************"; public static String encrypt(String valueToEnc) throws Exception { Key key = generateKey(); Cipher c = Cipher.getInstance(ALGORITHM); c.init(Cipher.ENCRYPT_MODE, key); byte[] encValue = c.doFinal(valueToEnc.getBytes()); String encryptedValue = bytesToHex(encValue); return encryptedValue; } public static String decrypt(String encryptedValue) throws Exception { Key key = generateKey(); Cipher c = Cipher.getInstance(ALGORITHM); c.init(Cipher.DECRYPT_MODE, key); byte[] decordedValue = hexStringToByteArray(encryptedValue); byte[] decValue = c.doFinal(decordedValue); String decryptedValue = new String(decValue); return decryptedValue; } private static Key generateKey() throws Exception { byte[] keyValue; keyValue = new BASE64Decoder().decodeBuffer(passKey); Key key = new SecretKeySpec(keyValue, ALGORITHM); return key; } public static String bytesToHex(byte[] bytes) { final char[] hexArray = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; char[] hexChars = new char[bytes.length * 2]; int v; for ( int j = 0; j < bytes.length; j++ ) { v = bytes[j] & 0xFF; hexChars[j * 2] = hexArray[v >>> 4]; hexChars[j * 2 + 1] = hexArray[v & 0x0F]; } return new String(hexChars); } public static byte[] hexStringToByteArray(String s) { int len = s.length(); byte[] data = new byte[len / 2]; for (int i = 0; i < len; i += 2) { data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i+1), 16)); } return data; } } 
+1
source

Your private key is most likely Base64 encoded (23 characters should decode up to about 16 bytes, which is the correct length for a 128-bit key for AES).

So, in your java code, first run your secret key string through the Base64 decoder to get the byte [] of the appropriate length (16 bytes) for the AES algorithm.

+2
source

128, but AES Encryption supports a 16-byte key.
16 * 8 = 128 bits, even in the example the key is 16 bytes.

It looks like your key is in Base64, so use Base64.decode (key or key.getBytes ()) to get an array of bytes, check it at 16 bytes, otherwise make it 16 bytes by filling.

+2
source

AES Encryption only supports 128-bit, 192-bit, or 256-bit key sizes.

http://en.wikipedia.org/wiki/Advanced_Encryption_Standard

You cannot just take any byte array and use it as an AES key. In the code example that you see above, the example cleverly used 16 characters, which corresponds to a 128-bit key.

This is because 1 character or more than 1 byte corresponds to 8 bits.

A 16-digit byte array will correspond to 16 * 8 = 128 bits

23 characters = 23 * 8 = 184 bits , so this is an invalid key size.

You need either 16 characters, or 24 characters, or 32 characters.

At the same time, the use of simple characters for AES encryption is extremely unsafe. Use a secure and secure random key for encryption.

To create a secure and random AES key:

 SecureRandom random = new SecureRandom(); byte [] secret = new byte[16]; random.nextBytes(secret); 

http://docs.oracle.com/javase/6/docs/api/java/security/SecureRandom.html

0
source

All Articles