C# RSA加解密与验签,AES加解密,以及与JAVA平台的密文加解密

前言:

  RSA算法是利用公钥与密钥对数据进行加密验证的一种算法。一般是拿私钥对数据进行签名,公钥发给友商,将数据及签名一同发给友商,友商利用公钥对签名进行验证。也可以使用公钥对数据加密,然后用私钥对数据进行解密。

  .Net平台生成的RSA公私钥是xml格式的,java平台下一般是使用der或者pem格式的公私钥,pem格式就是比der格式多了-----BEGIN PUBLIC KEY-----开头及结尾。

  .Net平台要使用der/pem公私钥要先转换成xml格式,这需要用到 BouncyCastle.Crypto 这个开源dll,网上已经很多例子。也可以用该dll将.Net生成的公私钥转换成Java平台使用的公私钥。

   AES加解密的数据也能在.Net平台和Java平台下互相加解密。

以下.net代码加密的数据皆能在java环境中验证或解密,反之亦然。

---------------------------------------------------------------------------------------------------

     /// <summary>
        /// Xml转换成Der,传入公钥文件格式
        /// </summary>
        /// <param name="publickey"></param>
        /// <returns></returns>
        private byte[] RSAPublicKeytoJava(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 serializedPublicBytes;
        }
     /// <summary>
        /// Xml转换成Der,传入私钥文件格式
        /// </summary>
        /// <param name="privateKey"></param>
        /// <returns></returns>
        private byte[] RSAPrivateKeytoJava(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 privateParam = new RsaPrivateCrtKeyParameters(m, exp, d, p, q, dp, dq, qinv);

            var publicKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateParam);
            byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();
            return serializedPublicBytes;
        }
     /// <summary>
        /// rsa公钥加密
        /// </summary>
        /// <param name="privateKeyfile"></param>
        /// <param name="text"></param>
        /// <returns></returns>
        private string RsaEncry(string privateKeyfile, string text)
        {
            var pubKey = File.ReadAllText(this.pubPath);

            var rsa = new RSACryptoServiceProvider(rsaSize);
            rsa.FromXmlString(pubKey);

            var bytesToEncrypt = Encoding.Unicode.GetBytes(text);
            var encrypt = rsa.Encrypt(bytesToEncrypt, false);
            return Convert.ToBase64String(encrypt);
        }
    /// <summary>
        /// RSA私钥解密
        /// </summary>
        /// <param name="privateKey">私钥文件</param>
        /// <param name="text">待解密字符串</param>
        /// <returns></returns>
        private string RsaDecry(string privateKey,string text)
        { 
            var provider = new RSACryptoServiceProvider(this.rsaSize);
            provider.FromXmlString(privateKey);
            var bytesEncrypted = Convert.FromBase64String(text);
            var bytesPlainText = provider.Decrypt(bytesEncrypted, false);
           return Encoding.Unicode.GetString(bytesPlainText);
        }
    /// <summary>
        /// RSA签名
        /// </summary>
        /// <param name="text">待加密文本</param>
        /// <param name="privateKey">私钥</param>
        /// <returns></returns>
        private string RsaSign(string text, string privateKey)
        {
            var bytesToEncrypt = Encoding.UTF8.GetBytes(text);
            var rsa = new RSACryptoServiceProvider();
            rsa.FromXmlString(privateKey);
            var sha = SHA256.Create();
            var encrypt = rsa.SignData(bytesToEncrypt, sha);
            return Convert.ToBase64String(encrypt);
        }
  /// <summary>
        /// rsa验证签名
        /// </summary>
        /// <param name="txt">明文</param>
        /// <param name="sign">签名串</param>
        /// <param name="pubKey">公钥</param>
        /// <returns></returns>
        private bool RsaVerifyData(string txt, string sign, string pubKey)
        {
            var soures = Encoding.UTF8.GetBytes(txt);
            var bytes = Convert.FromBase64String(sign);

            var rsa = new RSACryptoServiceProvider(rsaSize);
            rsa.FromXmlString(pubKey);
            SHA256 sha = SHA256.Create();

            return rsa.VerifyData(soures, sha, bytes);
        }
 /// <summary>
        /// AES加密
        /// </summary>
        /// <param name="text">加密字符串</param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        private string AESEncry(string text, string key, string iv)
        {
            var bytes = Encoding.UTF8.GetBytes(text);
            var keyBytes = new byte[16];
            var pwkBytes = Encoding.UTF8.GetBytes(key);
            //注意这段代码,很重要,没有则java验证不通过
            var len = pwkBytes.Length;
            if (len > keyBytes.Length)
                len = keyBytes.Length;

            Array.Copy(pwkBytes, keyBytes, len);
            var rm = new RijndaelManaged
            {
                Key = keyBytes,
                Mode = CipherMode.CBC,
                IV = Encoding.UTF8.GetBytes(iv),
                Padding = PaddingMode.PKCS7,
            };
            var tramsform = rm.CreateEncryptor();
            var rst = tramsform.TransformFinalBlock(bytes, 0, bytes.Length);
            return Convert.ToBase64String(rst);
        }
        /// <summary>
        /// AES解密
        /// </summary>
        /// <param name="text">解密字符串</param>
        /// <param name="key"></param>
        /// <param name="iv"></param>
        /// <returns></returns>
        private string AesDecry(string text, string key, string iv)
        {
            var bytes = Convert.FromBase64String(text);

            var keyBytes = new byte[16];
            var pwkBytes = Encoding.UTF8.GetBytes(key);
            var len = pwkBytes.Length;
            if (len > keyBytes.Length)
                len = keyBytes.Length;
            Array.Copy(pwkBytes, keyBytes, len);

            var rm = new RijndaelManaged()
            {
                Key = keyBytes,
                Mode = CipherMode.CBC,
                IV = Encoding.UTF8.GetBytes(iv),
                Padding = PaddingMode.PKCS7
            };
            var transform = rm.CreateDecryptor();
            var rst = transform.TransformFinalBlock(bytes, 0, bytes.Length);
            return Encoding.UTF8.GetString(rst);
        }

 这有一篇数字证书的原理文章写得比较清楚:数字证书原理(ssl,https)

原文地址:https://www.cnblogs.com/jidanfan/p/8813267.html