当前位置: 首页 > article >正文

.Net加密与Java互通

.Net加密与Java互通


文章目录

  • .Net加密与Java互通
  • 前言
  • RSA
    • 生成私钥和公钥
    • .net加密出数据传给Java端
      • 采用java方给出的公钥进行加密
      • 采用java方给出的私钥进行解密
    • .net 解密来自Java端的数据
  • AES
    • 带有向量的AES加密
    • 带有向量的AES解密
    • 无向量AES加密
    • 无向量AES解密
  • SM2(国密)
    • SM2加密
    • Sm2解密
    • 生成密钥串
  • SM3加密
  • MD5加密
  • Base64
    • Base64加密
    • Base64解密
  • DES
    • DES加密
    • DES解密
  • SHA1
  • 总结


前言

在接口对接过程中我们常常会遇到需要加密和签名等情况,像经典的RSA,AES,SM2,SM3,各个语言之间的加密都有些小差异,接下来我就总结一下我做.net开发中与java接口对接时发现的差异与解决办法。


提示:以下是本篇文章正文内容,下面案例可供参考

RSA

这里我们需要引用 Portable.BouncyCastle 包
在这里插入图片描述
总所周知RSA加密是对称加密也就是说在进行加密和解密过程中会用到公钥私钥一般来说,我们都是将私钥留下,将公钥送给对方,当对方拿到我们的公钥之后,他们传输给我们数据的时候需要用公钥进行加密,我方接收到信息之后,再用我们留下的这个私钥进行解密。大概流程如下
在这里插入图片描述
再此次讨论中,我们把A方设定为.net后台,B方设定为java

这里的重点是他们之间的转换方法


        /// <summary>
        /// Java转.net格式(公钥)
        /// </summary>
        /// <param name="JavaPublicKey">Java格式公钥</param>
        /// <returns></returns>
        public static string RSAPublicKeyJava2DotNet(string JavaPublicKey)
        {
            RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(JavaPublicKey));
            return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
               Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
               Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
        }

        /// <summary>
        /// .NET格式转Java格式(公钥)
        /// </summary>
        /// <param name="cPublicKey">c#的.net格式公钥</param>
        /// <returns></returns>
        public static string RSAPublicKeyDotNet2Java(string cPublicKey)
        {
            XmlDocument doc = new XmlDocument(); doc.LoadXml(cPublicKey);
            BigInteger m = new Org.BouncyCastle.Math.BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));
            BigInteger p = new Org.BouncyCastle.Math.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);
        }
        /// <summary>
        /// java格式转c#(私钥)
        /// </summary>
        /// <param name="JavaPrivateKey">.java私钥</param>
        /// <returns></returns>
        public static string RSAPrivateKeyJava2DotNet(string JavaPrivateKey)
        {
            RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(JavaPrivateKey));
            return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
                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()));
        }

        /// <summary>
        /// .net格式转Java(私钥)
        /// </summary>
        /// <param name="cPrivateKey">.net私钥</param>
        /// <returns></returns>
        public static string RSAPrivateKeyDotNet2Java(string cPrivateKey)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(cPrivateKey);
            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);
        }


生成私钥和公钥

这里展示的是.net的密钥生成方法

  /// <summary>
      /// 生成密钥
      /// <param name="privateKey">私钥</param>
      /// <param name="publicKey">公钥</param>
      /// <param name="keySize">密钥长度:512,1024,2048,4096,8192</param>
      /// </summary>
      public static void Generator(out string privateKey, out string publicKey, int keySize = 1024)
      {
          RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(keySize);
          privateKey = rsa.ToXmlString(true); //将RSA算法的私钥导出到字符串PrivateKey中 参数为true表示导出私钥 true 表示同时包含 RSA 公钥和私钥;false 表示仅包含公钥。
          publicKey = rsa.ToXmlString(false); //将RSA算法的公钥导出到字符串PublicKey中 参数为false表示不导出私钥 true 表示同时包含 RSA 公钥和私钥;false 表示仅包含公钥。
      }
      

.net加密出数据传给Java端

采用java方给出的公钥进行加密

    public static string RSAEncryptByJavaPublicKey(string javaPublicKey, string data)
    {
        string xml = Pem2XmlPublic(javaPublicKey);
        RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
        rsa.FromXmlString(xml);
        // 加密
        using (SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider())
        {
            byte[] dataToEncrypt = Encoding.UTF8.GetBytes(data);
            byte[] digest = sha1.ComputeHash(dataToEncrypt);

            // 使用RSA的OAEP填充进行加密
            return Convert.ToBase64String(rsa.Encrypt(digest, false));
        }
    }
      /// <summary>
  /// RSA公钥格式转换,java->.net
  /// </summary>
  /// <param name="keyInfoData">java生成的公钥</param>
  /// <returns>.net公钥</returns>
  private static string RSAPublicKeyJava2DotNet(byte[] keyInfoData)
  {
      RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(keyInfoData);
      return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
          Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()),
          Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()));
  }

  private static string Pem2XmlPublic(string pemFileConent)
  {
      pemFileConent = pemFileConent.Replace("-----BEGIN PUBLIC KEY-----", "").Replace("-----END PUBLIC KEY-----", "").Replace("\n", "").Replace("\r", "");
      var data = Convert.FromBase64String(pemFileConent);
      return RSAPublicKeyJava2DotNet(data);
  }
    

