.Net加密与Java互通

news2025/1/7 7:02:25

.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.coloradmin.cn/o/2271427.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

西安电子科技大学初/复试笔试、面试、机试成绩占比

西安电子科技大学初/复试笔试、面试、机试成绩占比 01通信工程学院 02电子工程学院 03计算机科学与技术学院 04机电工程学院 06经济与管理学院 07数学与统计学院 08人文学院 09外国语学院 12生命科学与技术学院 13空间科学与技术学院 14先进材料与纳米科技学院 15网络与信息安…

服务器信息整理

文章目录 引言I BIOS时间Windows查看BIOS版本安装日期linux查看BIOS时间II 操作系统安装日期LinuxIII MAC 地址IV 设备序列号Linux 查看主板信息引言 信息内容:重点信息:用途、操作系统安装日期、设备序列化、IP、MAC地址、BIOS时间、系统 Linux查看工具:ifconfig、宝塔运维…

关于PINN进一步的探讨

pinn 是有监督、无监督、半监督&#xff1f; PINN&#xff08;Physics-Informed Neural Networks&#xff0c;物理信息神经网络&#xff09;通常被归类为一种有监督学习的方法。在PINN中&#xff0c;神经网络的训练过程不仅依赖于数据点&#xff08;例如实验观测数据&#xff0…

Linux-Ubuntu之I2C通信

Linux-Ubuntu之I2C通信 一&#xff0c;I2C通信原理1.写时序2.读时序 二&#xff0c;代码实现三&#xff0c;显示 一&#xff0c;I2C通信原理 使用I2C接口驱动AP3216C传感器&#xff0c;该传感器能实现两个效果&#xff0c;一个是感应光强&#xff0c;另一个是探测物体与传感器…

Trimble天宝X9三维扫描仪为建筑外墙检测提供了全新的解决方案【沪敖3D】

随着城市化进程的快速推进&#xff0c;城市高层建筑不断增多&#xff0c;对建筑质量的要求也在不断提高。建筑外墙检测&#xff0c;如平整度和垂直度检测&#xff0c;是衡量建筑质量的重要指标之一。传统人工检测方法不仅操作繁琐、效率低下&#xff0c;还难以全面反映墙体的真…

主机A与主机B建立TCP连接的三次握手过程

&#xff08; 1 &#xff09;主机 A 的 TCP 向主机 B 发出连接请求 SYN 报文段&#xff08;第一次握手&#xff09;。&#xff08; 1 分&#xff09; &#xff08; 2 &#xff09;一旦包含 SYN 报文段的 IP 数据报到达主机 B &#xff0c; SYN 报文段被从数据报…

【GUI-pyqt5】QObject类

1. QObject模块详解 1.1 描述 所有Qt对象的父类 1.2 功能和作用 1.2.1 对象名称和属性 1.2.1.1 API API功能备注 setObjectName("唯一名称") 给一个Qt对象设置一个名称 一般这个名称是唯一的&#xff0c;当做对象ID来使用 objectName() 获取一个对象名称 - set…

C++Primer 变量

欢迎阅读我的 【CPrimer】专栏 专栏简介&#xff1a;本专栏主要面向C初学者&#xff0c;解释C的一些基本概念和基础语言特性&#xff0c;涉及C标准库的用法&#xff0c;面向对象特性&#xff0c;泛型特性高级用法。通过使用标准库中定义的抽象设施&#xff0c;使你更加适应高级…

VScode怎么重启

原文链接&#xff1a;【vscode】vscode重新启动 键盘按下 Ctrl Shift p 打开命令行&#xff0c;如下图&#xff1a; 输入Reload Window&#xff0c;如下图&#xff1a;

(leetcode算法题)382. 链表随机节点

如果给你一个 智能记录 k行内容的小笔记本&#xff0c;从一本你也不知道有多少行的 C Primer 中进行摘抄&#xff0c;你应该怎么做才能让抄写的时候能让书中的每一行都等概率的出现在小笔记本中&#xff1f; 答&#xff1a;准备好一个公平的轮盘和一个巨大的摇奖机&#xff0c…

