Using crypto-js to encrypt password and send form via ajax (and decrypt in java), I get : TypeError: Cannot read property 'words' of undefined

Using crypto-js to encrypt password and send form via ajax (and decrypt in java), I get : TypeError: Cannot read property 'words' of undefined

我正在尝试保护我从 HTML 表单发送到 Java Servlet(通过 ajax)的密码。我在我的js中使用crypto-js来加密密码。 当代码到达 ajax 调用时,出现错误:

Uncaught TypeError: Cannot read property 'words' of undefined (aes.js:8)

(我已经确定我发送的密钥不为空)

这是我的代码:


login.jsp:

<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="css/style.css">
<script src="jquery-1.11.2.min.js"></script>
<script type='text/javascript'>
localStorage.setItem('loggedin', false);
</script>
<script src="login.js"></script>
<script src="http://crypto-    js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/pbkdf2.js"></script>
<script type="text/javascript">
function convertAndSubmit()
{
    var salt = CryptoJS.lib.WordArray.random(128/8);
    var iv = CryptoJS.lib.WordArray.random(128/8);           
    console.log('salt  '+ salt );
    console.log('iv  '+ iv );
    var key128Bits100Iterations = CryptoJS.PBKDF2('1234567890987654', salt,         { keySize: 256/32, iterations: 100 });
    console.log( 'key128Bits100Iterations '+ key128Bits100Iterations);
    var encrypted = CryptoJS.AES.encrypt($("#pwd").val(), key128Bits100Iterations, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7  }).toString();
    checkLogin(encrypted, randkey, salt, iv);
}
    </script>
  </head>

  <body>

<div class="container">
  <div id="login-form">
    <h3>Login</h3>

    <fieldset>
      <form action="javascript:void(0);" method="get" name="login">
        <input type="email" id="email" name="email" required value="Email"      onBlur="if(this.value=='')this.value='Email'" onFocus="if(this.value=='Email')this.value='' ">
        <input type="password" id="pwd" name="pwd" required value="Password" onBlur="if(this.value=='')this.value='Password'" onFocus="if(this.value=='Password')this.value='' "> 
        <input type="submit" value="Login" id="login" onclick="javascript:convertAndSubmit()">
      </form>
    </fieldset>

  </div> <!-- end login-form -->
</div>
<div id="output"></div>
  </body>
</html>

login.js:

function ajaxLogin(credentials) {
    var retData = null;
    $.ajax({ //this is where the code generates the error
        async: false,
        type: 'GET',
        data: credentials,
        url: "http://localhost:8080/AtlasServices/Login",
        success: function(data) {
            retData = data;
        }
    });
    return retData;
}

function checkLogin(encrypted, key, s, i) {
    var credentials = {
        email: $("#email").val(),
        pass: encrypted,
        key: key,
        salt: s,
        iv: i
    };

    var res = window.ajaxLogin(credentials);
    if (res["userlogged"] !== "true") {
        alert("Failed to log in");
        $("#email").val("");
        $("#pwd").val("");
        localStorage.setItem('loggedin', false);
    } else {
        localStorage.setItem('loggedin', true);
        window.location = "http://localhost:8080/AtlasServices/main.html";
    }
}

我一直在寻找解决方案...真的很想得到一些帮助,谢谢:)

CryptoJS.lib.WordArray.random(..) 创建 WordArray 对象。

来自您的代码:

var salt = CryptoJS.lib.WordArray.random(128/8);
var iv = CryptoJS.lib.WordArray.random(128/8);    

这意味着 salt 并且 iv 是一个对象而不是字符串。

您能够按编码记录 saltiv,因为 console.logsaltiv 内部调用 toString encodes WordArray

您需要做的就是明确编码这些:

checkLogin(encrypted, randkey, salt.toString(), iv.toString());

注意:您遇到的错误与JQuery有关;在构建 url 参数时 JQuery 读取所有 objectssub-objectsarrays 函数 等...,当您将 WordArray 作为对象发送 jQuery 尝试调用它的函数以将 return 值提取到 url 参数中。

在您的情况下,它使用未定义的参数调用 concat 函数,这会导致出现错误。您可以通过调用 $.param(salt)(或 iv)简单地重现此错误。