采用java方给出的私钥进行解密

  /// <summary>  
  /// RSA解密 载入私钥,解密数据  
  /// </summary>  
  /// <param name="privateKey">私钥</param>  
  /// <param name="decryptstring">待解密的字符串</param>  
  public static string RsaDecrypt(string privateKey, string decryptstring)
  {
      using (var rsaProvider = new RSACryptoServiceProvider())
      {
          string key = RSAPrivateKeyJava2DotNet(privateKey);
          rsaProvider.FromXmlString(key); //载入私钥  
          var encryptedBytes = Convert.FromBase64String(decryptstring); //将传入的字符串转化为字节流  
                                                                        //var outputStream = new MemoryStream(encryptedBytes);
          var bufferSize = rsaProvider.KeySize / 8;
          var buffer = new byte[bufferSize];
          using (MemoryStream inputStream = new MemoryStream(encryptedBytes), outputStream = new MemoryStream())
          {
              while (true)
              {
                  int readSize = inputStream.Read(buffer, 0, bufferSize);
                  if (readSize <= 0)
                  {
                      break;
                  }
                  var temp = new byte[readSize];
                  Array.Copy(buffer, 0, temp, 0, readSize);
                  var decryptedBytes = rsaProvider.Decrypt(temp, false);
                  outputStream.Write(decryptedBytes, 0, decryptedBytes.Length);
              }
              return Encoding.UTF8.GetString(outputStream.ToArray()); //转化为字符串  
          }
      }
  }
  		/// <summary>
        /// .java格式私钥转c#使用的.net格式密钥
        /// </summary>
        /// <param name="JavaPrivateKey">.java密钥</param>
        /// <returns></returns>
        public static string RSAPrivateKeyJava2DotNet(string JavaPrivateKey)
        {
            RsaPrivateCrtKeyParameters privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(JavaPrivateKey));
            return string.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>",
                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()));
        }

.net 解密来自Java端的数据

注意这里解密的数据是java端采用.net提供的公钥进行加密后的数据。

//将之前生成的Base64字符串转为Xml格式
  private static string ToXmlPrivateKey(string privateKey)
        {
            RsaPrivateCrtKeyParameters privateKeyParams =
                PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)) as RsaPrivateCrtKeyParameters;
            using(RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                RSAParameters rsaParams = new RSAParameters()
                {
                    Modulus = privateKeyParams.Modulus.ToByteArrayUnsigned(),
                    Exponent = privateKeyParams.PublicExponent.ToByteArrayUnsigned(),
                    D = privateKeyParams.Exponent.ToByteArrayUnsigned(),
                    DP = privateKeyParams.DP.ToByteArrayUnsigned(),
                    DQ = privateKeyParams.DQ.ToByteArrayUnsigned(),
                    P = privateKeyParams.P.ToByteArrayUnsigned(),
                    Q = privateKeyParams.Q.ToByteArrayUnsigned(),
                    InverseQ = privateKeyParams.QInv.ToByteArrayUnsigned()
                };
                rsa.ImportParameters(rsaParams);
                return rsa.ToXmlString(true);
            }
        }
        
public string RSADecrypt(string PrivateKey, string decryptString)  
    {  
        try  
        {  
        string xmlPrivateKey=ToXmlPrivateKey(PrivateKey);
            byte[] PlainTextBArray;  
            byte[] DypherTextBArray;  
            string Result;  
            System.Security.Cryptography.RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();  
            rsa.FromXmlString(xmlPrivateKey);  
            PlainTextBArray = Convert.FromBase64String(decryptString);  
            DypherTextBArray = rsa.Decrypt(PlainTextBArray, false);  
            Result = (new UnicodeEncoding()).GetString(DypherTextBArray);  
            return Result;  
        }  
        catch (Exception ex)  
        {  
            throw ex;  
        }  
    }  

AES

带有向量的AES加密

    /// <summary>
    /// AES加密
    /// </summary>
    /// <param name="text">明文字符串</param>
    /// <param name="key">秘钥</param>
    /// <param name="iv">加密辅助向量</param>
    /// <returns>密文</returns>
    public static string AESEncrypt(string text, string key, string iv)
    {
        RijndaelManaged rijndaelCipher = new RijndaelManaged();
        rijndaelCipher.Mode = CipherMode.CBC;
        rijndaelCipher.Padding = PaddingMode.PKCS7;
        rijndaelCipher.KeySize = 128;
        rijndaelCipher.BlockSize = 128;
        byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(key);
        byte[] keyBytes = new byte[16];
        int len = pwdBytes.Length;
        if (len > keyBytes.Length) len = keyBytes.Length;
        System.Array.Copy(pwdBytes, keyBytes, len);
        rijndaelCipher.Key = keyBytes;
        byte[] ivBytes = System.Text.Encoding.UTF8.GetBytes(iv);
        rijndaelCipher.IV = ivBytes;
        ICryptoTransform transform = rijndaelCipher.CreateEncryptor();
        byte[] plainText = Encoding.UTF8.GetBytes(text);
        byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
        return Convert.ToBase64String(cipherBytes);
    }

带有向量的AES解密

/// <summary>
/// AES解密
/// </summary>
/// <param name="text">加密字符串</param>
/// <param name="key">秘钥</param>
/// <param name="iv">加密辅助向量</param>
/// <returns>明文</returns>
public static string AESDecrypt(string text, string key, string iv)
{
    try
    {
        ///空格替换为+ 否则解密会失败
        byte[] EncryptedBytes = Convert.FromBase64String(text.Replace(" ", "+"));

        //Setup the AES provider for decrypting.            
        AesCryptoServiceProvider aesProvider = new AesCryptoServiceProvider();
        aesProvider.Key = System.Text.Encoding.UTF8.GetBytes(key);
        aesProvider.IV = System.Text.Encoding.UTF8.GetBytes(iv);
        aesProvider.Padding = PaddingMode.None;
        aesProvider.Mode = CipherMode.CBC;

        ICryptoTransform cryptoTransform = aesProvider.CreateDecryptor(aesProvider.Key, aesProvider.IV);
        byte[] DecryptedBytes = cryptoTransform.TransformFinalBlock(EncryptedBytes, 0, EncryptedBytes.Length);
        string result = System.Text.Encoding.UTF8.GetString(DecryptedBytes).Replace("\0", "");
        return result;
    }
    catch(Exception ex)
    {
        return ex.Message;
    }
}

