Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

encrypt/decrypt AES 256, vorsalt error

New Here ,
Jul 06, 2012 Jul 06, 2012

Hiyas.

So I'm trying to get encrypt/decrypt to work for AES 256, with both 32byte key and 32byte IVorSalt. (Yup-new java security files v6 installed)

'IF' I 32byte key but dont use a IV at all, I get a nice looking AES 256 result. (I can tell it's AES 256 by looking the length of the encrypted string)

'IF' I use a 32byte key and 16bit salt, I get a AES 128 result (I know- as per docs theyre both s'posed to the same size, but the docs are wrong).

But when i switch to using both a 32byte key AND a 32byte salt I get the error below.

An error occurred while trying to encrypt or decrypt your input string: Bad parameters: invalid IvParameterSpec: com.rsa.jsafe.crypto.JSAFE_IVException: Invalid IV length. Should be 16.

Has anyone 'EVER' gotten encrypt to work for them using AES 256 32byte key and 32byte salt? Is this a bug in CF? Or Java? Or I am doing something wrong?

<!--- ////////////////////////////////////////////////////////////////////////// Here's the Code ///////////////////////////////////////////////////////////////////////// --->

<cfset theAlgorithm  = "Rijndael/CBC/PKCS5Padding" />

<cfset gKey = "hzj+1o52d9N04JRsj3vTu09Q8jcX+fNmeyQZSDlZA5w="><!--- these 2 are the same --->

<!---<cfset gKey = ToBase64(BinaryDecode("8738fed68e7677d374e0946c8f7bd3bb4f50f23717f9f3667b2419483959039c", "Hex"))>--->

<cfset theIV    = BinaryDecode("7fe8585328e9ac7b7fe8585328e9ac7b7fe8585328e9ac7b7fe8585328e9ac7b","hex")>

<!---<cfset theIV128    = BinaryDecode("7fe8585328e9ac7b7fe8585328e9ac7b","hex")>--->

<cffunction    name="DoEncrypt" access="public" returntype="string" hint="Fires when the application is first created.">

    <cfargument    name="szToEncrypt" type="string" required="true"/>

   

    <cfset secretkey = gKey>               

   

    <cfset szReturn=encrypt(szToEncrypt, secretkey, theAlgorithm, "Base64", theIV)>

    <cfreturn szReturn>

</cffunction>   

<cffunction    name="DoDecrypt" access="public" returntype="string" hint="Fires when the application is first created.">

    <cfargument    name="szToDecrypt" type="string" required="true"/>

   

    <cfset secretkey = gKey>   

   

    <cfset szReturn=decrypt(szToDecrypt, secretkey, theAlgorithm, "Base64",theIV)>       

    <cfreturn szReturn>

</cffunction>

<cfset szStart = form["toencrypt"]>

<cfset szStart = "Test me!">

<cfset szEnc = DoEncrypt(szStart)>

<cfset szDec = DoDecrypt(szEnc)>

<cfoutput>#szEnc# #szDec#</cfoutput>

5.3K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Advocate , Jul 08, 2012 Jul 08, 2012

Whether or not you are doing something wrong depends on what you are trying to do.

When it comes to so-called AES 256 there are two options as to what this can mean.

1. In most of the programming world, AES 256 means AES crypto with a 128-bit block size and a 256-bit key. The CBC Initialization vector should be the same size as the block, not the same size as the key. So it should be 128-bit

2. In some parts of the programming world (primarily PHP) AES 256 is Rijndael crypto with a 256-bit block

...
Translate
Advocate ,
Jul 08, 2012 Jul 08, 2012

Whether or not you are doing something wrong depends on what you are trying to do.

When it comes to so-called AES 256 there are two options as to what this can mean.

1. In most of the programming world, AES 256 means AES crypto with a 128-bit block size and a 256-bit key. The CBC Initialization vector should be the same size as the block, not the same size as the key. So it should be 128-bit

2. In some parts of the programming world (primarily PHP) AES 256 is Rijndael crypto with a 256-bit block size. The problem here is that this is NOT AES. It uses the MCRYPT_RIJNDAEL_256 algorithm. Rijndael is the algorithm on which AES was built, but not everything that is Rijndael is AES.

So if what you want is AES 256-bit crypto, then using a 256-bit key with a 128-bit IV is the correct way to do it. AES *only* has 128-bit block sizes. So this is neither a bug in Java or CF.

If you actually need 256-bit block sizes, then I would guess you are probably trying to interoperate with a system that used PHP for crypto. If that is the case, I believe you will need to dig down into Java and do the crypto the hard way to support it. You may also need to add a new JCA/JCE Crypto provider if none of the standard providers included with CF have MCRYPT_RIJNDAEL_256.

Good luck,

Jason

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 13, 2012 Jul 13, 2012
LATEST

Hi Robo

Thanks for explaination.

I was operating under the 'mis'conception that AES256 implied 32byte key AND salt.

.Net was more than happy to use 32byte values for both, so it was confusing when CF was choking even after I update the JS policy files.

And thank you itisdesign also!

Good work on the code mods! I had seen the lib you mentioned. Maybe for another project that would be the way to go

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Jul 09, 2012 Jul 09, 2012

Hi edevmachine,

This Bouncy Castle Encryption CFC supports Rijndael w/ 256-bit block size. (big thanks to Jason here and all who helped w/ that, btw!)

Example:

<cfscript>

  BouncyCastleCFC = new path.to.BouncyCastle();

  string = "ColdFusion Rocks!"; 

  key = binaryEncode(binaryDecode(generateSecretKey("Rijndael", 256), "base64"), "hex");//the CFC takes hex'd key

  ivSalt = binaryEncode(binaryDecode(generateSecretKey("Rijndael", 256), "base64"), "hex");//the CFC takes hex'd ivSalt

  encrypted = BouncyCastleCFC.doEncrypt(string, key, ivSalt);

  writeOutput(BouncyCastleCFC.doDecrypt(encrypted, key, ivSalt));

</cfscript>

Related links for anyone interested in adding 256-bit block size Rijndael support into ColdFusion:

- An explanation of how to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files in...

- An explanation of how to install the Bouncy Castle Crypto package into ColdFusion (near bottom, under the "Installing additional security providers" heading)

- An explanation of how to connect the Bouncy Castle classes together
- Bouncy Castle's doc for the Rijndael Engine

And here is the full CFC as posted in the StackOverflow discussion:

<cfcomponent displayname="Bounce Castle Encryption Component" hint="This provides bouncy castle encryption services" output="false">

<cffunction name="createRijndaelBlockCipher" access="private">
   
<cfargument name="key" type="string" required="true" >
   
<cfargument name="ivSalt" type="string" required="true" >
   
<cfargument name="bEncrypt" type="boolean" required="false" default="1">
   
<cfargument name="blocksize" type="numeric" required="false" default=256>
   
<cfscript>
    // Create a block cipher for Rijndael
    var cryptEngine = createObject("java", "org.bouncycastle.crypto.engines.RijndaelEngine").init(arguments.blocksize);

    // Create a Block Cipher in CBC mode
    var blockCipher = createObject("java", "org.bouncycastle.crypto.modes.CBCBlockCipher").init(cryptEngine);

    // Create Padding - Zero Byte Padding is apparently PHP compatible.
    var zbPadding = CreateObject('java', 'org.bouncycastle.crypto.paddings.ZeroBytePadding').init();

    // Create a JCE Cipher from the Block Cipher
    var cipher = createObject("java", "org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher").init(blockCipher,zbPadding);

    // Create the key params for the cipher    
    var binkey = binarydecode(arguments.key,"hex");
    var keyParams = createObject("java", "org.bouncycastle.crypto.params.KeyParameter").init(BinKey);

    var binIVSalt = Binarydecode(ivSalt,"hex");
    var ivParams = createObject("java", "org.bouncycastle.crypto.params.ParametersWithIV").init(keyParams, binIVSalt);

    cipher.init(javaCast("boolean",arguments.bEncrypt),ivParams);

    return cipher;
   
</cfscript>
</cffunction>

<cffunction name="doEncrypt" access="public" returntype="string">
   
<cfargument name="message" type="string" required="true">
   
<cfargument name="key" type="string" required="true">
   
<cfargument name="ivSalt" type="string" required="true">

   
<cfscript>
    var cipher = createRijndaelBlockCipher(key=arguments.key,ivSalt=arguments.ivSalt);
    var byteMessage = arguments.message.getBytes();
    var outArray = getByteArray(cipher.getOutputSize(arrayLen(byteMessage)));
    var bufferLength = cipher.processBytes(byteMessage, 0, arrayLen(byteMessage), outArray, 0);
    var cipherText = cipher.doFinal(outArray,bufferLength);

    return toBase64(outArray);
   
</cfscript>
</cffunction>


<cffunction name="doDecrypt" access="public" returntype="string">
   
<cfargument name="message" type="string" required="true">
   
<cfargument name="key" type="string" required="true">
   
<cfargument name="ivSalt" type="string" required="true">

   
<cfscript>
    var cipher = createRijndaelBlockCipher(key=arguments.key,ivSalt=arguments.ivSalt,bEncrypt=false);
    var byteMessage = toBinary(arguments.message);
    var outArray = getByteArray(cipher.getOutputSize(arrayLen(byteMessage)));
    var bufferLength = cipher.processBytes(byteMessage, 0, arrayLen(byteMessage), outArray, 0);
    var originalText = cipher.doFinal(outArray,bufferLength);

    return createObject("java", "java.lang.String").init(outArray);
   
</cfscript>
</cffunction>

<cfscript>
function getByteArray(someLength)
{
    byteClass = createObject("java", "java.lang.Byte").TYPE;
    return createObject("java","java.lang.reflect.Array").newInstance(byteClass, someLength);
}
</cfscript>

</cfcomponent>

Thanks!,

-Aaron

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Resources