Javascript – RSA: Encrypt password in javascript but failed to decrypt that in C#

cencryptionjavascriptrsa

I want apply the RSA encryption to my project, but encountered some troubles:

  1. First, I have download the JavaScripts library from
    http://www.ohdave.com/rsa/ ,and add reference to my project;
  2. Second, I have define the RSA object and code to initialize that:

    internal RSACryptoServiceProvider Rsa
        {
            get
            {
                if (HttpContext.Cache["Rsa"] != null)
                {
                    RSACryptoServiceProvider encryptKeys = (RSACryptoServiceProvider)HttpContext.Cache["Rsa"];
                    return encryptKeys;
                }
                else
                {
                    return new RSACryptoServiceProvider(1024);
                }
            }
            set
            {
                HttpContext.Cache.Remove("Rsa");
                HttpContext.Cache.Insert("Rsa", value);
            }
        }
    public ActionResult SignUp()
        {
            this.Rsa = Security.GetRsa();
            RSAParameters param= this.Rsa.ExportParameters(true);
            //this will bind to view
            TempData["exponent"] = Util.BytesToHexString(param.Exponent);
            TempData["key"] = Util.BytesToHexString(param.Modulus);
    
    
        UserInfo user = new UserInfo();
        user.Birthday = DateTime.Now.Date;
        return View(user);
    }
    private RSACryptoServiceProvider GetRsa()
        {
            RSACryptoServiceProvider Rsa = new RSACryptoServiceProvider(1024);
            return Rsa;
        }
    

3.then, on JavaScript side , I have code, it encrypt the password user input and the bind it control:

var hash = document.getElementById("Pwd").value;
var exponent = document.getElementById("exponent").innerHTML;
var rsa_n = document.getElementById("key").innerHTML;
setMaxDigits(131);
var key = new RSAKeyPair(exponent, "", rsa_n);
hash = encryptedString(key, "111");

document.getElementById("Pwd").value = hash;
document.getElementById("Pwd2").value = hash;

document.getElementById("error").innerHTML = "";
document.getElementById("submit").click();

4.when user click submit, my C# code get the encrypted pwd string and try to decrypt it but failed with exception: bad data:

[HttpPost]
    public ActionResult SignUp(UserInfo user)
    {
        user.UserId = user.UserId.ToLower(); //ignore case
        user.UserGUID = Guid.NewGuid();
        user.CreatedDate = DateTime.Now;
        user.IsEnabled = false;

        user.Pwd = Convert.ToBase64String(Rsa.Decrypt(Util.HexStringToBytes(user.Pwd), false));//Exception:Rsa.Decrypt throw bad data exception

who do you know how to fix it? thank you in advance.

Best Answer

I had a very similar problem in that most of the JavaScript based RSA encryption solutions wasn't "compatible" with .NET's implementation.

Almost all the implementations I found online had one or both of the following items causing the incompatibility with .NET's implementation.

  • The byte order encoding in JavaScript is different to the byte order that .NET used. This is a biggie as for example a string is represented with a different order of bytes in JS than it is in .NET so you'll need to convert before encrypting and after decrypting. I believe it's enough to just reverse the byte order to match .NET, but don't quote me on that.

  • Padding was different: .NET uses OAEP padding by default for RSA so the JS implementation of RSA should support the same padding too. I believe OAEP padding is also called PKCS#1 v2.0 padding, but don't quote me on that either.

Aside: I found an amazing JS library, called JavaScript.NET (from jocys.com) that mirrors tons of the .NET BCL functionality, including the RSA implementation, such that I could even use similar classes, properties and methods. Have a look at this. I can confirm it works with .NET RSA implementation. Give it a go - here are some links for it:

Hth

Related Topic