无向量AES加密

 /// <summary>
 /// AES加密(无向量)
 /// </summary>
 /// <param name="plainBytes">被加密的明文</param>
 /// <param name="key">密钥</param>
 /// <returns>密文</returns>
 public static string AESEncrypt(string Data, string Key,int KeySize=128)
 {
     MemoryStream mStream = new MemoryStream();
     RijndaelManaged aes = new RijndaelManaged();

     byte[] plainBytes = Encoding.UTF8.GetBytes(Data);
     Byte[] bKey = new Byte[32];
     Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);

     aes.Mode = CipherMode.ECB;
     aes.Padding = PaddingMode.PKCS7;
     aes.KeySize = KeySize;
     //aes.Key = _key;
     aes.Key = bKey;
     //aes.IV = _iV;

     CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateEncryptor(), CryptoStreamMode.Write);
     try
     {
         cryptoStream.Write(plainBytes, 0, plainBytes.Length);
         cryptoStream.FlushFinalBlock();
         return Convert.ToBase64String(mStream.ToArray());
     }
     finally
     {
         cryptoStream.Close();
         mStream.Close();
         aes.Clear();
     }
 }

无向量AES解密

 /// <summary>
 /// AES解密(无向量)
 /// </summary>
 /// <param name="encryptedBytes">被加密的明文</param>
 /// <param name="key">密钥</param>
 /// <returns>明文</returns>
 public static string AESDecrypt(string Data, string Key)
 {
     Byte[] encryptedBytes = Convert.FromBase64String(Data);
     Byte[] bKey = new Byte[32];
     Array.Copy(Encoding.UTF8.GetBytes(Key.PadRight(bKey.Length)), bKey, bKey.Length);

     MemoryStream mStream = new MemoryStream(encryptedBytes);
     //mStream.Write( encryptedBytes, 0, encryptedBytes.Length );
     //mStream.Seek( 0, SeekOrigin.Begin );
     RijndaelManaged aes = new RijndaelManaged();
     aes.Mode = CipherMode.ECB;
     aes.Padding = PaddingMode.PKCS7;
     aes.KeySize = 128;
     aes.Key = bKey;
     //aes.IV = _iV;
     CryptoStream cryptoStream = new CryptoStream(mStream, aes.CreateDecryptor(), CryptoStreamMode.Read);
     try
     {
         byte[] tmp = new byte[encryptedBytes.Length + 32];
         int len = cryptoStream.Read(tmp, 0, encryptedBytes.Length + 32);
         byte[] ret = new byte[len];
         Array.Copy(tmp, 0, ret, 0, len);
         return Encoding.UTF8.GetString(ret);
     }
     finally
     {
         cryptoStream.Close();
         mStream.Close();
         aes.Clear();
     }
 }

SM2(国密)

这里我要分享的也是java和.net之间互相传递过程中的细节问题
这里要用到:BouncyCastle.Crypto包
下载地址:https://www.bouncycastle.org/download/bouncy-castle-c/

以下是相关帮助类

using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Generators;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.Utilities;
using Org.BouncyCastle.Utilities.Encoders;
using Org.BouncyCastle.X509;
using System;
using System.Collections.Generic;
using System.IO;

namespace CommonUtils
{
    /**
     * 用BC的注意点:
     * 这个版本的BC对SM3withSM2的结果为asn1格式的r和s,如果需要直接拼接的r||s需要自己转换。下面rsAsn1ToPlainByteArray、rsPlainByteArrayToAsn1就在干这事。
     * 这个版本的BC对SM2的结果为C1||C2||C3,据说为旧标准,新标准为C1||C3||C2,用新标准的需要自己转换。下面(被注释掉的)changeC1C2C3ToC1C3C2、changeC1C3C2ToC1C2C3就在干这事。java版的高版本有加上C1C3C2,csharp版没准以后也会加,但目前还没有,java版的目前可以初始化时“ SM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);”。
     * 
     * 按要求国密算法仅允许使用加密机,本demo国密算法仅供学习使用,请不要用于生产用途。
     */
    public class GmUtil
    {

        //private static readonly ILog log = LogManager.GetLogger(typeof(GmUtil));

        private static X9ECParameters x9ECParameters = GMNamedCurves.GetByName("sm2p256v1");
        private static ECDomainParameters ecDomainParameters = new ECDomainParameters(x9ECParameters.Curve, x9ECParameters.G, x9ECParameters.N);

        /**
         *
         * @param msg
         * @param userId
         * @param privateKey
         * @return r||s,直接拼接byte数组的rs
         */
        public static byte[] SignSm3WithSm2(byte[] msg, byte[] userId, AsymmetricKeyParameter privateKey)
        {
            return RsAsn1ToPlainByteArray(SignSm3WithSm2Asn1Rs(msg, userId, privateKey));
        }

        /**
          * @param msg
          * @param userId
          * @param privateKey
          * @return rs in <b>asn1 format</b>
          */
        public static byte[] SignSm3WithSm2Asn1Rs(byte[] msg, byte[] userId, AsymmetricKeyParameter privateKey)
        {
            try
            {
                ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
                signer.Init(true, new ParametersWithID(privateKey, userId));
                signer.BlockUpdate(msg, 0, msg.Length);
                byte[] sig = signer.GenerateSignature();
                return sig;
            }
            catch (Exception e)
            {
                //log.Error("SignSm3WithSm2Asn1Rs error: " + e.Message, e);
                return null;
            }
        }

        /**
        *
        * @param msg
        * @param userId
        * @param rs r||s,直接拼接byte数组的rs
        * @param publicKey
        * @return
        */
        public static bool VerifySm3WithSm2(byte[] msg, byte[] userId, byte[] rs, AsymmetricKeyParameter publicKey)
        {
            if (rs == null || msg == null || userId == null) return false;
            if (rs.Length != RS_LEN * 2) return false;
            return VerifySm3WithSm2Asn1Rs(msg, userId, RsPlainByteArrayToAsn1(rs), publicKey);
        }

