RSA JS与.net的合用

因为有前端加密后端解密的需求,所以就研究了一下。小生可能代码不够简洁各位大神就不要吐槽,欢迎指正。

先说所需要的组件:

前端:rsajs-------jsencrypt.js这个我试了几个版本1.*的试过。好像比2.*的好用。其原因就是2.0没有sign和verify方法。最后选择了3.0版本.

后端:Org.BouncyCastle;

Security.Cryptography;

key .因为是个纯html所以只有弄成xml保存了。

前端方法展示:

   
   
   

结果最后展示。 

C# 加密引用

using Org.BouncyCastle.Asn1.Pkcs;
using Org.BouncyCastle.Asn1.X509;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Pkcs;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Xml;

public static class RSAHelper
    {

        static byte[] AOutput;

        private static readonly string pubKey = System.Configuration.ConfigurationManager.AppSettings["pubKey"];
        private static readonly string priKey = System.Configuration.ConfigurationManager.AppSettings["priKey"];


        public static void RSAKey(out string privateKeys, out string publicKey)
        {
            System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            privateKeys = RSAPrivateKeyDotNet2Java(rsa.ToXmlString(true));
            publicKey = RSAPublicKeyDotNet2Java(rsa.ToXmlString(false));

        }
        public static string GetKeyFromContainer(string ContainerName, bool privatekey)
        {
            CspParameters cp = new CspParameters();
            cp.KeyContainerName = ContainerName;
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);
            return rsa.ToXmlString(privatekey);
        }

        #region 加密 解密

        ///


        /// 解密
        ///

        ///
        /// nix 719
        public static string Decrypt(string decryptString)
        {
            try
            {
                byte[] PlainTextBArray;
                byte[] DypherTextBArray;
                string Result;
                System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.FromXmlString(RSAPrivateKeyJava2DotNet(priKey));
                PlainTextBArray = Convert.FromBase64String(decryptString);
                DypherTextBArray = rsa.Decrypt(PlainTextBArray, false);
                Result = Encoding.UTF8.GetString(DypherTextBArray);
                return Result;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        ///


        /// 加密
        ///

        ///
        /// nix 719
        public static string Encrypt(string m_strEncryptString)
        {

            byte[] PlainTextBArray;
            byte[] CypherTextBArray;
            string Result;
            RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(RSAPublicKeyJava2DotNet(pubKey));
            PlainTextBArray = (new UnicodeEncoding()).GetBytes(m_strEncryptString);
            CypherTextBArray = rsa.Encrypt(PlainTextBArray, false);
            Result = Convert.ToBase64String(CypherTextBArray);
            return Result;


        }

        #endregion

        #region hash method
        ///


        /// 获取hash值
        ///

        ///
        /// nix 719
        public static byte[] GetHash(string content)
        {
            try
            {
                //FileStream objFile = File.OpenRead(filePath);
                byte[] data_Bytes = Encoding.UTF8.GetBytes(content);
                HashAlgorithm MD5 = HashAlgorithm.Create("MD5");
                byte[] Hashbyte = MD5.ComputeHash(data_Bytes);
                //objFile.Close();
                return Hashbyte;
            }
            catch
            {
                return null;
            }
            throw new NotImplementedException();
        }


        //获取文件hash
        public static byte[] GetFileHash(string filePath)
        {
            try
            {
                FileStream objFile = File.OpenRead(filePath);
                HashAlgorithm MD5 = HashAlgorithm.Create("MD5");
                byte[] Hashbyte = MD5.ComputeHash(objFile);
                objFile.Close();
                return Hashbyte;
            }
            catch
            {
                return null;
            }
        }

        //创建数字签名
        public static byte[] EncryptHash(string privateKey, byte[] hash_Bytes)
        {
            RSACryptoServiceProvider Rsa3 = new RSACryptoServiceProvider();
            Rsa3.FromXmlString(RSAPrivateKeyJava2DotNet(privateKey));

            RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(Rsa3);
            RSAFormatter.SetHashAlgorithm("MD5");

            return RSAFormatter.CreateSignature(hash_Bytes); ;
        }


        //验证数字签名
        public static bool DecryptHash(string publicKey, byte[] hash_byte, byte[] eSignature)
        {
            try
            {
                RSACryptoServiceProvider Rsa4 = new RSACryptoServiceProvider();
                Rsa4.FromXmlString(RSAPublicKeyJava2DotNet(publicKey));

                //bool bVerify = Rsa4.VerifyData(strData, "SHA1", AOutput);
                RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(Rsa4);
                RSADeformatter.SetHashAlgorithm("MD5");

                bool bVerify = RSADeformatter.VerifySignature(hash_byte, eSignature);

                if (bVerify)
                {
                    return true;
                }
                return false;
            }
            catch (CryptographicException e)
            {
                return false;
            }
        }
        // 将Byte[]转换成十六进制字符串
        public static string ConvertBytesToString(byte[] bytes)
        {
            string bytestring = string.Empty;
            if (bytes != null && bytes.Length > 0)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    bytestring += bytes[i].ToString("X") + " ";
                }
            }
            return bytestring;
        }

        #endregion

        #region 私有方法 pemToXml
        ///


        /// RSA私钥格式转换,java->.net
        ///

        /// java生成的RSA私钥
        ///
        private static string RSAPrivateKeyJava2DotNet(string privateKey)
        {
            RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey));

            return string.Format("{0}{1}

{2}

{3}{4}{5}{6}{7}",
                Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()),
                Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()));
        }

        ///


        /// RSA私钥格式转换,.net->java
        ///

        /// .net生成的私钥
        ///
        private static string RSAPrivateKeyDotNet2Java(string privateKey)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(privateKey);
            BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
            BigInteger exp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
            BigInteger d = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("D")[0].InnerText));
            BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("P")[0].InnerText));
            BigInteger q = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Q")[0].InnerText));
            BigInteger dp = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DP")[0].InnerText));
            BigInteger dq = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("DQ")[0].InnerText));
            BigInteger qinv = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("InverseQ")[0].InnerText));

            RsaPrivateCrtKeyParameters privateKeyParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);

            PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKeyParam);
            byte[] serializedPrivateBytes = privateKeyInfo.ToAsn1Object().GetEncoded();
            return Convert.ToBase64String(serializedPrivateBytes);
        }

        ///


        /// RSA公钥格式转换,java->.net
        ///

        /// java生成的公钥
        ///
        private static string RSAPublicKeyJava2DotNet(string publicKey)
        {
            RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey));
            return string.Format("{0}{1}",
                Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
                Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
        }

        ///


        /// RSA公钥格式转换,.net->java
        ///

        /// .net生成的公钥
        ///
        private static string RSAPublicKeyDotNet2Java(string publicKey)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(publicKey);
            BigInteger m = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
            BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));
            RsaKeyParameters pub = new RsaKeyParameters(false, m, p);

            SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);
            byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
            return Convert.ToBase64String(serializedPublicBytes);
        }

        #endregion

        #region sign verify
        public static string SignContent(string content)
        {
            return Encoding.UTF8.GetString(EncryptHash(priKey, GetHash(content)));
        }


        ///


        /// RSA签名
        ///

        /// 明文
        /// 私匙
        /// 密文
        public static string CreateSignature(string sSource)
        {
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                rsa.FromXmlString(RSAPrivateKeyJava2DotNet(priKey));

                RSAPKCS1SignatureFormatter sf = new RSAPKCS1SignatureFormatter(rsa);
                sf.SetHashAlgorithm("sha256");

                byte[] source = System.Text.Encoding.UTF8.GetBytes(sSource);

                SHA256Managed sha2 = new SHA256Managed();
                byte[] result = sha2.ComputeHash(source);
                byte[] signature = sf.CreateSignature(result);

                return Convert.ToBase64String(signature);
            }
        }

        public static string Sign(string content)
        {
            var signData = CreateSignature(content);
            StringBuilder sp = new StringBuilder();
            sp.Append("signData=" + signData);
            sp.Append(";" + "jsonData=" + content);
            byte[] s = Encoding.UTF8.GetBytes(sp.ToString());
            string sb = Convert.ToBase64String(s);
            return sb;
        }


        public static string Verify(string base64Content)
        {

            var buffer = Convert.FromBase64String(base64Content);
            string str = Encoding.UTF8.GetString(buffer);
            string[] s = str.Split(';');
            string result = "";
            string t = "";
            foreach (var item in s)
            {
                if (item.Contains("signData"))
                {
                    result = item.Replace("signData=", string.Empty);
                }
                else
                {
                    t = item.Replace("jsonData=", string.Empty);
                }
            }
            if (VerifySignature(result, t))
            {
                return result;
            }
            else
            {
                return t;
            }
        }


        


        ///


        /// RSA签名验证
        ///

        /// 密文
        /// 需要比较的明文字符串
        /// 公匙
        /// 是否相同
        private static bool VerifySignature(string sEncryptSource, string sCompareString)
        {
            try
            {
                using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
                {
                    rsa.FromXmlString(RSAPublicKeyJava2DotNet(pubKey));

                    RSAPKCS1SignatureDeformatter df = new RSAPKCS1SignatureDeformatter(rsa);
                    df.SetHashAlgorithm("sha256");

                    byte[] signature = Convert.FromBase64String(sEncryptSource);

                    SHA256Managed sha2 = new SHA256Managed();
                    byte[] compareByte = sha2.ComputeHash(Encoding.UTF8.GetBytes(sCompareString));

                    return df.VerifySignature(compareByte, signature);
                }
            }
            catch (Exception)
            {
                return false;
            }
        }

        #endregion
    }

 

RSAHelper方法综合了csdn里面很多。有些完全没办法完美。我也不清楚我这个是不是最好的,但是加密和解密能用。感觉可以了吧。Org组件自行百度.

        public object GetSign(string data)
        {
            var str = RSAHelper.Decrypt(data);
            SuppTransMethod model = new SuppTransMethod();
            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(str)))
            {
                DataContractJsonSerializer deseralizer = new DataContractJsonSerializer(typeof(SuppTransMethod));
                model = (SuppTransMethod)deseralizer.ReadObject(ms);
            }
            return model;
        }

 后端方法代码.

 

最后结果

RSA JS与.net的合用_第1张图片

RSA JS与.net的合用_第2张图片 

你可能感兴趣的:(RSA JS与.net的合用)