Using CryptoJS to encrypt in JavaScript and decrypt in C#

10,703

I had to do something similar recently, here is a working version of what you were shooting for - this encrypts a string on on the server in C# with the AES provider from System.Security.Cryptography, then sends the encrypted text to the client where it decrypts it in JavaScript with the CryptoJS library:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Security.Cryptography" %>
<%@ Import Namespace="System.IO" %>

<script src="http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/aes.js"></script>
<script>
    window.onload = function (e) {
        var key = CryptoJS.enc.Base64.parse(document.getElementById('key').innerText);
        var iv = CryptoJS.enc.Base64.parse(document.getElementById('iv').innerText);
        var ciphertext = document.getElementById('ciphertext').innerText;
        var decrypted = CryptoJS.AES.decrypt(ciphertext, key, { iv: iv });

        document.getElementById('output').innerText = decrypted.toString(CryptoJS.enc.Utf8);
    }
</script>

<%
    string plaintext = "the quick brown fox jumped over the lazy dog";
    string ciphertext;
    string decryptedtext;

    UTF8Encoding utf8 = new UTF8Encoding();

    AesCryptoServiceProvider aes = new AesCryptoServiceProvider();

    using (ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV)) { 
        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
        byte[] bytes = utf8.GetBytes(plaintext);
        cs.Write(bytes, 0, bytes.Length);
        cs.FlushFinalBlock();
        ms.Position = 0;
        bytes = new byte[ms.Length];
        ms.Read(bytes, 0, bytes.Length);
        ciphertext = Convert.ToBase64String(bytes);
    }

    using (ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
    {
        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Write);
        byte[] bytes = Convert.FromBase64String(ciphertext);
        cs.Write(bytes, 0, bytes.Length);
        cs.FlushFinalBlock();
        ms.Position = 0;
        bytes = new byte[ms.Length];
        ms.Read(bytes, 0, bytes.Length);
        decryptedtext = utf8.GetString(bytes);
    }    
%>

<h1>Server-side in C# using System.Security.Cryptography</h1>
Key:<div id="key"><% Response.Write(Convert.ToBase64String(aes.Key)); %></div>
IV:<div id="iv"><% Response.Write(Convert.ToBase64String(aes.IV)); %></div>
Plain text:<div id="plaintext"><% Response.Write(plaintext); %></div>
Cipher text:<div id="ciphertext"><% Response.Write(ciphertext); %></div>
Decrypted text:<div id="decryptedtext"><% Response.Write(decryptedtext); %></div>

<h1>Client-side in JS using CryptoJS)</h1>
<div id="output"></div>
Share:
10,703
user1044169
Author by

user1044169

Updated on June 04, 2022

Comments

  • user1044169
    user1044169 almost 2 years

    I am trying to use CryptoJS to encrypt in JavaScript and decrypt in C#. Spent quite a bit of time trying to get both technologies to return the same output. Still, the output is different -- the encrypted string produced by CryptoJS is different from encrypted string produced by C#. What am I doing wrong? Thank you for your help.

       <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Test.aspx.cs" Inherits=".com.Test" %>
    <%@ Import Namespace="System.Security.Cryptography" %>
    <p id="output"></p>
    <script src="/Scripts/aes.js"></script>
    <script>
        var encrypted = CryptoJS.AES.encrypt(
            CryptoJS.enc.Utf8.parse("test"),
            CryptoJS.enc.Utf8.parse("607490BE-18CA-43D7-B11A-57E2621B0137"),
            {
                mode: CryptoJS.mode.CBC, 
                padding: CryptoJS.pad.Pkcs7,
                iv: CryptoJS.enc.Utf8.parse("2D59831C-78AC-4227-B3F3-CE656636C23E")
            });
        document.getElementById('output').innerText = encrypted.ciphertext.toString(CryptoJS.enc.Base64);
    </script>
    
    <%
        var encryptor = new AesCryptoServiceProvider
            {
                Key = Encoding.UTF8.GetBytes("607490BE-18CA-43D7-B11A-57E2621B0137").Take(32).ToArray(),
                IV = Encoding.UTF8.GetBytes("2D59831C-78AC-4227-B3F3-CE656636C23E").Take(16).ToArray(),
                Mode = CipherMode.CBC,
                Padding = PaddingMode.PKCS7
            }.CreateEncryptor();
        var dataToEncrypt = Encoding.UTF8.GetBytes("test");
        Response.Write(Convert.ToBase64String(encryptor.TransformFinalBlock(dataToEncrypt, 0, dataToEncrypt.Length)));
    %>