.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); //c1Buffer.BlockCopy(c1c2c3, c1c2c3.Length - c3Len, result, c1Len, c3Len); //c3Buffer.BlockCopy(c1c2c3, c1Len, result, c1Len + c3Len, c1c2c3.Length - c1Len - c3Len); //c2return 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->65Buffer.BlockCopy(c1c3c2, c1Len + c3Len, result, c1Len, c1c3c2.Length - c1Len - c3Len); //c2Buffer.BlockCopy(c1c3c2, c1Len, result, c1c3c2.Length - c3Len, c3Len); //c3return 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<=32byte[] 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.NamefileStream = 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);}elsebyteSource.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=1Asn1Sequence priSeq = (Asn1Sequence)asn1Sequence[1];//private keyAsn1Sequence 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.mzph.cn/web/64658.shtml

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

相关文章

工作中常用Vim的命令

Hi, 我是你们的老朋友&#xff0c;主要专注于嵌入式软件开发&#xff0c;有兴趣不要忘记点击关注【码思途远】 目录 0. ctags -R 1.认识 Vim的几种工作模式 2.高频使用命令 2.1 修改文件 2.2 关于行号 2.3 删除多行&#xff0c;删除部分 2.4 复制粘贴 2.5 光标移动 2.…

如何在 Vue 2 中使用 Swiper 5.4.5 处理静态与后端数据不能切换问题

一、文章大纲 1.前言 介绍 Swiper 作为一款强大的轮播组件,常用于处理图片、文章、商品等内容的滑动展示。 在 Vue.js 项目中集成 Swiper,尤其是在 Vue 2 中使用,常见的两种数据来源:静态数据与后端数据。 在 Vue 2 项目中集成 Swiper 5.4.5 2.如何通过 npm 安装 Swiper…

究极炫酷3D立方体宇宙

演示动画&#xff1a;https://life.mdjsjd.me/2024/12/27/3d-cube-animation/ 一个使用Python和Pygame制作的炫酷3D立方体动画效果。结合了多种视觉特效,包括: 动态旋转的3D立方体炫彩渐变的颜色系统星空背景粒子效果动态残影拖尾效果深度透视投影 主要特性 动态变换: 立方…

什么是 Azure OpenAI ?了解微软 Azure OpenAI 和 OpenAI 的关系

一、什么是Azure OpenAI &#xff1f; 微软已与 OpenAI 合作以实现三个主要目标&#xff1a; ⦿利用 Azure 的基础结构&#xff08;包括安全性、合规性和区域可用性&#xff09;&#xff0c;帮助用户构建企业级应用程序。 ⦿在微软产品&#xff08;包括 Azure AI 产品以及以外…

Linux day 1129

家人们今天继续学习Linux&#xff0c;ok话不多说一起去看看吧 三.Linux常用命令 3.1 Linux命令体验 3.1.1 常用命令演示 在这一部分中&#xff0c;我们主要介绍几个常用的命令&#xff0c;让大家快速感 受以下 Linux 指令的操作方式。主要包含以下几个指令&#xff1a; ls命…

mysql8 从C++源码角度看 Statement cancelled due to timeout or client request异常

##Statement cancelled due to timeout or client request 异常 Caused by: com.mysql.jdbc.exceptions.MySQLTimeoutException: Statement cancelled due to timeout or client requestat com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:1932)at …

【数据结构-单调队列】力扣1438. 绝对差不超过限制的最长连续子数组

给你一个整数数组 nums &#xff0c;和一个表示限制的整数 limit&#xff0c;请你返回最长连续子数组的长度&#xff0c;该子数组中的任意两个元素之间的绝对差必须小于或者等于 limit 。 如果不存在满足条件的子数组&#xff0c;则返回 0 。 示例 1&#xff1a; 输入&#x…

SAP HCM 标准报表与前台操作的增强差异逻辑分析(rhgrenz4)

导读 增强差异:SAP的HCM模块组织和人事增强都有标准的增强点&#xff0c;不管你调用标准的函数还是前台操作都会触发对应的增强。所以很多业务不需要考虑那么多分散点&#xff0c;只要找到一个合适的增强点&#xff0c;就能解决很多和外围系统集成的业务逻辑&#xff0c;今天遇…

【Spring】Spring DI(依赖注入)详解——自动装配——手动装配与自动装配的区别