        /**
         *
         * @param msg
         * @param userId
         * @param rs in <b>asn1 format</b>
         * @param publicKey
         * @return
         */

        public static bool VerifySm3WithSm2Asn1Rs(byte[] msg, byte[] userId, byte[] sign, AsymmetricKeyParameter publicKey)
        {
            try
            {
                ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
                signer.Init(false, new ParametersWithID(publicKey, userId));
                signer.BlockUpdate(msg, 0, msg.Length);
                return signer.VerifySignature(sign);
            }
            catch (Exception e)
            {
                //log.Error("VerifySm3WithSm2Asn1Rs error: " + e.Message, e);
                return false;
            }
        }

        /**
         * bc加解密使用旧标c1||c2||c3,此方法在加密后调用,将结果转化为c1||c3||c2
         * @param c1c2c3
         * @return
         */
        private static byte[] ChangeC1C2C3ToC1C3C2(byte[] c1c2c3)
        {
            int c1Len = (x9ECParameters.Curve.FieldSize + 7) / 8 * 2 + 1; //sm2p256v1的这个固定65。可看GMNamedCurves、ECCurve代码。
            const int c3Len = 32; //new SM3Digest().getDigestSize();
            byte[] result = new byte[c1c2c3.Length];
            Buffer.BlockCopy(c1c2c3, 0, result, 0, c1Len); //c1
            Buffer.BlockCopy(c1c2c3, c1c2c3.Length - c3Len, result, c1Len, c3Len); //c3
            Buffer.BlockCopy(c1c2c3, c1Len, result, c1Len + c3Len, c1c2c3.Length - c1Len - c3Len); //c2
            return result;
        }


        /**
         * bc加解密使用旧标c1||c3||c2,此方法在解密前调用,将密文转化为c1||c2||c3再去解密
         * @param c1c3c2
         * @return
         */
        private static byte[] ChangeC1C3C2ToC1C2C3(byte[] c1c3c2)
        {
            int c1Len = (x9ECParameters.Curve.FieldSize + 7) / 8 * 2 + 1; //sm2p256v1的这个固定65。可看GMNamedCurves、ECCurve代码。
            const int c3Len = 32; //new SM3Digest().GetDigestSize();
            byte[] result = new byte[c1c3c2.Length];
            Buffer.BlockCopy(c1c3c2, 0, result, 0, c1Len); //c1: 0->65
            Buffer.BlockCopy(c1c3c2, c1Len + c3Len, result, c1Len, c1c3c2.Length - c1Len - c3Len); //c2
            Buffer.BlockCopy(c1c3c2, c1Len, result, c1c3c2.Length - c3Len, c3Len); //c3
            return result;
        }

        /**
         * c1||c3||c2
         * @param data
         * @param key
         * @return
         */
        public static byte[] Sm2Decrypt(byte[] data, AsymmetricKeyParameter key)
        {
            return Sm2DecryptOld(ChangeC1C3C2ToC1C2C3(data), key);
        }

        /**
         * c1||c3||c2
         * @param data
         * @param key
         * @return
         */

        public static byte[] Sm2Encrypt(byte[] data, AsymmetricKeyParameter key)
        {
            return ChangeC1C2C3ToC1C3C2(Sm2EncryptOld(data, key));
        }

        /**
         * c1||c2||c3
         * @param data
         * @param key
         * @return
         */
        public static byte[] Sm2EncryptOld(byte[] data, AsymmetricKeyParameter pubkey)
        {
            try
            {
                SM2Engine sm2Engine = new SM2Engine();
                sm2Engine.Init(true, new ParametersWithRandom(pubkey, new SecureRandom()));
                return sm2Engine.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                //log.Error("Sm2EncryptOld error: " + e.Message, e);
                return null;
            }
        }

        /**
         * c1||c2||c3
         * @param data
         * @param key
         * @return
         */
        public static byte[] Sm2DecryptOld(byte[] data, AsymmetricKeyParameter key)
        {
            try
            {
                SM2Engine sm2Engine = new SM2Engine();
                sm2Engine.Init(false, key);
                return sm2Engine.ProcessBlock(data, 0, data.Length);
            }
            catch (Exception e)
            {
                //log.Error("Sm2DecryptOld error: " + e.Message, e);
                return null;
            }
        }

        /**
         * @param bytes
         * @return
         */
        public static byte[] Sm3(byte[] bytes)
        {
            try
            {
                SM3Digest digest = new SM3Digest();
                digest.BlockUpdate(bytes, 0, bytes.Length);
                byte[] result = DigestUtilities.DoFinal(digest);
                return result;
            }
            catch (Exception e)
            {
                //log.Error("Sm3 error: " + e.Message, e);
                return null;
            }
        }

        private const int RS_LEN = 32;

        private static byte[] BigIntToFixexLengthBytes(BigInteger rOrS)
        {
            // for sm2p256v1, n is 00fffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123,
            // r and s are the result of mod n, so they should be less than n and have length<=32
            byte[] rs = rOrS.ToByteArray();
            if (rs.Length == RS_LEN) return rs;
            else if (rs.Length == RS_LEN + 1 && rs[0] == 0) return Arrays.CopyOfRange(rs, 1, RS_LEN + 1);
            else if (rs.Length < RS_LEN)
            {
                byte[] result = new byte[RS_LEN];
                Arrays.Fill(result, (byte)0);
                Buffer.BlockCopy(rs, 0, result, RS_LEN - rs.Length, rs.Length);
                return result;
            }
            else
            {
                throw new ArgumentException("err rs: " + Hex.ToHexString(rs));
            }
        }

