locked
Decode Encoded Javascript url, UserID, PassPhrase, Expiring Url, in Asp.net, c# RRS feed

  • Question

  • User1045460610 posted

    I have a javascript to encode a url and pass the UserID (which is HostID below), with a passphrase and expiring url. I can decode it with javascript. But when I try to decode it with c# the UserID doesn't return. How do I determine why the UserID isn't returning and how to decode that with c#?

    test url
    http://aspnet-test.parkernet.edu/instructorcourse.aspx/?q=U2FsdGVkX18NyH%2ByhnwNrLTqZluqLcmYhSubZRcDIAPbNethvKxpA%2BVBubQjWuBp7tDp3bKQvYHy8rUxa0C0oQ%3D%3D

    Javascript Encoding
    <button id="encode_link" onclick="encryptdemo()" type="button">Encode Demo</button>

    <br />
    Display hostid: <span id="display_hostid"></span>
    <br />
    Display now: <span id="display_now"></span>
    <br />
    Display key: <span id="display_key"></span>
    <br />
    Display url: <span id="display_url"></span>
    <br />
    <br />

    <p><a title="Attendance Instructor" href="https://attendance.parker.edu/instructorcourse.aspx?HostID=@@HostID" target="_blank" rel="noopener">Click here to set the check-in code for your class. Current Link</a></p>

    <button id="encode_link" onclick="encrypt()" type="button">Click here to set the check-in code for your class.New Button</button>

    <br />
    <button id="decode_link" onclick="decrypt()" type="button">Decode</button>

    Decrypt result: <span id="decrypt_result"></span>

    <span id='initialhostid' style='display:none;'>{{data}}</span>

    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
    <script type="text/javascript">
    var value = '';

    function encryptdemo(hostId) {
    if (value == ''){
    value = document.getElementById('initialhostid').innerHTML;
    document.getElementById('initialhostid').remove();
    }

    var now = new Date(),

    //value = document.getElementById('hostId').value + '|' + now.toISOString(),
    //value = '123456' + '|' + now.toISOString(),
    value = value + '|' + now.toISOString(), //value: "123456|2019-05-21T20:57:05.051Z"

    key = 'iaUdrdMy7H';

    var encrypted = CryptoJS.AES.encrypt(value, key); //encrypted = {init: ƒ, $super: {…}, ciphertext: init, key: {…}, iv: {…}, …}, value = "123456|2019-05-21T20:57:05.051Z", key = "iaUdrdMy7H"
    //location.href = '/?q=' + encodeURIComponent(encrypted.toString());
    //location.href = 'https://attendance.parker.edu/instructorcourse.aspx' + '/?q=' + encodeURIComponent(encrypted.toString());


    document.getElementById('display_hostid').innerText = value;
    document.getElementById('display_now').innerText = now;
    document.getElementById('display_key').innerText = key;
    document.getElementById('display_url').innerText = encrypted;
    }

    function encrypt(hostId) {
    if (value == ''){
    value = document.getElementById('initialhostid').innerHTML;
    document.getElementById('initialhostid').remove();
    }

    var now = new Date(),

    //value = document.getElementById('hostId').value + '|' + now.toISOString(),
    //value = '123456' + '|' + now.toISOString(),
    value = value + '|' + now.toISOString(),

    key = 'iaUdrdMy7H';

    var encrypted = CryptoJS.AES.encrypt(value, key);
    //location.href = '/?q=' + encodeURIComponent(encrypted.toString());
    location.href = 'https://attendance.parker.edu/instructorcourse.aspx' + '/?q=' + encodeURIComponent(encrypted.toString());
    //location.href = 'http://aspnet-test.parkernet.edu/instructorcourse.aspx' + '/?q=' + encodeURIComponent(encrypted.toString());

    document.getElementById('display_hostid').innerText = value;
    document.getElementById('display_now').innerText = now;
    document.getElementById('display_key').innerText = key;
    document.getElementById('display_url').innerText = encrypted;
    }

    function decrypt() {
    var params = new URLSearchParams(window.location.search),
    queryString = params.get('q'),
    key = 'iaUdrdMy7H';

    if (queryString) {
    var decrypted = CryptoJS.AES.decrypt(queryString, key).toString(CryptoJS.enc.Utf8),
    temp = decrypted.split('|'),
    hostId = temp[0],
    timestamp = new Date(temp[1]),
    expired = diff_minutes(new Date(), timestamp) > 30;
    document.getElementById('decrypt_result').innerText = 'Host ID was sent ' + hostId + ', Url ' + (expired ? 'expired' : 'not expired');
    }
    }

    function diff_minutes(dt2, dt1) {
    var diff = (dt2.getTime() - dt1.getTime()) / 1000;
    diff /= 60;
    return Math.abs(Math.round(diff));
    }
    </script>


    //hostid method worked, not encoded
    //var returnUrl = Request.Params["ReturnUrl"];
    //var hostID = Request.Params["HostID"];
    //if (string.IsNullOrWhiteSpace(hostID))
    //{
    // if (!string.IsNullOrWhiteSpace(returnUrl))
    // Response.Redirect(returnUrl);

    // throw new Exception("Variable \"HostID\" not found in query params");
    //}

    //encoded hostid method, hostid not returning
    string hostID = null;
    var q = Request.Params["q"];
    if (!string.IsNullOrWhiteSpace(q))
    hostID = EncryptionHelper.GetHostID(q, lifetime: TimeSpan.FromMinutes(30));

    var returnUrl = Request.Params["ReturnUrl"];
    if (string.IsNullOrWhiteSpace(hostID))
    {
    if (!string.IsNullOrWhiteSpace(returnUrl))
    Response.Redirect(returnUrl);

    throw new Exception("Variable \"HostID\" not found in query params");
    }


    EncryptionHelper.cs
    using System;
    using System.Configuration;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;

    public static class EncryptionHelper
    {
    public static TimeSpan DefaultLifetime = TimeSpan.FromMinutes(15);

    public static string GetHostID(string data, TimeSpan? lifetime = null)
    {
    lifetime = lifetime ?? DefaultLifetime;

    string decrypted = Decrypt(data);
    string[] raw = decrypted.Split('|');
    if (raw.Length < 2)
    throw new Exception("Invalid request. Unable to correctly decrypt data");

    DateTime createDate = DateTime.Parse(raw[1]);
    if (DateTime.Now - createDate > lifetime)
    throw new Exception("Request expired");

    return raw[0];
    }

    public static string Decrypt(string data)
    {
    string result = null;

    string keyRaw = ConfigurationManager.AppSettings["AesKey"],
    vectorRaw = ConfigurationManager.AppSettings["AesVector"];

    if (string.IsNullOrWhiteSpace(keyRaw) || string.IsNullOrWhiteSpace(vectorRaw))
    throw new Exception("Web.config doesn't contain AppSettings.AesKey or AppSettings.AesVector");

    byte[] key = Convert.FromBase64String(keyRaw),
    vector = Convert.FromBase64String(vectorRaw),
    buffer = Convert.FromBase64String(data);

    using (var aes = Aes.Create())
    {
    using (var decryptor = aes.CreateDecryptor(key, vector))
    {
    using (var ms = new MemoryStream(buffer))
    {
    using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
    {
    using (var reader = new StreamReader(cs))
    result = reader.ReadToEnd();
    }
    }
    }
    }

    return result;
    }

    public static string Encrypt(string data)
    {
    string result = null;

    string keyRaw = ConfigurationManager.AppSettings["AesKey"],
    vectorRaw = ConfigurationManager.AppSettings["AesVector"];

    if (string.IsNullOrWhiteSpace(keyRaw) /*|| string.IsNullOrWhiteSpace(vectorRaw)*/)
    throw new Exception("Web.config doesn't contain AppSettings.AesKey or AppSettings.AesVector");

    byte[] key = Convert.FromBase64String(keyRaw),
    vector = Convert.FromBase64String(vectorRaw);

    using (var aes = Aes.Create())
    {
    using (var encryptor = aes.CreateEncryptor(key, vector))
    {
    using (var ms = new MemoryStream())
    {
    using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
    {
    using (var writer = new StreamWriter(cs))
    writer.Write(data);
    }

    result = Convert.ToBase64String(ms.ToArray());
    }
    }
    }

    return result;
    }
    }

    Wednesday, June 5, 2019 4:17 PM

