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

C#加密与java 互通

文章目录

  • 前言
  • 对方接口签名要求
  • 我方对接思路
    • 1.RSA 加密
    • 2.AES256加密
  • 完整的加密帮助类


前言

提示:这里可以添加本文要记录的大概内容:

在我们对接其他公司接口的时候,时常会出现对方使用的开发语言和我方使用的开发语言不同的情况,因为每个语言之间都会有些许差别,在进行加密签名中就会出现签名一直对接不上的问题,下面我就来和各位分享一下我所遇到的问题以及解决方案。


对方接口签名要求

  1. 报文发送方自行产生随机密钥,然后再使用接收方公钥对随机秘钥进行RSA 非对称加密,生成 encrypted。
  2. 按照报文规范生成报文原文,然后对报文原文(JSON 格式字符串)使用 对称密钥字节数组进行 AES256 算法加密,再进行 Base64 编码,生成msg
  3. 再对报文原文进行签名,得到签名结果(十六进制字符串),签名算法采用“SHA1withRSA”,生成 signature

可以看到上面这一堆文字,看似字很少,实则却使用到了很多种加密方式
可以梳理出会用到的加密有:RSA加密,AES256加密,Base64加密,SHA1加密

我方对接思路

1.RSA 加密

由于对方时使用的java,java密钥的key格式和我们C#这边RSA加密使用的key格式不一样,需要进行格式处理也就是下面的“RSAPrivateKeyJava2DotNet”方法。

  public class RSAUtils{/// <summary>/// 生成私钥/// </summary>/// <returns></returns>public static string CreatePrivateKey(){string str = Guid.NewGuid().ToString("N");Byte[] bytes = Encoding.GetEncoding("utf-8").GetBytes(str);byte[] aesKey = new byte[16];for (int i = 0; i < 16; i++){aesKey[i] = bytes[i];}return Convert.ToBase64String(aesKey);}/// <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 表示仅包含公钥。}/// <summary>/// RSA加密 将公钥导入到RSA对象中,准备加密/// </summary>/// <param name="publicKey">公钥</param>/// <param name="encryptstring">待加密的字符串</param>public static string RsaEncrypt(string publicKey, string encryptstring){using (var rsaProvider = new RSACryptoServiceProvider()){string key = RSAPublicKeyJava2DotNet(publicKey);var inputBytes = Encoding.UTF8.GetBytes(encryptstring);//有含义的字符串转化为字节流rsaProvider.FromXmlString(key);//载入公钥int bufferSize = (rsaProvider.KeySize / 8) - 11;//单块最大长度var buffer = new byte[bufferSize];using (MemoryStream inputStream = new MemoryStream(inputBytes), 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 encryptedBytes = rsaProvider.Encrypt(temp, false);outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);}return Convert.ToBase64String(outputStream.ToArray());//转化为字节流方便传输}}}/// <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 BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));RsaKeyParameters pub = new RsaKeyParameters(false, m, p);SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();return Convert.ToBase64String(serializedPublicBytes);}/// <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()));}/// <summary>/// c#使用的.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);}/// <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>/// RSA私钥加密/// </summary>/// <param name="privateKey">私钥</param>/// <param name="encryptstring">待加密的字符串</param>public static string RsaPrivateEncrypt(string privateKey, string encryptstring){var rsaProvider = new RSACryptoServiceProvider();rsaProvider.FromXmlString(privateKey);//载入私钥var inputBytes = Convert.FromBase64String(encryptstring);//有含义的字符串转化为字节流int bufferSize = (rsaProvider.KeySize / 8) - 11;//单块最大长度var buffer = new byte[bufferSize];using (MemoryStream inputStream = new MemoryStream(inputBytes), 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 encryptedBytes = RsaPrivateEncrypt(privateKey, temp);outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);}return Convert.ToBase64String(outputStream.ToArray());//转化为字节流方便传输}}/// <summary>  /// RSA公钥解密/// </summary>  /// <param name="publicKey">公钥</param>  /// <param name="decryptstring">待解密的字符串</param>  public static string RsaPublicDecrypt(string publicKey, string decryptstring){var rsaProvider = new RSACryptoServiceProvider();rsaProvider.FromXmlString(publicKey); //载入私钥  var encryptedBytes = Convert.FromBase64String(decryptstring); //将传入的字符串转化为字节流  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 = decryptByPublicKey(publicKey, temp);outputStream.Write(decryptedBytes, 0, decryptedBytes.Length);}return Convert.ToBase64String(outputStream.ToArray());}}/// <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);}}/// <summary>/// 私钥加密/// 这个方法只能加密 私钥长度/8 -11 个字符,分段加密的代码要自己处理了。/// </summary>/// <param name="privateKey">密钥</param>/// <param name="data">要加密的数据</param>/// <returns></returns>public static byte[] RsaPrivateEncrypt(string privateKey, byte[] data){string xmlPrivateKey = privateKey;//加载私钥  RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider();privateRsa.FromXmlString(xmlPrivateKey);//转换密钥  AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);//IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致       IBufferedCipher c = CipherUtilities.GetCipher("RSA");c.Init(true, keyPair.Private); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥 byte[] DataToEncrypt = data;byte[] outBytes = c.DoFinal(DataToEncrypt);//加密  return outBytes;}/// <summary>/// 用公钥解密/// 这个方法只能加密 私钥长度/8 -11 个字符,分段加密的代码要自己处理了。/// </summary>/// <param name="data"></param>/// <param name="key"></param>/// <returns></returns>public static byte[] decryptByPublicKey(string publicKey, byte[] data){string xmlPublicKey = publicKey;RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();publicRsa.FromXmlString(xmlPublicKey);AsymmetricKeyParameter keyPair = DotNetUtilities.GetRsaPublicKey(publicRsa);//转换密钥  // AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetRsaKeyPair(publicRsa);//IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致       IBufferedCipher c = CipherUtilities.GetCipher("RSA");c.Init(false, keyPair); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥 byte[] DataToEncrypt = data;byte[] outBytes = c.DoFinal(DataToEncrypt);//解密  return outBytes;}}

调用方法

  string pkey= RSAUtils.CreatePrivateKey();encrypt.data.encrypted = RSAUtils.RsaEncrypt(publicKey, pkey);

其中publicKey 是对方公司(JAVA)给我们的公钥,
这里我们生成的KEY是:Q2THHWOD1H4L81DO
加密出来的值是:rZdVr8ksB4EyJ0L6GGjcgHR+XYKwRnxxs+94Hyd/Y52SgqaROFva3DLACjYrzyAHetmGrMpPLKf4TRq0V8F5eDrjZRhOQelA5ogSWRoLwzpN4KZirBc1HCHyrfaEvHDtoJeNabZzKFTDHvNZ94NRQfpHXqABlS7TzOXJKLK1Z/BiQjGuyOGL3xohwhyZ+vgjqNFjpTYU7gqobno5kBK6zoG8B2wilsDP+4hkF7IAn6dAlw8scBMpuULZF6ceBCEakkgWrBYn4E5DiC5c1tz2x3yViBNO+2XV0YdZIrBVkWKZGCWBYVkq53ovyPavuMMyK16HF7CnKlE3RdMc2WvT6g==

这一步我们加密后对方公司的java是能解密出正确明文的。

2.AES256加密

这里问题就来了

下面是错误方法:

        /// <summary>/// AES加密/// </summary>/// <param name="encryptStr">明文</param>/// <param name="key">密钥</param>/// <returns></returns>public static string Encrypt(string encryptStr,string key){byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(encryptStr);RijndaelManaged rDel = new RijndaelManaged();rDel.Key = keyArray;rDel.Mode = CipherMode.ECB;rDel.Padding = PaddingMode.PKCS7;ICryptoTransform cTransform = rDel.CreateEncryptor();byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);return Convert.ToBase64String(resultArray, 0, resultArray.Length);}/// <summary>/// AES解密/// </summary>/// <param name="decryptStr">密文</param>/// <param name="key">密钥</param>/// <returns></returns>public static string Decrypt(string decryptStr,string key){byte[] keyArray = UTF8Encoding.UTF8.GetBytes(key);byte[] toEncryptArray = Convert.FromBase64String(decryptStr);RijndaelManaged rDel = new RijndaelManaged();rDel.Key = keyArray;rDel.Mode = CipherMode.ECB;rDel.Padding = PaddingMode.PKCS7;ICryptoTransform cTransform = rDel.CreateDecryptor();byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);return UTF8Encoding.UTF8.GetString(resultArray);}

这种方式加密在网上的在线解密工具都解密不了,只有我们C#写的解密方法能解密,估计是因为填充类型或者其他什么地方有问题。在这里我也困惑了很久

下面是正确方法:

public class AESUtils
{/// <summary>/// AES256加密/// </summary>/// <param name="content">明文</param>/// <param name="passphase">密钥</param>/// <returns></returns>public static string Encrypt(string content, string passphase){byte[] bytes = Encoding.UTF8.GetBytes(content);byte[] key, iv, salt = new byte[8];using (var rng = new RNGCryptoServiceProvider()){rng.GetBytes(salt); }using (var md5 = new MD5CryptoServiceProvider()){var preHash = Encoding.UTF8.GetBytes(passphase).Concat(salt).ToArray();var bs1 = md5.ComputeHash(preHash);var bs2 = md5.ComputeHash(bs1.Concat(preHash).ToArray());var bs3 = md5.ComputeHash(bs2.Concat(preHash).ToArray());key = bs1.Concat(bs2).ToArray();iv = bs3;}using (var aes = new AesCryptoServiceProvider() { Key = key, IV = iv })using (var encryptor = aes.CreateEncryptor()){var encryptedBytes = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);var concated = Encoding.UTF8.GetBytes("Salted__").Concat(salt).Concat(encryptedBytes);return Convert.ToBase64String(concated.ToArray());}}/// <summary>/// AES256解密/// </summary>/// <param name="content">密文</param>/// <param name="passphase">密钥</param>/// <returns></returns>public static string Decrypt(string content, string passphase){// openssl aes-256-cbc -k 123456789 -md md5 -e -base64//byte[] bytes = Convert.FromBase64String(content);byte[] key, iv, salt = new byte[8], encryptedBytes = new byte[bytes.Length - 8 - 8];//提取 saltArray.ConstrainedCopy(sourceArray: bytes,sourceIndex: 8, //剔除开头的 "Salted__"destinationArray: salt,destinationIndex: 0,length: salt.Length);//提取 encryptedBytesArray.ConstrainedCopy(sourceArray: bytes,sourceIndex: 8 + 8, //并剔除开头的 saltdestinationArray: encryptedBytes,destinationIndex: 0,length: encryptedBytes.Length);using (var md5 = new MD5CryptoServiceProvider()){var preHash = Encoding.UTF8.GetBytes(passphase).Concat(salt).ToArray();var bs1 = md5.ComputeHash(preHash);var bs2 = md5.ComputeHash(bs1.Concat(preHash).ToArray());var bs3 = md5.ComputeHash(bs2.Concat(preHash).ToArray());key = bs1.Concat(bs2).ToArray();iv = bs3;}using (var aes = new AesCryptoServiceProvider() { Key = key, IV = iv })using (var decryptor = aes.CreateDecryptor()){byte[] decryptedBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);return Encoding.UTF8.GetString(decryptedBytes);}}/// <summary>/// 加密 (新的思路)/// </summary>/// <param name="content">明文</param>/// <param name="passphase">密码(固定32位)</param>/// <returns>密文(base64)</returns>static string CryptoJsEncrypt_New(string content, string passphase ){byte[] bytes = Encoding.UTF8.GetBytes(content);byte[] key = Encoding.UTF8.GetBytes(passphase); //32位的keybyte[] iv = new byte[16];using (var rng = new RNGCryptoServiceProvider())rng.GetBytes(iv); // 产生16个字节的随机ivusing (var aes = new AesCryptoServiceProvider() { Key = key, IV = iv })using (var encryptor = aes.CreateEncryptor()){var encryptedBytes = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);var concated = iv.Concat(encryptedBytes);return "aes256:" + Convert.ToBase64String(concated.ToArray());}}/// <summary>/// 解密 (新的思路)/// </summary>/// <param name="content">密文(base64)</param>/// <param name="passphase">密码(固定32位)</param>/// <returns>明文</returns>static string CryptoJsDecrypt_New(string content, string passphase ){byte[] bytes = Convert.FromBase64String(content.Substring(7)); //剔除开头的 "aes256:"byte[] key = Encoding.UTF8.GetBytes(passphase); //32位的keybyte[] iv = new byte[16];byte[] encryptedBytes = new byte[bytes.Length - 16];//提取 ivArray.ConstrainedCopy(sourceArray: bytes,sourceIndex: 0,destinationArray: iv,destinationIndex: 0,length: iv.Length);//提取 加密结果Array.ConstrainedCopy(sourceArray: bytes,sourceIndex: 16, //并剔除开头的 ivdestinationArray: encryptedBytes,destinationIndex: 0,length: encryptedBytes.Length);using (var aes = new AesCryptoServiceProvider() { Key = key, IV = iv })using (var decryptor = aes.CreateDecryptor()){byte[] decryptedBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);return Encoding.UTF8.GetString(decryptedBytes);}}
}

调用方法

AESUtils.Encrypt(datastr, pkey);

加密前明文字符串:
{"storeId":"1788431406828474370","merchantId":"1788027169854296065","tradeNo":"123456","phone":"13366237305","tradeAmount":"5.0","notifyUrl":"http://wx.wjy99.com/onlinemtorder/yunxin/orderMsg","callbackUrl":"http://wx.wjy99.com/onlinemtorder/yunxin/orderMsg","remark":"测试请求"}
加密后密文:
U2FsdGVkX1+FSSnYrXRRcvfDoSeLLPcaA2LEN0/ix7Z41jXIYRdCdIm3DMob+xwvVdMnFwv4iq7LhFxAZcetRHbS3hxhbjObhNvkQrvd79+AnZdEMoM/BGTx66U/c8xtdMheqxrRWoXoIIpfRf++UQCGZBuU5upwMjTmuU3vJKQX/2r5qUHkjH05qkR+ioLb6bvi1FKI6vp3Bs4sKPEKtq+5M26aBdOfo5RmmrSJ023GkvC4DGxlyVn7ac97bBj3X/8h2yfpT1E6zW6FwZIBK+aVPlPFVeKVeXBZwdX5tgpgB+4e6duHPAjArQ1XYRfx2ugNn38IDxwtap7ocBi3GnPB8U4iTXPCz+/7uFutDzIQi0hRVEMpVRqaaaw2Ri2fFV84QYgotJC+qXkKRwyx9g==

这种加密方式,网上的解密都能解开了。


完整的加密帮助类

  /// <summary>/// RSA/// </summary>public class RSAUtils{/// <summary>/// 生成私钥/// </summary>/// <returns></returns>public static string CreatePrivateKey(){string str = Guid.NewGuid().ToString("N");Byte[] bytes = Encoding.GetEncoding("utf-8").GetBytes(str);byte[] aesKey = new byte[16];for (int i = 0; i < 16; i++){aesKey[i] = bytes[i];}return Convert.ToBase64String(aesKey);}/// <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 表示仅包含公钥。}/// <summary>/// RSA加密 将公钥导入到RSA对象中,准备加密/// </summary>/// <param name="publicKey">公钥</param>/// <param name="encryptstring">待加密的字符串</param>public static string RsaEncrypt(string publicKey, string encryptstring){using (var rsaProvider = new RSACryptoServiceProvider()){string key = RSAPublicKeyJava2DotNet(publicKey);var inputBytes = Encoding.UTF8.GetBytes(encryptstring);//有含义的字符串转化为字节流rsaProvider.FromXmlString(key);//载入公钥int bufferSize = (rsaProvider.KeySize / 8) - 11;//单块最大长度var buffer = new byte[bufferSize];using (MemoryStream inputStream = new MemoryStream(inputBytes), 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 encryptedBytes = rsaProvider.Encrypt(temp, false);outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);}return Convert.ToBase64String(outputStream.ToArray());//转化为字节流方便传输}}}/// <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 BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Modulus")[0].InnerText));BigInteger p = new BigInteger(1, Convert.FromBase64String(doc.DocumentElement.GetElementsByTagName("Exponent")[0].InnerText));RsaKeyParameters pub = new RsaKeyParameters(false, m, p);SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(pub);byte[] serializedPublicBytes = publicKeyInfo.ToAsn1Object().GetDerEncoded();return Convert.ToBase64String(serializedPublicBytes);}/// <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()));}/// <summary>/// c#使用的.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);}/// <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>/// RSA私钥加密/// </summary>/// <param name="privateKey">私钥</param>/// <param name="encryptstring">待加密的字符串</param>public static string RsaPrivateEncrypt(string privateKey, string encryptstring){var rsaProvider = new RSACryptoServiceProvider();rsaProvider.FromXmlString(privateKey);//载入私钥var inputBytes = Convert.FromBase64String(encryptstring);//有含义的字符串转化为字节流int bufferSize = (rsaProvider.KeySize / 8) - 11;//单块最大长度var buffer = new byte[bufferSize];using (MemoryStream inputStream = new MemoryStream(inputBytes), 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 encryptedBytes = RsaPrivateEncrypt(privateKey, temp);outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);}return Convert.ToBase64String(outputStream.ToArray());//转化为字节流方便传输}}/// <summary>  /// RSA公钥解密/// </summary>  /// <param name="publicKey">公钥</param>  /// <param name="decryptstring">待解密的字符串</param>  public static string RsaPublicDecrypt(string publicKey, string decryptstring){var rsaProvider = new RSACryptoServiceProvider();rsaProvider.FromXmlString(publicKey); //载入私钥  var encryptedBytes = Convert.FromBase64String(decryptstring); //将传入的字符串转化为字节流  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 = decryptByPublicKey(publicKey, temp);outputStream.Write(decryptedBytes, 0, decryptedBytes.Length);}return Convert.ToBase64String(outputStream.ToArray());}}/// <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);}}/// <summary>/// 私钥加密/// 这个方法只能加密 私钥长度/8 -11 个字符,分段加密的代码要自己处理了。/// </summary>/// <param name="privateKey">密钥</param>/// <param name="data">要加密的数据</param>/// <returns></returns>public static byte[] RsaPrivateEncrypt(string privateKey, byte[] data){string xmlPrivateKey = privateKey;//加载私钥  RSACryptoServiceProvider privateRsa = new RSACryptoServiceProvider();privateRsa.FromXmlString(xmlPrivateKey);//转换密钥  AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetKeyPair(privateRsa);//IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致       IBufferedCipher c = CipherUtilities.GetCipher("RSA");c.Init(true, keyPair.Private); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥 byte[] DataToEncrypt = data;byte[] outBytes = c.DoFinal(DataToEncrypt);//加密  return outBytes;}/// <summary>/// 用公钥解密/// 这个方法只能加密 私钥长度/8 -11 个字符,分段加密的代码要自己处理了。/// </summary>/// <param name="data"></param>/// <param name="key"></param>/// <returns></returns>public static byte[] decryptByPublicKey(string publicKey, byte[] data){string xmlPublicKey = publicKey;RSACryptoServiceProvider publicRsa = new RSACryptoServiceProvider();publicRsa.FromXmlString(xmlPublicKey);AsymmetricKeyParameter keyPair = DotNetUtilities.GetRsaPublicKey(publicRsa);//转换密钥  // AsymmetricCipherKeyPair keyPair = DotNetUtilities.GetRsaKeyPair(publicRsa);//IBufferedCipher c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding");// 参数与Java中加密解密的参数一致       IBufferedCipher c = CipherUtilities.GetCipher("RSA");c.Init(false, keyPair); //第一个参数为true表示加密,为false表示解密;第二个参数表示密钥 byte[] DataToEncrypt = data;byte[] outBytes = c.DoFinal(DataToEncrypt);//解密  return outBytes;}}/// <summary>/// AES /// </summary>public class AESUtils{/// <summary>/// AES256加密/// </summary>/// <param name="content">明文</param>/// <param name="passphase">密钥</param>/// <returns></returns>public static string Encrypt(string content, string passphase){byte[] bytes = Encoding.UTF8.GetBytes(content);byte[] key, iv, salt = new byte[8];using (var rng = new RNGCryptoServiceProvider()){rng.GetBytes(salt); }using (var md5 = new MD5CryptoServiceProvider()){var preHash = Encoding.UTF8.GetBytes(passphase).Concat(salt).ToArray();var bs1 = md5.ComputeHash(preHash);var bs2 = md5.ComputeHash(bs1.Concat(preHash).ToArray());var bs3 = md5.ComputeHash(bs2.Concat(preHash).ToArray());key = bs1.Concat(bs2).ToArray();iv = bs3;}using (var aes = new AesCryptoServiceProvider() { Key = key, IV = iv })using (var encryptor = aes.CreateEncryptor()){var encryptedBytes = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);var concated = Encoding.UTF8.GetBytes("Salted__").Concat(salt).Concat(encryptedBytes);return Convert.ToBase64String(concated.ToArray());}}/// <summary>/// AES256解密/// </summary>/// <param name="content">密文</param>/// <param name="passphase">密钥</param>/// <returns></returns>public static string Decrypt(string content, string passphase){// openssl aes-256-cbc -k 123456789 -md md5 -e -base64//byte[] bytes = Convert.FromBase64String(content);byte[] key, iv, salt = new byte[8], encryptedBytes = new byte[bytes.Length - 8 - 8];//提取 saltArray.ConstrainedCopy(sourceArray: bytes,sourceIndex: 8, //剔除开头的 "Salted__"destinationArray: salt,destinationIndex: 0,length: salt.Length);//提取 encryptedBytesArray.ConstrainedCopy(sourceArray: bytes,sourceIndex: 8 + 8, //并剔除开头的 saltdestinationArray: encryptedBytes,destinationIndex: 0,length: encryptedBytes.Length);using (var md5 = new MD5CryptoServiceProvider()){var preHash = Encoding.UTF8.GetBytes(passphase).Concat(salt).ToArray();var bs1 = md5.ComputeHash(preHash);var bs2 = md5.ComputeHash(bs1.Concat(preHash).ToArray());var bs3 = md5.ComputeHash(bs2.Concat(preHash).ToArray());key = bs1.Concat(bs2).ToArray();iv = bs3;}using (var aes = new AesCryptoServiceProvider() { Key = key, IV = iv })using (var decryptor = aes.CreateDecryptor()){byte[] decryptedBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);return Encoding.UTF8.GetString(decryptedBytes);}}/// <summary>/// 加密 (新的思路)/// </summary>/// <param name="content">明文</param>/// <param name="passphase">密码(固定32位)</param>/// <returns>密文(base64)</returns>static string CryptoJsEncrypt_New(string content, string passphase ){byte[] bytes = Encoding.UTF8.GetBytes(content);byte[] key = Encoding.UTF8.GetBytes(passphase); //32位的keybyte[] iv = new byte[16];using (var rng = new RNGCryptoServiceProvider())rng.GetBytes(iv); // 产生16个字节的随机ivusing (var aes = new AesCryptoServiceProvider() { Key = key, IV = iv })using (var encryptor = aes.CreateEncryptor()){var encryptedBytes = encryptor.TransformFinalBlock(bytes, 0, bytes.Length);var concated = iv.Concat(encryptedBytes);return "aes256:" + Convert.ToBase64String(concated.ToArray());}}/// <summary>/// 解密 (新的思路)/// </summary>/// <param name="content">密文(base64)</param>/// <param name="passphase">密码(固定32位)</param>/// <returns>明文</returns>static string CryptoJsDecrypt_New(string content, string passphase ){byte[] bytes = Convert.FromBase64String(content.Substring(7)); //剔除开头的 "aes256:"byte[] key = Encoding.UTF8.GetBytes(passphase); //32位的keybyte[] iv = new byte[16];byte[] encryptedBytes = new byte[bytes.Length - 16];//提取 ivArray.ConstrainedCopy(sourceArray: bytes,sourceIndex: 0,destinationArray: iv,destinationIndex: 0,length: iv.Length);//提取 加密结果Array.ConstrainedCopy(sourceArray: bytes,sourceIndex: 16, //并剔除开头的 ivdestinationArray: encryptedBytes,destinationIndex: 0,length: encryptedBytes.Length);using (var aes = new AesCryptoServiceProvider() { Key = key, IV = iv })using (var decryptor = aes.CreateDecryptor()){byte[] decryptedBytes = decryptor.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length);return Encoding.UTF8.GetString(decryptedBytes);}}}

相关文章:

C#加密与java 互通

文章目录 前言对方接口签名要求我方对接思路1.RSA 加密2.AES256加密 完整的加密帮助类 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 在我们对接其他公司接口的时候&#xff0c;时常会出现对方使用的开发语言和我方使用的开发语言不同的情况&#xff…...

C#【进阶】特殊语法

特殊语法、值和引用类型 特殊语法 文章目录 特殊语法1、var隐式类型2、设置对象初始值3、设置集合初始值4、匿名类型5、可空类型6、空合并操作符7、内插字符串8、单句逻辑简略写法 值和引用类型1、判断值和引用类型2、语句块3、变量的生命周期4、结构体中的值和引用5、类中的值…...

c语言之向文件读写数据块

c语言需要向文件读写数据块需要用到fread语句和fwrite语句 fread语句的语法格式 fread(butter,size,count,fp) butter&#xff1a;读取的数据存入内存地址 size:读取的字节大小 count:读取数据的个数 fp:读取的文件指针 fwrite语句语法格式 fwrite(butter,size,count,fp…...

6键编程智能照明:编程指南与深度解析

6键编程智能照明&#xff1a;编程指南与深度解析 随着智能家居的普及&#xff0c;智能照明系统逐渐成为现代家庭不可或缺的一部分。而6键编程智能照明&#xff0c;以其高度的灵活性和个性化设置&#xff0c;受到了越来越多消费者的青睐。那么&#xff0c;如何对6键编程智能照明…...

sql server 中的6种约束

一、约束定义 约束是用于定义和实施表的规则和限制&#xff0c;以确保数据的完整性和一致性。 即对一张表中的属性操作进行限制。 二、约束分类 通过定义约束&#xff0c;可以对数据库中的数据进行限制&#xff0c;以下是常见的约束&#xff1a; 1. 主键约束&#xff08;Pr…...

师彼长技以助己(2)产品思维

师彼长技以助己&#xff08;2&#xff09;产品思维 前言 我把产品思维称之为&#xff1a;人生底层的能力以及蹉跎别人还蹉跎自己的能力&#xff0c;前者说明你应该具备良好产品思维原因&#xff0c;后者是你没有好的产品思维去做产品带来的灾难。 人欲即天理 请大家谈谈看到这…...

Redis学习笔记【基础篇】

SQL vs NOSQL SQL&#xff08;Structured Query Language&#xff09;和NoSQL&#xff08;Not Only SQL&#xff09;是两种不同的数据库处理方式&#xff0c;它们在多个维度上有所差异&#xff0c;主要区别包括&#xff1a; 数据结构: SQL&#xff08;关系型数据库&#xff09;…...

【文献阅读】基于模型设计的汽车软件质量属性

参考文献&#xff1a;《基于模型设计满足汽车软件质量和快速交付的挑战》&#xff0c;深向科技在2024年MATLAB XEPO大会的演讲 Tips&#xff1a;KISS原则&#xff0c;全称为“Keep It Simple, Stupid”&#xff0c;直译为“保持简单&#xff0c;愚蠢的人也能懂”...

撸广告赚金币小游戏app开发

在app上投放广告有哪些注意事项&#xff1f; 在app上投放广告需要注意以下几个方面。 首先&#xff0c;要选择合适的广告形式。根据自己的需求和目标受众&#xff0c;选择合适的广告形式&#xff0c;如横幅广告、插屏广告、视频广告等。不同的广告形式适用于不同的场景和目标…...

海外高清短视频:四川京之华锦信息技术公司

海外高清短视频&#xff1a;探索世界的新窗口 在数字化时代的浪潮下&#xff0c;海外高清短视频成为了人们探索世界、了解异国风情的新窗口。四川京之华锦信息技术公司这些短视频以其独特的视角、丰富的内容和高清的画质&#xff0c;吸引了无数观众的目光&#xff0c;让人们足…...

16:00面试,16:08就出来了,问的问题有点变态。。。

从小厂出来&#xff0c;没想到在另一家公司又寄了。 到这家公司开始上班&#xff0c;加班是每天必不可少的&#xff0c;看在钱给的比较多的份上&#xff0c;就不太计较了。没想到8月一纸通知&#xff0c;所有人不准加班&#xff0c;加班费不仅没有了&#xff0c;薪资还要降40%…...

Android MediaCodec 简明教程(九):使用 MediaCodec 解码到纹理,使用 OpenGL ES 进行处理,并编码为 MP4 文件

系列文章目录 Android MediaCodec 简明教程&#xff08;一&#xff09;&#xff1a;使用 MediaCodecList 查询 Codec 信息&#xff0c;并创建 MediaCodec 编解码器Android MediaCodec 简明教程&#xff08;二&#xff09;&#xff1a;使用 MediaCodecInfo.CodecCapabilities 查…...

Neo4j安装部署及python连接neo4j操作

Neo4j安装部署及python连接neo4j操作 Neo4j安装和环境配置 安装依赖库&#xff1a; sudo apt-get install wget curl nano software-properties-common dirmngr apt-transport-https gnupg gnupg2 ca-certificates lsb-release ubuntu-keyring unzip -y 增加Neo4 GPG key&…...

一维时间序列信号的改进小波降噪方法(MATLAB R2021B)

目前国内外对于小波分析在降噪方面的方法研究中&#xff0c;主要有小波分解与重构法降噪、小波阈值降噪、小波变换模极大值法降噪等三类方法。 (1)小波分解与重构法降噪 早在1988 年&#xff0c;Mallat提出了多分辨率分析的概念&#xff0c;利用小波分析的多分辨率特性进行分…...

Java整合EasyExcel实战——3(上下列相同合并单元格策略)

参考&#xff1a;https://juejin.cn/post/7322156759443095561?searchId202405262043517631094B7CCB463FDA06https://juejin.cn/post/7322156759443095561?searchId202405262043517631094B7CCB463FDA06 准备条件 依赖 <dependency><groupId>com.alibaba</gr…...

dmdts连接kingbase8报错

dmdts连接kingbase报错 环境介绍1 人大金仓jdbc配置2 dmdts 人大金仓jdbc默认配置3 dmdts 修改jdbc配置4 达梦产品学习使用列表 环境介绍 dts版本 使用dmdts连接kingbase金仓数据库报错 无效的URL 对比jdbc连接串,修改配置解决 1 人大金仓jdbc配置 配置URL模版信息等 类名…...

【算法训练 day44 分割等和子集】

目录 一、分割等和子集-LeetCode 416思路实现代码1.二维dp代码2.一维dp代码 问题总结 一、分割等和子集-LeetCode 416 Leecode链接: leetcode 416 文章链接: 代码随想录 视频链接: B站 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&…...

前端实习记录——git篇(一些问题与相关命令)

1、版本控制 &#xff08;1&#xff09;版本回滚 git log // 查看版本git reset --mixed HEAD^ // 回滚到修改状态&#xff0c;文件内容没有变化git reset --soft HEAD^ // 回滚暂存区&#xff0c;^的个数代表几个版本git reset --hard HEAD^ // 回滚到修改状态&#xff…...

XML Web 服务技术解析:WSDL 与 SOAP 原理、应用案例一览

XML Web服务是一种用于在网络上发布、发现和使用应用程序组件的技术。它基于一系列标准和协议&#xff0c;如WSDL、SOAP、RDF和RSS。下面是一些相关的内容&#xff1a; WSDL&#xff08;Web服务描述语言&#xff09;&#xff1a;用于描述Web服务的基于XML的语言&#xff0c;定义…...

解析Java中1000个常用类:FunctionalInterface类,你学会了吗?

Java 8 引入了一系列新的特性和改进,其中之一便是函数式编程。函数式接口(Functional Interface)是函数式编程的核心概念之一。本文将深入探讨 FunctionalInterface 注解,介绍其用法、重要性,并通过示例展示如何在实际开发中应用函数式接口。 什么是函数式接口? 函数式…...

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成

厌倦手动写WordPress文章&#xff1f;AI自动生成&#xff0c;效率提升10倍&#xff01; 支持多语言、自动配图、定时发布&#xff0c;让内容创作更轻松&#xff01; AI内容生成 → 不想每天写文章&#xff1f;AI一键生成高质量内容&#xff01;多语言支持 → 跨境电商必备&am…...

【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)

升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点&#xff0c;但无自动故障转移能力&#xff0c;Master宕机后需人工切换&#xff0c;期间消息可能无法读取。Slave仅存储数据&#xff0c;无法主动升级为Master响应请求&#xff…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

Python Ovito统计金刚石结构数量

大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...