4

I'm having trouble understanding how I can pad a string in CF with null bytes. In Java I would do this...

String ZeroPad = "";
for (int i = 0; i < 32; i++)
    ZeroPad = ZeroPad + "\0";
String strKey = strUsername + strPassword + ZeroPad;
strKey = strKey.substring(0, 32);

But doing the following in ColdFusion produces something like this "\0\0..." instead of null bytes.

<cfset var key = arguments.username&arguments.password/>
<cfloop condition="#len(key)# less than 32">
    <cfset key = key & "\0"/>
</cfloop>
<cfset key = key.substring(0,32)/>

Continued problems. Ok, I've updated my CFML to this...

<cfset var strB = createObject("java", "java.lang.StringBuilder")/>

<cfloop from=1 to=32 index="i">
    <cfset zeroPad = zeroPad & URLDecode("%00")/>
</cfloop>

<cfset strB.append(arguments.username)/>
<cfset strB.append(arguments.password)/>
<cfset strB.append(zeroPad)/>

<cfif strB.length() GT 32>
    <cfset key = strB.substring(0,32)/>
<cfelse>
    <cfset key = strB.toString()/>
</cfif>

The key being generated is used for AES encryption. On my local dev machine (Mac OS X Mavericks) this works fine and I'm able to encrypt with the generated key. However, on my Production environment (Windows Server 2008) I'm getting error "Invalid key size". The key size on both shows as 32 and I'm flummoxed.

E-Madd
  • 4,414
  • 5
  • 45
  • 77
  • @AdamCameron - Unfortunately no. The character just disappears. But URLDecode("%00") will generate a single null byte. – Leigh Dec 06 '13 at 23:09
  • Oh weird. I'll have to have a play around with that. Is that expected behaviour? Cheers for the correction @Leigh – Adam Cameron Dec 06 '13 at 23:10
  • @AdamCameron - Expected? Well, not from my POV. But string handling has always been a bit off from java in some areas. For example, in you can use escapes like `new String("\u0061")` to get the character `a`, but the same createObject code in CF just gives you the literal chars: `\u0061`. Funky behavior IMO. – Leigh Dec 06 '13 at 23:18
  • @Leigh Thanks. That worked, but I ran into another problem and updated my question. – E-Madd Dec 06 '13 at 23:26
  • Adam - Though now I am wondering if `chr(0)` deliberately returning "" instead of a null byte was for technical reasons or just a "protect developers from themselves" deal.. – Leigh Dec 06 '13 at 23:27
  • @Leigh it wouldn't surprise me from Aunty Adobe. If I can make something interesting about it, I might write a blog article. Seeing some weirdness, fer sure. – Adam Cameron Dec 06 '13 at 23:29
  • @E-Madd - Probably better to keep the issues separate and open a new thread about the encryption key issues. If possible, include some sample values (plain string, key, encrypted result) so we can test the code .. using a **sample** key of course! – Leigh Dec 06 '13 at 23:29
  • @Leigh Thanks. I'll do that. It appears my local machine is running Java 1.6.0_65 while the production server is Java 1.7.0_15. – E-Madd Dec 06 '13 at 23:31
  • @Leigh: FYI: http://cfmlblog.adamcameron.me/2013/12/cfml-weirdness-with-chr0.html – Adam Cameron Dec 07 '13 at 20:59
  • 1
    Just want to add use `stringRepeat(URLDecode("%00"), 32)` instead of that verbose for loop. :) – Busches Dec 07 '13 at 23:08

1 Answers1

2

I have used this tip in the past, ie: URLDecode("%00", "utf-8")

Update:

Since the encrypt() function always interprets the plain text input as a UTF-8 string, you can also use charsetEncode(bytes, "utf-8") to create a null character from a single element byte array.

 charsetEncode( javacast("byte[]", [0] ), "utf-8");
Leigh
  • 28,765
  • 10
  • 55
  • 103