CF8和AES解密MySQL AES:编码不一样

Ste*_*eve 4 mysql encryption coldfusion aes coldfusion-8

对于我做错的事情而言,这已经成为一种锻炼,而不是关键任务,但我仍然希望看到我正在犯的错误(简单可能).

我正在使用mysql(5.1.x)AES_ENCRYPT来加密字符串.我正在使用CF的generateSecretKey('AES')来创建一个密钥(我已经在defaul和128和256位长度上尝试过它).

所以让我们说我的代码看起来像这样:

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

这可以正常工作,我可以使用SELECT AES_DECRYPT(str,'#key#')AS来选择它...完全没有问题.

我似乎无法做的是让CF使用以下内容解密它:

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

要么

    <cfoutput>#Decrypt(toString(s.str),key,'AES')#</cfoutput>
Run Code Online (Sandbox Code Playgroud)

我一直得到"输入和输出编码不一样"(包括toString() - 没有我得到二进制数据错误).db中加密字符串的字段类型是blob.

Lei*_*igh 5

此条目解释了mySQL处理AES-128键的方式与您预期的略有不同:

..如果密码长度超过16个字符,则MySQL算法正好或者是给定密码短语的字节数,如果密码长度超过16个字符,则只留下0.

没有高度测试,但这似乎产生相同的结果(十六进制).

<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>
Run Code Online (Sandbox Code Playgroud)

注意:如果您使用mySQL进行加密,请务必查看其文档,其中提到纯文本可能最终出现在各种日志中 (复制,历史记录,etectera),"任何对该信息具有读取权限的人都可以阅读".


更新:事情可能已经改变,但根据2004年的错误报告,.mysql_history文件仅在Unix上.(请记住可能有其他日志文件)有关清除.mysql_history的详细说明,请参阅手册,但总结如下:

  • MYSQL_HISTFILE变量设置为/ dev/null(在每次登录时)
  • 创建.mysql_history作为/ dev/null的符号链接(仅一次)