        /**
         * BC的SM3withSM2签名得到的结果的rs是asn1格式的,这个方法转化成直接拼接r||s
         * @param rsDer rs in asn1 format
         * @return sign result in plain byte array
         */
        private static byte[] RsAsn1ToPlainByteArray(byte[] rsDer)
        {
            Asn1Sequence seq = Asn1Sequence.GetInstance(rsDer);
            byte[] r = BigIntToFixexLengthBytes(DerInteger.GetInstance(seq[0]).Value);
            byte[] s = BigIntToFixexLengthBytes(DerInteger.GetInstance(seq[1]).Value);
            byte[] result = new byte[RS_LEN * 2];
            Buffer.BlockCopy(r, 0, result, 0, r.Length);
            Buffer.BlockCopy(s, 0, result, RS_LEN, s.Length);
            return result;
        }

        /**
         * BC的SM3withSM2验签需要的rs是asn1格式的,这个方法将直接拼接r||s的字节数组转化成asn1格式
         * @param sign in plain byte array
         * @return rs result in asn1 format
         */
        private static byte[] RsPlainByteArrayToAsn1(byte[] sign)
        {
            if (sign.Length != RS_LEN * 2) throw new ArgumentException("err rs. ");
            BigInteger r = new BigInteger(1, Arrays.CopyOfRange(sign, 0, RS_LEN));
            BigInteger s = new BigInteger(1, Arrays.CopyOfRange(sign, RS_LEN, RS_LEN * 2));
            Asn1EncodableVector v = new Asn1EncodableVector();
            v.Add(new DerInteger(r));
            v.Add(new DerInteger(s));
            try
            {
                return new DerSequence(v).GetEncoded("DER");
            }
            catch (IOException e)
            {
                //log.Error("RsPlainByteArrayToAsn1 error: " + e.Message, e);
                return null;
            }
        }

        public static AsymmetricCipherKeyPair GenerateKeyPair()
        {
            try
            {
                ECKeyPairGenerator kpGen = new ECKeyPairGenerator();
                kpGen.Init(new ECKeyGenerationParameters(ecDomainParameters, new SecureRandom()));
                return kpGen.GenerateKeyPair();
            }
            catch (Exception e)
            {
                //log.Error("generateKeyPair error: " + e.Message, e);
                return null;
            }
        }

        public static ECPrivateKeyParameters GetPrivatekeyFromD(BigInteger d)
        {
            return new ECPrivateKeyParameters(d, ecDomainParameters);
        }

        public static ECPublicKeyParameters GetPublickeyFromXY(BigInteger x, BigInteger y)
        {
            return new ECPublicKeyParameters(x9ECParameters.Curve.CreatePoint(x, y), ecDomainParameters);
        }

        public static AsymmetricKeyParameter GetPublickeyFromX509File(FileInfo file)
        {

            FileStream fileStream = null;
            try
            {
                //file.DirectoryName + "\\" + file.Name
                fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read);
                X509Certificate certificate = new X509CertificateParser().ReadCertificate(fileStream);
                return certificate.GetPublicKey();
            }
            catch (Exception e)
            {
                //log.Error(file.Name + "读取失败,异常:" + e);
            }
            finally
            {
                if (fileStream != null)
                    fileStream.Close();
            }
            return null;
        }

        public class Sm2Cert
        {
            public AsymmetricKeyParameter privateKey;
            public AsymmetricKeyParameter publicKey;
            public String certId;
        }

        private static byte[] ToByteArray(int i)
        {
            byte[] byteArray = new byte[4];
            byteArray[0] = (byte)(i >> 24);
            byteArray[1] = (byte)((i & 0xFFFFFF) >> 16);
            byteArray[2] = (byte)((i & 0xFFFF) >> 8);
            byteArray[3] = (byte)(i & 0xFF);
            return byteArray;
        }

        /**
         * 字节数组拼接
         *
         * @param params
         * @return
         */
        private static byte[] Join(params byte[][] byteArrays)
        {
            List<byte> byteSource = new List<byte>();
            for (int i = 0; i < byteArrays.Length; i++)
            {
                byteSource.AddRange(byteArrays[i]);
            }
            byte[] data = byteSource.ToArray();
            return data;
        }

        /**
         * 密钥派生函数
         *
         * @param Z
         * @param klen
         *            生成klen字节数长度的密钥
         * @return
         */
        private static byte[] KDF(byte[] Z, int klen)
        {
            int ct = 1;
            int end = (int)Math.Ceiling(klen * 1.0 / 32);
            List<byte> byteSource = new List<byte>();
            try
            {
                for (int i = 1; i < end; i++)
                {
                    byteSource.AddRange(GmUtil.Sm3(Join(Z, ToByteArray(ct))));
                    ct++;
                }
                byte[] last = GmUtil.Sm3(Join(Z, ToByteArray(ct)));
                if (klen % 32 == 0)
                {
                    byteSource.AddRange(last);
                }
                else
                    byteSource.AddRange(Arrays.CopyOfRange(last, 0, klen % 32));
                return byteSource.ToArray();
            }
            catch (Exception e)
            {
                //log.Error("KDF error: " + e.Message, e);
            }
            return null;
        }

        public static byte[] Sm4DecryptCBC(byte[] keyBytes, byte[] cipher, byte[] iv, String algo)
        {
            if (keyBytes.Length != 16) throw new ArgumentException("err key length");
            if (cipher.Length % 16 != 0 && algo.Contains("NoPadding")) throw new ArgumentException("err data length");

            try
            {
                KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
                IBufferedCipher c = CipherUtilities.GetCipher(algo);
                if (iv == null) iv = ZeroIv(algo);
                c.Init(false, new ParametersWithIV(key, iv));
                return c.DoFinal(cipher);
            }
            catch (Exception e)
            {
                //log.Error("Sm4DecryptCBC error: " + e.Message, e);
                return null;
            }
        }


