.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();
        }

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/946283.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

elasticsearch-java客户端jar包中各模块的应用梳理

最近使用elasticsearch-java客户端实现对elasticsearch服务的Api请求&#xff0c;现对elasticsearch-java客户端jar包中各模块的应用做个梳理。主要是对co.elastic.clients.elasticsearch路径下的各子包的简单说明。使用的版本为&#xff1a;co.elastic.clients:elasticsearch-…

119.【C语言】数据结构之快速排序(调用库函数)

目录 1.C语言快速排序的库函数 1.使用qsort函数前先包含头文件 2.qsort的四个参数 3.qsort函数使用 对int类型的数据排序 运行结果 对char类型的数据排序 运行结果 对浮点型数据排序 运行结果 2.题外话:函数名的本质 1.C语言快速排序的库函数 cplusplus网的介绍 ht…

JVM实战—G1垃圾回收器的原理和调优

1.G1垃圾回收器的工作原理 (1)ParNew CMS的组合有哪些痛点 Stop the World是最大的问题。无论是新生代GC还是老年代GC&#xff0c;都会或多或少产生STW现象&#xff0c;这对系统的运行是有一定影响的。 所以JVM对垃圾回收器的优化&#xff0c;都是朝减少STW的目标去做的。在这…

HuatuoGPT-o1:基于40K可验证医学问题的两阶段复杂推理增强框架,通过验证器引导和强化学习提升医学模型的推理能力

HuatuoGPT-o1&#xff1a;基于40K可验证医学问题的两阶段复杂推理增强框架&#xff0c;通过验证器引导和强化学习提升医学模型的推理能力 论文大纲理解1. 确认目标2. 分析过程3. 实现步骤4. 效果展示 解法拆解全流程提问俩阶段详细分析 论文&#xff1a;HuatuoGPT-o1, Towards …

HTML——45.单元格合并

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>表格</title></head><body><!--合并单元格&#xff1a;1.在代码中找到要合并的单元格2.在要合并的所有单元格中&#xff0c;保留要合并的第一个单元格…

electron在arm64架构交叉编译遇到libnotify/notify.h文件找不到错误记录

问题描述 在按照官方文档进行arm64下electron编译时出现下面的错误&#xff0c;编译环境为ubuntun22.04.5。 问题分析 由于当前目标架构是arm64&#xff0c;所以从上图可知sysroot为build/linux/debian_bullseye_arm64-sysroot&#xff0c;进入到该目录下查看libnotify的头文…

我的创作纪念日与2024年年报

我的创作纪念日 机缘 原来是你&#xff01; 收获 在创作的过程中都有哪些收获 获得了14668粉丝的关注。获得了正向或者反向的反馈&#xff1a;1万多赞、426评论、140多万阅读量等。认识和哪些志同道合的领域同行&#xff1a;有且再寻觅。 日常 &#x1f3e0;个人主页&…

点击锁定按钮,锁定按钮要变成解锁按钮,然后状态要从待绑定变成 已锁定(升级版)

文章目录 1、updateInviteCodeStatus2、handleLock3、InviteCodeController4、InviteCodeService5、CrudRepository 点击锁定按钮&#xff0c;锁定按钮要变成解锁按钮&#xff0c;然后状态要从待绑定变成 已锁定&#xff1a;https://blog.csdn.net/m0_65152767/article/details…

使用npm包的工程如何引入mapboxgl-enhance/maplibre-gl-enhance扩展包

作者&#xff1a;刘大 前言 在使用iClient for MapboxGL/MapLibreGL项目开发中&#xff0c;往往会对接非EPSG:3857坐标系的地图&#xff0c;由于默认不支持&#xff0c;因此需引入mapboxgl-enhance/maplibre-gl-enhance扩展包。 在使用Vue等其他框架&#xff0c;通过npm包下载…

[2474].第04节:Activiti官方画流程图方式

我的后端学习大纲 Activiti大纲 1.安装位置&#xff1a; 2.启动&#xff1a;

UnityRenderStreaming使用记录(三)

测试UnityRenderStreaming在Ubuntu24.04.1LTS上的表现 先放上运行图操作系统 Ubuntu24.04.1LTSUnity测试工程环境相关修改遇到的问题 先放上运行图 操作系统 Ubuntu24.04.1LTS 系统下载地址 https://cn.ubuntu.com/download/desktop安装UnityHub https://blog.csdn.net/AWNUXC…

电脑主机后置音频插孔无声?还得Realtek高清晰音频管理器调教

0 缘起 一台联想电脑&#xff0c;使用Windows 10 专业版32位&#xff0c;电脑主机后置音频插孔一直没有声音&#xff0c;所以音箱是接在机箱前面版的前置音频插孔上的。 一天不小心捱到了音箱的音频线&#xff0c;音频线头断在音频插孔里面了&#xff0c;前置音频插孔因此用不…

【项目】智能BI洞察引擎 测试报告

目录 一、项目背景BI介绍问题分析项目背景 二、项目功能三、功能测试1、登录测试测试用例测试结果 2、注册测试测试用例测试结果出现的bug 3、上传文件测试测试用例测试结果 4、AI生成图表测试测试用例测试结果 5、分析数据页面测试&#xff08;异步&#xff09;测试用例测试结…

年会头投票小游戏

原型预览 源码 https://github.com/open-frame/vote 原型源文件 https://download.csdn.net/download/qq_42618566/90206788

活动预告 |【Part1】Microsoft Azure 在线技术公开课:基础知识

课程介绍 参加“Azure 在线技术公开课&#xff1a;基础知识”活动&#xff0c;培养有助于创造新的技术可能性的技能并探索基础云概念。参加我们举办的本次免费培训活动&#xff0c;扩充自身的云模型和云服务类型知识。你还可以查看以计算、网络和存储为核心的 Azure 服务。 活…

springboot499基于javaweb的城乡居民基本医疗信息管理系统(论文+源码)_kaic

摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到了互联网时代才发现能补上自古…

Java高级

1.反射 每个类都有一个唯一的类对象&#xff0c;该对象是 java.lang.Class 类型。【是 Java 类的元数据&#xff08;metadata&#xff09;对象&#xff0c;包含了该类的结构信息和其他相关数据】 获取类对象 1.什么是类对象 public class Daughter extends Parent{ …

HarmonyOS NEXT 实战之元服务:静态案例效果---我的热门应用服务

背景&#xff1a; 前几篇学习了元服务&#xff0c;后面几期就让我们开发简单的元服务吧&#xff0c;里面丰富的内容大家自己加&#xff0c;本期案例 仅供参考 先上本期效果图 &#xff0c;里面图片自行替换 效果图1完整代码案例如下&#xff1a; Index import { authentica…

libvirt学习

文章目录 libvirt 简介节点、Hypervisor和域libvirt 安装和配置libvirt的XML配置文件libvirt APIMain libvirt APIsError handlingSpecial specific APIs 建立到Hypervisor的连接libvirt API使用编译libvirt工具virshvirt-clonevirt-dfvirt-imagevirt-installvirt-topvirt-what…

“进制转换”公式大集合

咱们都知道十进制是“逢10进1 ”&#xff0c;同理&#xff0c;N进制就是 “逢N进1”。进制其实就这么简单。它的麻烦之处在于各种进制之间的转换。 一、十进制整数转N进制 1&#xff0e;十进制转二进制 除2取余法&#xff1a;连续除以2&#xff0c;直到商为0&#xff0c;逆序…