在spring开发中&#xff0c;依赖注入&#xff08;Dependency Injection&#xff0c;DI&#xff09;是实现松耦合和高内聚设计的重要模式。它使得对象的创建和管理与其依赖关系分离&#xff0c;从而提高了代码的可维护性、可测试性和灵活性。Spring框架通过IoC&#xff08;控制反…

EZ-USB™ FX3 USB 5 Gbps 外设控制器

EZ-USB™ FX3 USB 5 Gbps 外设控制器 EZ-USB™ FX3 提供 USB 5Gbps 至 32 位数据总线&#xff0c;并配备 ARM9&#xff0c;可为任何系统添加 USB 3.0 连接 英飞凌的 EZ-USB™ FX3 是业界用途最广泛的 USB 外围设备控制器&#xff0c;可以为几乎任何系统添加 USB 5Gbps 连接。 …

【数据仓库】spark大数据处理框架

文章目录 概述架构spark 架构角色下载安装启动pyspark启动spark-sehll启动spark-sqlspark-submit经验 概述 Spark是一个性能优异的集群计算框架&#xff0c;广泛应用于大数据领域。类似Hadoop&#xff0c;但对Hadoop做了优化&#xff0c;计算任务的中间结果可以存储在内存中&a…

数据库容灾备份的意义+分类+执行工具!

数据库容灾解决方案的背景 数据库容灾&#xff08;Disaster Recovery&#xff0c;DR&#xff09;解决方案的背景主要源于企业对数据安全性、业务连续性和系统高可用性的需求。随着数字化转型的加速&#xff0c;企业的数据量迅猛增长&#xff0c;数据库已成为支撑核心业务的关键…

PDF怎么压缩得又小又清晰?5种PDF压缩方法

PDF 文件在日常办公与学习中使用极为频繁&#xff0c;可想要把它压缩得又小又清晰却困难重重。一方面&#xff0c;PDF 格式本身具有高度兼容性&#xff0c;集成了文字、图像、矢量图等多样元素&#xff0c;压缩时难以兼顾不同元素特性&#xff0c;稍不注意&#xff0c;文字就会…

SpringBoot数据字典字段自动生成对应code和desc

效果&#xff1a;接口会返回orderType&#xff0c;但是这个orderType是枚举的类型&#xff08;1&#xff0c;2&#xff0c;3&#xff0c;4&#xff09;&#xff0c;我想多返回一个orderTypeDesc给前端展示&#xff0c;这样前端就可以直接拿orderTypeDesc使用了。 1. 定义注解 …

【YashanDB知识库】imp导入数据库时,报错YAS-08023

本文内容来自YashanDB官网&#xff0c;原文内容请见 https://www.yashandb.com/newsinfo/7849010.html?templateId1718516 **【问题分类】**数据导入导出 **【关键字】**imp、YAS-08023 【问题描述】 导出数据库时&#xff0c;使用以下命令&#xff0c;导出正常&#xff1…

又一年。。。。。。

2024&#xff0c;浑浑噩噩的一年。 除了100以内的加减法&#xff08;数据&#xff0c;数据&#xff0c;还是数据。。。。。。&#xff09;&#xff0c;似乎没做些什么。 脸盲症越来越重的&#xff0c;怕是哪天连自己都不认得自己的了。 看到什么&#xff0c;听到什…

FreeRTOS: ISR(中断服务例程)和 TCB(任务控制块)

在讨论 ISR&#xff08;中断服务例程&#xff09;和 TCB&#xff08;任务控制块&#xff0c;Task Control Block&#xff09;时&#xff0c;我们实际上是在探讨 FreeRTOS 中两个不同但又相互关联的概念&#xff1a;一个是用于处理硬件或软件触发的中断事件&#xff0c;另一个是…

GoldenDB组件及对应的用户和进程

1. GoldenDB组件及对应的用户和进程 GoldenDB数据库由管理节点、全局事务节点GTM、计算节点CN、数据节点DN等组成。 1.1. 管理节点 管理节点分为集群管理、Insight运维管理平台&#xff08;InsightServer、RDB、ZK&#xff09;。 1.1.1. 集群管理 1. 集群管理包括Metadatas…

OpenStack系列第四篇:云平台基础功能与操作(Dashboard)

文章目录 1. 镜像&#xff08;Image&#xff09;添加镜像查看镜像删除镜像 2. 卷&#xff08;Volume&#xff09;创建卷查看卷删除卷 3. 网络&#xff08;虚拟网络&#xff09;创建网络查看网络删除网络 4. 实例类型创建实例类型查看实例类型删除实例类型 4. 密钥对&#xff08…

CSDN编辑器

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…