        public static byte[] Sm4EncryptCBC(byte[] keyBytes, byte[] plain, byte[] iv, String algo)
        {
            if (keyBytes.Length != 16) throw new ArgumentException("err key length");
            if (plain.Length % 16 != 0 && algo.Contains("NoPadding")) throw new ArgumentException("err data length");

            try
            {
                KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
                IBufferedCipher c = CipherUtilities.GetCipher(algo);
                if (iv == null) iv = ZeroIv(algo);
                c.Init(true, new ParametersWithIV(key, iv));
                return c.DoFinal(plain);
            }
            catch (Exception e)
            {
                //log.Error("Sm4EncryptCBC error: " + e.Message, e);
                return null;
            }
        }


        public static byte[] Sm4EncryptECB(byte[] keyBytes, byte[] plain, string algo)
        {
            if (keyBytes.Length != 16) throw new ArgumentException("err key length");
            //NoPadding 的情况下需要校验数据长度是16的倍数.
            if (plain.Length % 16 != 0 && algo.Contains("NoPadding")) throw new ArgumentException("err data length");

            try
            {
                KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
                IBufferedCipher c = CipherUtilities.GetCipher(algo);
                c.Init(true, key);
                return c.DoFinal(plain);
            }
            catch (Exception e)
            {
                //log.Error("Sm4EncryptECB error: " + e.Message, e);
                return null;
            }
        }

        public static byte[] Sm4DecryptECB(byte[] keyBytes, byte[] cipher, string algo)
        {
            if (keyBytes.Length != 16) throw new ArgumentException("err key length");
            if (cipher.Length % 16 != 0 && algo.Contains("NoPadding")) throw new ArgumentException("err data length");

            try
            {
                KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
                IBufferedCipher c = CipherUtilities.GetCipher(algo);
                c.Init(false, key);
                return c.DoFinal(cipher);
            }
            catch (Exception e)
            {
                //log.Error("Sm4DecryptECB error: " + e.Message, e);
                return null;
            }
        }

        public const String SM4_ECB_NOPADDING = "SM4/ECB/NoPadding";
        public const String SM4_CBC_NOPADDING = "SM4/CBC/NoPadding";
        public const String SM4_CBC_PKCS7PADDING = "SM4/CBC/PKCS7Padding";

        /**
         * cfca官网CSP沙箱导出的sm2文件
         * @param pem 二进制原文
         * @param pwd 密码
         * @return
         */
        public static Sm2Cert readSm2File(byte[] pem, String pwd)
        {

            Sm2Cert sm2Cert = new Sm2Cert();
            try
            {
                Asn1Sequence asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(pem);
                //            ASN1Integer asn1Integer = (ASN1Integer) asn1Sequence.getObjectAt(0); //version=1
                Asn1Sequence priSeq = (Asn1Sequence)asn1Sequence[1];//private key
                Asn1Sequence pubSeq = (Asn1Sequence)asn1Sequence[2];//public key and x509 cert

                //            ASN1ObjectIdentifier sm2DataOid = (ASN1ObjectIdentifier) priSeq.getObjectAt(0);
                //            ASN1ObjectIdentifier sm4AlgOid = (ASN1ObjectIdentifier) priSeq.getObjectAt(1);
                Asn1OctetString priKeyAsn1 = (Asn1OctetString)priSeq[2];
                byte[] key = KDF(System.Text.Encoding.UTF8.GetBytes(pwd), 32);
                byte[] priKeyD = Sm4DecryptCBC(Arrays.CopyOfRange(key, 16, 32),
                        priKeyAsn1.GetOctets(),
                        Arrays.CopyOfRange(key, 0, 16), SM4_CBC_PKCS7PADDING);
                sm2Cert.privateKey = GetPrivatekeyFromD(new BigInteger(1, priKeyD));
                //            log.Info(Hex.toHexString(priKeyD));

                //            ASN1ObjectIdentifier sm2DataOidPub = (ASN1ObjectIdentifier) pubSeq.getObjectAt(0);
                Asn1OctetString pubKeyX509 = (Asn1OctetString)pubSeq[1];
                X509Certificate x509 = (X509Certificate)new X509CertificateParser().ReadCertificate(pubKeyX509.GetOctets());
                sm2Cert.publicKey = x509.GetPublicKey();
                sm2Cert.certId = x509.SerialNumber.ToString(10); //这里转10进账,有啥其他进制要求的自己改改
                return sm2Cert;
            }
            catch (Exception e)
            {
                //log.Error("readSm2File error: " + e.Message, e);
                return null;
            }
        }

        /**
         *
         * @param cert
         * @return
         */
        public static Sm2Cert ReadSm2X509Cert(byte[] cert)
        {
            Sm2Cert sm2Cert = new Sm2Cert();
            try
            {

                X509Certificate x509 = new X509CertificateParser().ReadCertificate(cert);
                sm2Cert.publicKey = x509.GetPublicKey();
                sm2Cert.certId = x509.SerialNumber.ToString(10); //这里转10进账,有啥其他进制要求的自己改改
                return sm2Cert;
            }
            catch (Exception e)
            {
                //log.Error("ReadSm2X509Cert error: " + e.Message, e);
                return null;
            }
        }

        public static byte[] ZeroIv(String algo)
        {

            try
            {
                IBufferedCipher cipher = CipherUtilities.GetCipher(algo);
                int blockSize = cipher.GetBlockSize();
                byte[] iv = new byte[blockSize];
                Arrays.Fill(iv, (byte)0);
                return iv;
            }
            catch (Exception e)
            {
                //log.Error("ZeroIv error: " + e.Message, e);
                return null;
            }
        }
    }
}

SM2加密

