Search code examples
jquerycryptojs

Why doesn't JQuery work with CryptoJS?


I have an encoding program which allows the user to enter some text and a password to send messages securely.

However, when I try to run the following code, JQuery does not work properly:

text = CryptoJS.AES.encrypt(text, pass);
$("#encodedText").html(text);

<!DOCTYPE html>

<html>

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
  <link rel="icon" sizes="192x192" href="http://www.tdat.byethost10.com/web_images/favicon.ico">
  <link rel="apple-touch-startup-image" href="http://www.tdat.byethost10.com/web_images/favicon.ico">
  <link rel="shortcut icon" href="" type="image/icon">
  <link rel="icon" href="http://www.tdat.byethost10.com/web_images/favicon.ico" type="image/icon">
  <meta name="viewport" content="width = device-width">
  <meta name="mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-capable" content="yes">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"></script>
  <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
  <meta name="mobile-web-app-capable" content="yes">
  <title>ENCRYPT</title>
  <meta charset="UTF-8">
</head>

<style>
  #first {
    font-family: "courier";
    text-align: center;
    color: #00FF04;
  }
  #second {
    color: white;
  }
  #myDIV {
    border: 1px solid green;
    margin-bottom: 10px;
  }
  button {
    border-radius: 50%;
    background-color: #00FF04;
    border-color: #00FF04;
    color: white;
    font-size: 40px;
    transition-duration: 0.4s;
    width: 25%;
    height: 80px;
  }
  button:hover {
    box-shadow: 0 12px 16px 0 rgba(0, 0, 0, 0.24), 0 17px 50px 0 rgba(0, 0, 0, 0.19);
    background-color: red;
    border-color: red;
  }
  .searchTxt {
    color: #00FF04;
    font-family: "courier";
    border: solid #00FF04;
    border-radius: 5px;
    background-color: black;
  }
  .heading {
    font-size: 80px
  }
</style>

<body bgcolor="black" id="first">

  <p class="heading">ENCODE TEXT</p>
  <p>
    Your text:
  </p>
  <br>
  <input class="searchTxt" size="50" id="textToEncode">
  <br>
  <p>Your password:</p>
  <br>
  <input class="searchTxt" size="50" id="textToRedact">
  <br>
  <br>
  <br>
  <button id="encodeButton">Encode!</button>
  <br>
  <br>
  <br>
  <br>
  <p id="encodedText"></p>


  <p class="heading">DECODE TEXT</p>
  <p>Text:</p>
  <br>
  <input class="searchTxt" size="50" id="textToDecode">
  <br>
  <p>Key:</p>
  <br>
  <input class="searchTxt" size="50" id="keyForDecode">
  <br>
  <br>
  <br>
  <button id="decodeButton">Decode!</button>
  <br>
  <br>
  <br>
  <br>
  <p id="decodedText"></p>


  <script>
    var text = "";
    var word = "";
    var redacted = "";
    var encodedInfo = [];
    var key = "";
    var pass = "";

    $("#encodeButton").on("click", function() {
      $("#key").html("");
      $("#encodedText").html("");
      encodedInfo = [];
      redacted = "";
      text = $("#textToEncode").val();
      pass = $("#textToRedact").val();
      text = CryptoJS.AES.encrypt(text, pass);
      alert("Your encrypted message is as such: " + text);
      $("#encodedText").html(text);
    });


    $("#decodeButton").on("click", function() {
      $("#decodedText").html("");
      redacted = "";
      word = "REDACTED";
      text = $("#textToDecode").val();
      key = $("#keyForDecode").val();
      decrypted = CryptoJS.AES.decrypt(text, key);
      decrypted = decrypted.toString(CryptoJS.enc.Utf8);
      if (decrypted === "") {
        alert("FAIL!!! Wrong password.");
      } else {
        $("#decodedText").html(decrypted);
        alert("The message is: " + decrypted);
      }

    });
  </script>
</body>

</html>

As you can see in the snippet it correctly alerts you the encoded message, but it does not change the value of #encodedText. Why might this be so?

LIVE DEMO: redacted.ga/advance.html


Solution

  • Because CryptoJS.AES.encrypt does not return a string with HTML but an object, as you can see if you use the browser console:

    console.log(text);
    

    Object { $super={...}, ciphertext={...}, key={...}, más...}

    The object has a properly defined toString() method:

    console.log(text.toString());
    

    U2FsdGVkX1+r/YSe+2AafmlH+fLkrfUoioilEJ3qay0=

    ... so it's very easy to get a plain text representation of the hash and you don't need to deal with raw binary output. But you still need to manipulate it as what it is, plain text:

    $("#encodedText").text(text);