MIPI_DPU 综合(DPU+MIPI+Demosaic+VDMA 通路)

目录 1. 简介 2. 创建 Platform 2.1 Block Design 2.1.1 DPU PFM Lite 2.1.2 DPU prj 2.1.3 DPU MIPI Platform 2.2 pin 约束 2.2.1 GPIO 约束 2.2.2 IIC 约束 2.1.3 DPHY 约束 3. 报错总结 3.1 AXI_M 必须顺序引用 3.2 DPU 地址分配错误 4. Design Example 4.…

亚信安全2025年第1期《勒索家族和勒索事件监控报告》

本周态势快速感知 本周全球共监测到勒索事件51起&#xff0c;本周勒索事件数量降至近一年来最低&#xff0c;需注意防范。从整体上看Ransomhub依旧是影响最严重的勒索家族&#xff1b;本周Acrusmedia和Safepay也是两个活动频繁的恶意家族&#xff0c;需要注意防范。本周&#…

麒麟服务器安装kafka--亲测

我这安装的是单机版本的&#xff1a; 下载地址&#xff1a;Index of /kafka/3.9.0 我下载的是&#xff1a;https://dlcdn.apache.org/zookeeper/zookeeper-3.9.3/apache-zookeeper-3.9.3-bin.tar.gz https://dlcdn.apache.org/kafka/3.9.0/kafka_2.12-3.9.0.tgz 一、下载并上…

利用Deeplearning4j进行 图像识别

目录 图像识别简介 神经网络 感知器 前馈神经网络 自动编码器 受限玻尔兹曼机 深度卷积网络 理解图像内容以及图像含义方面&#xff0c;计算机遇到了很大困难。本章先介绍计算机理解图像教育方面 遇到的难题&#xff0c;接着重点讲解一个基于深度学习的解决方法。我们会…

51单片机——按键实验

由于机械点的弹性作用&#xff0c;按键开关在闭合时不会马上稳定的接通&#xff0c;在断开时也不会一下子断开&#xff0c;因而在闭合和断开的瞬间均伴随着一连串的抖动。抖动时间的长短由按键的机械特性决定的&#xff0c;一般为 5ms 到 10ms&#xff0c;为了确保 CPU 对按键的…

关于嵌入式系统的知识课堂(二)

成长路上不孤单&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a;&#x1f60a; 【14后&#x1f60a;///计算机爱好者&#x1f60a;///持续分享所学&#x1f60a;///如有需要欢迎收藏转发///&#x1f60a;】 今日分享关于嵌入式系统的知识课堂&#xff08;…

CSS——5. 外部样式

<!DOCTYPE html> <html><head><meta charset"UTF-8"><title>方法3&#xff1a;外部样式</title><link rel"stylesheet" href"a.css" /><link rel"stylesheet" href"b.css"/&g…

玩游戏提示找不到vcruntime140.dll,修复方法分享

在玩游戏时&#xff0c;电脑突然弹出“找不到vcruntime140.dll”的提示怎么回事&#xff1f;玩游戏时提示找不到vcruntime140.dll文件时&#xff0c;这通常意味着你的系统中缺少了这个关键的DLL文件&#xff0c;或者该文件已损坏。vcruntime140.dll是Visual C运行时库的一部分&…

Aloudata AIR | 逻辑数据平台的 NoETL 之道

一文为你介绍 Aloudata AIR 逻辑数据平台的技术原理与核心价值 本文主旨是介绍逻辑数据平台的技术原理与核心价值&#xff0c;包含几个部分的内容&#xff1a; 首先&#xff0c;简要阐述逻辑数据平台出现的背景&#xff1b;其次&#xff0c;详细讲解逻辑数据平台的构建方法&am…

电子应用设计方案86:智能 AI背景墙系统设计

智能 AI 背景墙系统设计 一、引言 智能 AI 背景墙系统旨在为用户创造一个动态、个性化且具有交互性的空间装饰体验&#xff0c;通过融合先进的技术和创意设计&#xff0c;提升室内环境的美观度和功能性。 二、系统概述 1. 系统目标 - 提供多种主题和风格的背景墙显示效果&…