注意:publicKey是一个全局变量,是java方提供给.net方的公钥
格式如下:
在这里插入图片描述

  /// <summary>
  /// SM2加密
  /// </summary>
  /// <param name="publicKey"></param>
  /// <param name="message"></param>
  /// <returns></returns>
  public string Encrypt(string message)
  {
      if (publicKey.Length == 130)
      {
          publicKey = publicKey.Substring(2, 128);
      }
      //公钥X,前64位
      String x = publicKey.Substring(0, 64);
      //公钥Y,后64位
      String y = publicKey.Substring(64);
      //获取公钥对象
      AsymmetricKeyParameter publicKey1 = GmUtil.GetPublickeyFromXY(new BigInteger(x, 16), new BigInteger(y, 16));
      byte[] digestByte = GmUtil.Sm2Encrypt(Encoding.UTF8.GetBytes(message), publicKey1);
      //如果对方要的是16进制字符串的话需要转换之后去除04之后直接返回newCipherText 就可以了。
       //string newCipherText = Hex.ToHexString(digestByte);
       //if (newCipherText.StartsWith("04"))
       //{
       //    newCipherText = newCipherText.Substring(2);
       //}
       //如果对方要的是base64字符串的话可以直接转换
      string   newCipherText = Convert.ToBase64String(digestByte);
       return newCipherText; 
  }

Sm2解密

这里的privateKey也是一个全局变量,是.net这边自己生成的一对密钥串(私钥和公钥一对一)中的私钥
格式如下:
在这里插入图片描述

 /// <summary>
 /// SM2解密
 /// </summary>
 /// <param name="privateKey"></param>
 /// <param name="message"></param>
 /// <returns></returns>
 public string Decrypt(string message)
 {
     BigInteger d = new BigInteger(privateKey, 16);
     AsymmetricKeyParameter bcecPrivateKey = CommonUtils.GmUtil.GetPrivatekeyFromD(d);
     string datastr = Base64ToHexString(message);
     if (!datastr.StartsWith("04"))
     {
         datastr = "04" + datastr;
     }
     byte[] byToDecrypt = Hex.Decode(datastr);
     byte[] byDecrypted = GmUtil.Sm2Decrypt(byToDecrypt, bcecPrivateKey);
     if (byDecrypted != null && byDecrypted.Length > 0)
     {
         string strDecrypted = Encoding.UTF8.GetString(byDecrypted);
         return strDecrypted;
     }
     else
     {
         return "解密失败!";
     }

 }

生成密钥串

  • 第一种方式:

这里是采用我上面贴出来的帮助类中的方法生成的公钥和私钥

   AsymmetricCipherKeyPair kp2 = GmUtil.GenerateKeyPair();
  AsymmetricKeyParameter publicKey2 = kp2.Public;
  AsymmetricKeyParameter privateKey2 = kp2.Private;

当然还有其他方法可以生成

  • 第二种方式:
  /// <summary>
  /// 密钥生成
  /// </summary>
  /// <returns></returns>
  public static (string, string) GenerateKeyPair()
  {
      X9ECParameters sm2Params = GMNamedCurves.GetByName("sm2p256v1");
      ECDomainParameters domainParams = new ECDomainParameters(sm2Params.Curve, sm2Params.G, sm2Params.N, sm2Params.H);

      ECKeyPairGenerator keyGen = new ECKeyPairGenerator();
      SecureRandom random = new SecureRandom();
      ECKeyGenerationParameters keyGenParam = new ECKeyGenerationParameters(domainParams, random);
      keyGen.Init(keyGenParam);

      AsymmetricCipherKeyPair keyPair = keyGen.GenerateKeyPair();
      ECPrivateKeyParameters privateKeyParams = (ECPrivateKeyParameters)keyPair.Private;
      ECPublicKeyParameters publicKeyParams = (ECPublicKeyParameters)keyPair.Public;
      string privateKeyHex = privateKeyParams.D.ToString(16);
      string publicKeyHex = Hex.ToHexString(publicKeyParams.Q.GetEncoded());
      return (privateKeyHex, publicKeyHex);
  }

SM3加密

 /// <summary>
 /// SM3生成加密
 /// </summary>
 /// <param name="input"></param>
 /// <returns></returns>
 public static string SM3Encrypt(string input)
 {
     byte[] dataBytes = Encoding.GetEncoding("UTF-8").GetBytes(input);
     SM3Digest sm3Digest = new SM3Digest();
     sm3Digest.BlockUpdate(dataBytes, 0, dataBytes.Length);
     byte[] ret = new byte[sm3Digest.GetDigestSize()];
     sm3Digest.DoFinal(ret, 0);
     return Hex.ToHexString(ret);
 }

MD5加密

 public string MD5Encrypt(string input)
        {
            if (string.IsNullOrEmpty(input)) input= "";
             MD5 md5Hash = MD5.Create();
            byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input)); 
            StringBuilder sBuilder = new StringBuilder(); 
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            } 
            return sBuilder.ToString(); 
        }

Base64

Base64加密

		/// <summary>
        /// Base64加密,采用utf8编码方式加密
        /// </summary>
        /// <param name="source">待加密的明文</param>
        /// <returns>加密后的字符串</returns>
        public static string Base64Encode(string source)
        {
            return Base64Encode(Encoding.UTF8, source);
        }

        /// <summary>
        /// Base64加密
        /// </summary>
        /// <param name="encodeType">加密采用的编码方式</param>
        /// <param name="source">待加密的明文</param>
        /// <returns></returns>
        public static string Base64Encode(Encoding encodeType, string source)
        {
            string encode = string.Empty;
            byte[] bytes = encodeType.GetBytes(source);
            try
            {
                encode = Convert.ToBase64String(bytes);
            }
            catch
            {
                encode = source;
            }
            return encode;
        } 

Base64解密

