Reputation: 43
I am trying to secure the password that i am sending from an HTML form to a Java Servlet (via ajax). I use crypto-js
in my js to encrypt the password.
When the code reaches the ajax call, I get the error:
Uncaught TypeError: Cannot read property 'words' of undefined (aes.js:8)
(I already made sure that the key I'm sending is not null)
This is my code:
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";
}
}
I was searching for a long time for a solution...will really love some help, thanks:)
Upvotes: 4
Views: 11863
Reputation: 8793
CryptoJS.lib.WordArray.random(..)
creates WordArray
object.
From your code :
var salt = CryptoJS.lib.WordArray.random(128/8);
var iv = CryptoJS.lib.WordArray.random(128/8);
This means salt
and iv
is an object not a string.
You are able to log salt
and iv
as encoded because console.log
calls toString
internally from salt
and iv
which encodes
the WordArray
All you need to do is encode these explicitly:
checkLogin(encrypted, randkey, salt.toString(), iv.toString());
Note: The error you've got is related with the JQuery
; while building url parameters JQuery
reads all objects
, sub-objects
, arrays
and functions etc... , When you send WordArray
as an object jQuery tries to call it's functions to fetch return value into the url parameter.
In your case it is calling the concat
function with an undefined parameters, which leads to the error you get. You can simply reproduce this error by calling $.param(salt)
(or for iv
).
Upvotes: 2