4

This has become more of an exercise in what am I doing wrong than mission critical, but I'd still like to see what (simple probably) mistake I'm making.

I'm using mysql (5.1.x) AES_ENCRYPT to encrypt a string. I'm using CF's generateSecretKey('AES') to make a key (I've tried it at defaul and 128 and 256 bit lengths).

So let's say my code looks like this:

    <cfset key = 'qLHVTZL9zF81kiTnNnK0Vg=='/>
    <cfset strToEncrypt = '4111111111111111'/>
    <cfquery name="i" datasource="#dsn#">
        INSERT INTO table(str) 
            VALUES AES_ENCRYPT(strToEncrypt,'#key#');
    </cfquery>

That works fine as expected and I can select it using SELECT AES_DECRYPT(str,'#key#') AS... with no problems at all.

What I can't seem to do though is get CF to decrypt it using something like:

    <cfquery name="s" datasource="#dsn#">
        SELECT str
          FROM table
    </cfquery>
    <cfoutput>#Decrypt(s.str,key,'AES')#</cfoutput>

or

    <cfoutput>#Decrypt(toString(s.str),key,'AES')#</cfoutput>

I keep getting "The input and output encodings are not same" (including the toString() - without that I get a binary data error). The field type for the encrypted string in the db is blob.

Sergey Galashyn
  • 6,946
  • 2
  • 19
  • 39
Steve
  • 2,776
  • 3
  • 25
  • 44
  • 1
    I've fixed a couple of tiny `cfml` things, but your queries look like you've written, but not really tested. This looks not very good. You should be more careful with code samples -- we may want to try them (surprise!). – Sergey Galashyn Jun 07 '12 at 05:53
  • These were definitely not real queries or anything - just used to illustrate the question. – Steve Jun 08 '12 at 10:42

1 Answers1

5

This entry explains that mySQL handles AES-128 keys a bit differently than you might expect:

.. the MySQL algorithm just or’s the bytes of a given passphrase against the previous bytes if the password is longer than 16 chars and just leaves them 0 when the password is shorter than 16 chars.

Not highly tested, but this seems to yield the same results (in hex).

<cfscript>
    function getMySQLAES128Key( key ) {
        var keyBytes   = charsetDecode( arguments.key, "utf-8" );
        var finalBytes = listToArray( repeatString("0,", 16) );

        for (var i = 1; i <= arrayLen(keyBytes); i++) {
            // adjust for base 0 vs 1 index
            var pos = ((i-1) % 16) + 1;
            finalBytes[ pos ] = bitXOR(finalBytes[ pos ], keyBytes[ i ]);
        }

        return binaryEncode( javacast("byte[]", finalBytes ), "base64" );
    }

    key     = "qLHVTZL9zF81kiTnNnK0Vg==";
    input   = "4111111111111111";

    encrypted = encrypt(input, getMySQLAES128Key(key), "AES", "hex");
    WriteDump("encrypted="& encrypted);

    // note: assumes input is in "hex". either convert the bytes 
    // to hex in mySQL first or use binaryEncode
    decrypted = decrypt(encrypted, getMySQLAES128Key(key), "AES", "hex");
    WriteDump("decrypted="& decrypted);
</cfscript>

Note: If you are using mySQL for encryption be sure to see its documentation which mentions the plain text may end up in various logs (replication, history, etectera) and "may be read by anyone having read access to that information".


Update: Things may have changed, but according to this 2004 bug report the .mysql_history file is only on Unix. (Keep in mind there may be other log files) Detailed instructions for clearing .mysql_history can be found in the manual, but in summary:

  • Set the MYSQL_HISTFILE variable to /dev/null (on each log in)
  • Create .mysql_history as a symbolic link to /dev/null (only once)
Leigh
  • 28,765
  • 10
  • 55
  • 103
  • Yeah, I was a little surprised when I saw that in the documentation. Definitely something I would not have thought of.. – Leigh Jun 07 '12 at 17:39
  • Great tip on the logs. I ended up rolling my own in that CF encrypts the initial string and MySQL encrypts the CF key. I do want to go through my MySQL logs though and see what's being logged and if/how to move or change the logging settings. – Steve Jun 08 '12 at 10:40
  • @Steve - If you find out anything new about the log settings, do post it. I would be curious to know if there is a way to disable it / or if the behavior has changed in recent versions. – Leigh Jun 08 '12 at 12:26