/// <summary>
        /// Base64解密,采用utf8编码方式解密
        /// </summary>
        /// <param name="result">待解密的密文</param>
        /// <returns>解密后的字符串</returns>
        public static string Base64Decode(string result)
        {
            return Base64Decode(Encoding.UTF8, result);
        }

        /// <summary>
        /// Base64解密
        /// </summary>
        /// <param name="encodeType">解密采用的编码方式,注意和加密时采用的方式一致</param>
        /// <param name="result">待解密的密文</param>
        /// <returns>解密后的字符串</returns>
        public static string Base64Decode(Encoding encodeType, string result)
        {
            string decode = string.Empty;
            byte[] bytes = Convert.FromBase64String(result);
            try
            {
                decode = encodeType.GetString(bytes);
            }
            catch
            {
                decode = result;
            }
            return decode;
        }  

DES

//默认密钥向量
        private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
        private static string DESKey = "CQYRZHXG"; 

DES加密

		/// <summary>
        /// <summary>
        /// 加密【可逆】
        /// </summary>
        /// <param name="Text">需要加密的字符串</param>
        /// <param name="DESKey">加密密钥,要求为8位</param>
        /// <returns></returns>
        public static string Encrypt(string Text)
        {
            return EncryptDES(Text, DESKey);
        }
        /// <summary> 
        /// 加密数据
        /// </summary> 
        /// <param name="Text"></param> 
        /// <param name="sKey"></param> 
        /// <returns></returns> 
        /// DES加密字符串
        /// </summary>
        /// <param name="encryptString">待加密的字符串</param>
        /// <param name="encryptKey">加密密钥,要求为8位</param>
        /// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
        public static string EncryptDES(string encryptString, string encryptKey)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
                byte[] rgbIV = Keys;
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Convert.ToBase64String(mStream.ToArray());
            }
            catch
            {
                return encryptString;
            }
        } 

DES解密

/// <summary>
        /// 解密
        /// </summary>
        /// <param name="Text">需要解密的字符串</param>
        /// <returns></returns>
        public static string Decrypt(string Text)
        {
            if (!string.IsNullOrEmpty(Text))
            {
                return DecryptDES(Text, DESKey);
            }
            else
            {
                return "";
            }
        }
        /// <summary>
        /// DES解密字符串
        /// </summary>
        /// <param name="decryptString">待解密的字符串</param>
        /// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
        /// <returns>解密成功返回解密后的字符串,失败返源串</returns>
        public static string DecryptDES(string decryptString, string decryptKey)
        {
            try
            {
                byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
                byte[] rgbIV = Keys;
                byte[] inputByteArray = Convert.FromBase64String(decryptString);
                DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }
            catch
            {
                return decryptString;
            }
        } 

SHA1

  • 第一种方法:
/// <summary>
      /// SHA1 加密,返回大写字符串
      /// </summary>
      /// <param name="content">需要加密字符串</param>
      /// <returns>返回40位UTF8 大写</returns>
      public static string SHA1(string content)
      {
          return SHA1(content, Encoding.UTF8);
      }
      /// <summary>
      /// SHA1 加密,返回大写字符串
      /// </summary>
      /// <param name="content">需要加密字符串</param>
      /// <param name="encode">指定加密编码</param>
      /// <returns>返回40位大写字符串</returns>
      private static string SHA1(string content, Encoding encode)
      {
          try
          {
              SHA1 sha1 = new SHA1CryptoServiceProvider();
              byte[] bytes_in = encode.GetBytes(content);
              byte[] bytes_out = sha1.ComputeHash(bytes_in);
              sha1.Dispose();
              string result = BitConverter.ToString(bytes_out);
              result = result.Replace("-", "");
              return result;
          }
          catch (Exception ex)
          {
              throw new Exception("SHA1加密出错:" + ex.Message);
          }
      }
  • 第二种方法:
  public string SHA1Encrypt(string Source_String)
        {
            byte[] StrRes = Encoding.Default.GetBytes(Source_String);
            HashAlgorithm iSHA = new SHA1CryptoServiceProvider();
            StrRes = iSHA.ComputeHash(StrRes);
            StringBuilder EnText = new StringBuilder();
            foreach (byte iByte in StrRes)
            {
                EnText.AppendFormat("{0:x2}", iByte);
            }
            return EnText.ToString();
        }

总结

以上就是常用的加密和解密方式。希望对大家有所帮助,对于加密和解密不用过多在意他们的计算公式和原理。咱们只管开发就好,过于追求真理只会延迟开发进度。


http://www.kler.cn/a/467313.html

相关文章:

  • 202-01-06 Unity 使用 Tip1 —— UnityHub 模块卸载重装
  • doris:基于 Arrow Flight SQL 的高速数据传输链路
  • ansible-性能优化
  • Vue3+Element Plus的表格分页实战
  • 为什么HTTP请求后面有时带一个sign参数(HTTP请求签名校验)
  • spring mvc源码学习笔记之六
  • Ubuntu静态IP地址
  • HTML——78. 图像地图
  • 【AWS SDK PHP】This operation requests `sigv4a` auth schemes 问题处理
  • 常见的 MySQL 性能问题
  • 框架Tensorflow2
  • 《Rust权威指南》学习笔记(四)
  • Elasticsearch:Lucene 2024 年回顾
  • 豆包 MarsCode 编程助手之Visual Studio Code快速开始教程
  • 【数据可视化-10】国防科技大学录取分数线可视化分析
  • SQL Server 数据库 忘记密码
  • 5.1 冒泡排序与选择排序
  • 对一个双向链表,从尾部遍历找到第一个值为x的点,将node p插入这个点之前,如果找不到,则插在末尾。使用C语言实现
  • Unity3D仿星露谷物语开发16之角色拾取道具
  • spark环境搭建
  • T-SQL语言的编程范式
  • 如何不修改模型参数来强化大语言模型 (LLM) 能力?
  • 【Unity笔记】如何把语言修改为简体中文?
  • 全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之循环结构(for循环语句)—(十)(求解数学中特殊的数)
  • windows终端conda activate命令行不显示环境名
  • 《Armv8-A virtualization》学习笔记