All replies

  • User839733648 posted

    Hi Tom4IT,

    According to your description, I'm sorry that I could not reproduce your issue successfully.

    string keyRaw = ConfigurationManager.AppSettings["AesKey"],
    vectorRaw = ConfigurationManager.AppSettings["AesVector"];

    I'd like to ask about the two keys.

    Since not clear about the values, I could not reproduce the issue.

    I guess that the AesKey is meant to be the key = 'iaUdrdMy7H', right?

    But I have no idea about the value of AesVector , if possible, please provide more details so that it will be easier to help with you.

    Best Regards,

    Jenifer

    Thursday, June 6, 2019 9:33 AM
  • User753101303 posted

    Hi,

    It's unclear if you have a problem on just the user id or on the whole encrypted value. Or do you mean you have an exception? Always tell what happens when your code runs rather than something such as "the user id doesn't return". If needed use F12 in your browser and the VS debugger to see what actually happens. 

    The problem is that when reading code you can often see multiple possible problems that could happen and you still don't know which one actually happens.

    You could also do that in multiple steps for example encrypt a value on both sides and see if you have the same result. For example I suspect the key could use utf8 on one side and unicode on the other side (as one side side you start from a string and on the other side you use a base64 value but I'm not sure how you created this value from the key). And so I could keep reading the code and fiinding other possible issues such as exception and still wonder as you basically just told that "it doesn't work".

    So clarify what happens. If the full decrypted string is wrong I suspect it could be a key issue.

    Thursday, June 6, 2019 9:47 AM