import .net public xml key to javascript in RSA

拟墨画扇 提交于 2021-01-28 02:25:48

问题


I have public key in XML that created in C# the format is:

<Modulus>rYDd94biRAJ1P6j68xjARl......and so on</Modulus>
<Exponent>A**B</Exponent>

I want to create this key in Javascript, and encrypt string with it, how can I do it?

Thanks,


回答1:


After so many hours researching, testing, giving up, researching again, etc., for a solution on RSA interoperability for .NET and Javascript, I have found this library:

http://www.jocys.com/Common/JsClasses/Documents/

Their classes have the same working code as the RSACryptoServiceProvider on the server.

What you have to do:

  1. Download the source code from their Github : https://github.com/JocysCom/JsClasses/archive/master.zip

  2. Rename the files from *.debug.js to *.js. See the list of files below, on (3).

  3. Add the required files to your html page

     <script type="text/javascript" src="js/System.js"></script>
     <script type="text/javascript" src="js/System.IO.js"></script>
     <script type="text/javascript" src="js/System.Text.js"></script>
     <script type="text/javascript" src="js/System.Convert.js"></script>
     <script type="text/javascript" src="js/System.BigInt.js"></script>
     <script type="text/javascript" src="js/System.BitConverter.js"></script>
     <script type="text/javascript" src="js/System.Security.Cryptography.js"></script>
     <script type="text/javascript" src="js/System.Security.Cryptography.SHA1.js"></script>
     <script type="text/javascript" src="js/System.Security.Cryptography.HMACSHA1.js"></script>
     <script type="text/javascript" src="js/System.Security.Cryptography.RSA.js"></script>
    
  4. Add this javascript code to encrypt your text:

     function RsaEncrypt()
     {
         //a public key generated from their sample.
         //your should generate yours and stamp it here.
         var xmlParams =
         "<RSAKeyValue>" +
             "<Modulus>pxtmFnrGI6Sb8ziyY+NRUDuQ4b/ETw5WabQ4daFQqzsCEr/6J/LLBU/2D5mO5/Wu5U/Rya1E55aYFZeaZMNqAw==</Modulus>" +
             "<Exponent>AQAB</Exponent>" +
             "<P>2TsVXWPEvDIJv/gd2rX9k0UOyXuaYgoAchIH6vUicis=</P>" +
             "<Q>xO4+OYREQfqYRQK7y73+RaUG0IxobT0OQ0c+Ok2hc4k=</Q>" +
             "<DP>K7/xgpiIU9rECeyfnp/OjS14V+3T3vDivBaTj6eFI3c=</DP>" +
             "<DQ>K4N9ClZ4gp+tn6oP9t//XEIvtEsiE+kmyqTmUhmvMAk=</DQ>" +
             "<InverseQ>p7o4BOlKZQZ693R1ViZ66y5gTjUkNNTd2za7/1YGBCs=</InverseQ>" +
             "<D>XZqFVrYy4qhECruJgVZFp/GVuD5Y0gev88nVjl5r911QT+I8vgJSklTso7jTlpMtf2oe7UZ0WRWEtgPS3tZn4Q==</D>" +
         "</RSAKeyValue>";
         var rsa = new System.Security.Cryptography.RSACryptoServiceProvider();
         rsa.FromXmlString(xmlParams);
    
         // Encrypt
         var decryptedBytes = System.Text.Encoding.UTF8.GetBytes(text);
         var doOaepPadding = true;
         var encryptedBytes = rsa.Encrypt(decryptedBytes, doOaepPadding);
         var encryptedString = System.Convert.ToBase64String(encryptedBytes);
         return encryptedString;
     }
    

Look for documentation (link above) on how to generate the private and public keys. The code is quite the same as you would manually write .NET on server.

You can also check their test page




回答2:


Also you can save public key in PEM format in C#:

private static string ExportPublicKey(RSACryptoServiceProvider csp)
    {
        var parameters = csp.ExportParameters(false);
        using (var stream = new MemoryStream())
        {
            var writer = new BinaryWriter(stream);
            writer.Write((byte)0x30); // SEQUENCE
            using (var innerStream = new MemoryStream())
            {
                var innerWriter = new BinaryWriter(innerStream);
                EncodeIntegerBigEndian(innerWriter, new byte[] { 0x00 }); // Version
                EncodeIntegerBigEndian(innerWriter, parameters.Modulus);
                EncodeIntegerBigEndian(innerWriter, parameters.Exponent);
                EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.D
                EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.P
                EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.Q
                EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.DP
                EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.DQ
                EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.InverseQ
                var length = (int)innerStream.Length;
                EncodeLength(writer, length);
                writer.Write(innerStream.GetBuffer(), 0, length);
            }

            char[] base64 = Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length).ToCharArray();
            StringBuilder res = new StringBuilder();
            res.AppendLine("-----BEGIN RSA PUBLIC KEY-----");
            for (int i = 0; i < base64.Length; i += 64)
            {
                int l = Math.Min(64, base64.Length - i);
                for (int j = 0; j < l; j++) res.Append(base64[i + j]);
                res.AppendLine();
            }
            res.AppendLine("-----END RSA PUBLIC KEY-----");
            return res.ToString();
        }
    }

    private static void EncodeIntegerBigEndian(BinaryWriter stream, byte[] value, bool forceUnsigned = true)
    {
        stream.Write((byte)0x02); // INTEGER
        var prefixZeros = 0;
        for (var i = 0; i < value.Length; i++)
        {
            if (value[i] != 0) break;
            prefixZeros++;
        }
        if (value.Length - prefixZeros == 0)
        {
            EncodeLength(stream, 1);
            stream.Write((byte)0);
        }
        else
        {
            if (forceUnsigned && value[prefixZeros] > 0x7f)
            {
                // Add a prefix zero to force unsigned if the MSB is 1
                EncodeLength(stream, value.Length - prefixZeros + 1);
                stream.Write((byte)0);
            }
            else
            {
                EncodeLength(stream, value.Length - prefixZeros);
            }
            for (var i = prefixZeros; i < value.Length; i++)
            {
                stream.Write(value[i]);
            }
        }
    }

    private static void EncodeLength(BinaryWriter stream, int length)
    {
        if (length < 0) throw new ArgumentOutOfRangeException("length", "Length must be non-negative");
        if (length < 0x80)
        {
            // Short form
            stream.Write((byte)length);
        }
        else
        {
            // Long form
            var temp = length;
            var bytesRequired = 0;
            while (temp > 0)
            {
                temp >>= 8;
                bytesRequired++;
            }
            stream.Write((byte)(bytesRequired | 0x80));
            for (var i = bytesRequired - 1; i >= 0; i--)
            {
                stream.Write((byte)(length >> (8 * i) & 0xff));
            }
        }
    }


来源:https://stackoverflow.com/questions/14037204/import-net-public-xml-key-to-javascript-in-rsa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!