ColdFusion加密/解密中的“无效填充”异常

时间:2014-12-17 02:08:35

标签: coldfusion coldfusion-11

我的代码抛出了一个我无法理解的异常。我还是编程新手,所以请耐心等待。这是我的代码:

<cfsetting showdebugoutput="false">
<cfprocessingdirective pageencoding="utf-8">
<html>
    <head>
        <title>Test</title>
    </head>
<body>

    <cfset key = generateSecretKey("AES")>

    <cfscript>
        if (isDefined("form")) {
            encFieldnamesArr = listToArray(form.fieldnames);
            decFieldnamesArr = arrayNew(1);

            for (paramName in encFieldnamesArr) {
                arrayAppend(decFieldnamesArr, "#decrypt(paramName, key, 'AES', 'HEX')#");
            }
        }
    </cfscript>

    <cfform>
        <cfinput name="#encrypt("firstName", key, "AES", "HEX")#" type="text" />
        <cfinput name="#encrypt("lastName", key, "AES", "HEX")#" type="text" />
        <cfinput type="submit" name="#encrypt("action", key, "AES", "HEX")#" value="submit" />
    </cfform>

</body>
</html>

它引发了这个异常:

 An error occurred while trying to encrypt or decrypt your input string: Invalid padding..

The error occurred in C:/ColdFusion11/cfusion/wwwroot/test/index.cfm: line 17

15 : 
16 :            for (paramName in encFieldnamesArr) {
17 :                arrayAppend(decFieldnamesArr, "#decrypt(paramName, key, 'AES', 'HEX')#");
18 :            }
19 :        }

“无效填充”是什么意思?感谢

1 个答案:

答案 0 :(得分:1)

解密时,必须使用与加密值完全相同的key。每次页面加载时,您的代码都会生成一个全新的密钥:

<cfset key = generateSecretKey("AES")>

因此代码使用一个密钥进行加密。然后,当提交表单时,它使用完全不同的密钥decrypt()。因此错误。

示例:

<cfscript>
  // WORKS: encrypt and decrypt with the same key
  key = generateSecretKey("AES");
  text = "the quick brown fox jumps over the lazy dog";
  encrypted = encrypt(text, key, 'AES', 'HEX');
  decrypted = decrypt(encrypted, key, 'AES', 'HEX');
  writeOutput("<br>text="& text);
  writeOutput("<br>key="& key);
  writeOutput("<br>encrypted="& encrypted);
  writeOutput("<br>decrypted="& decrypted);

  // FAILS: Decrypting with a *different* key will fail
  key = generateSecretKey("AES");
  writeOutput("<br>key="& key);
  decrypted = decrypt(encrypted, key, 'AES', 'HEX');
</cfscript>

我意识到以上只是一个实验,但有一些提示:

  1. FORM是一个系统结构,因此应始终定义它。通常,您会检查是否存在特定的表单字段名称。即

    structKeyExists(FORM, "someFieldName")

  2. 由于您没有使用cfform / cfinput的任何额外功能(无论如何都不是很好),只需使用简单的html <form><input>标记即可。使用CF版本将导致CF向您的页面添加大量不必要的JavaScript代码。

  3. 解密后无需双引号或#符号。只需使用:

    decrypt(paramName, key, 'AES', 'HEX')