EncryptionAttribute.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. using Org.BouncyCastle.Asn1;
  2. using Org.BouncyCastle.Asn1.Pkcs;
  3. using Org.BouncyCastle.Asn1.X509;
  4. using Org.BouncyCastle.Crypto;
  5. using Org.BouncyCastle.Crypto.Encodings;
  6. using Org.BouncyCastle.Crypto.Engines;
  7. using Org.BouncyCastle.Crypto.Generators;
  8. using Org.BouncyCastle.Crypto.Parameters;
  9. using Org.BouncyCastle.Pkcs;
  10. using Org.BouncyCastle.Security;
  11. using QWPlatform.SystemLibrary.Utils;
  12. using Org.BouncyCastle.X509;
  13. using PMS.WebUI.Controllers;
  14. using System;
  15. using System.Collections.Generic;
  16. using System.IO;
  17. using System.Linq;
  18. using System.Text;
  19. using System.Web;
  20. using System.Web.Mvc;
  21. namespace PMS.WebUI
  22. {
  23. /// <summary>
  24. /// 加密解密特性
  25. /// 支持Post入参 并且是DecryInput<>的加密 请求值必须是{"Str":"加密值"}
  26. /// 支持完全的出参加密
  27. /// </summary>
  28. public class EncryptionAttribute : ActionFilterAttribute
  29. {
  30. private static RSATool rsa = new RSATool();
  31. private static string privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJPfIxM/cGiMPSrR7v+H7Kbjpeo41GAryvetr8L6kzgGifGzv3IW/EMm/bWLW7lD8yp0ilwvELo6DaxZhzzeflJzd6AI+2zGcMAKunHalXjsYeg2SSROvk750Pfu7v/x0BiYGlRwb+zmFuEArCMmjSSIFE7aZjff9lczJecQDufbAgEDAoGAGKUwgzU9ZsIKMc2n1UFSG9Cbpwl4urH3KUedSynDNAEW/Z31Pa5/YIZ/nkHknuCohxNsZLKCybRXnLmWiiUVDXxiwcObqIrsK0Gr5v5Y+n8WfHlPAF5lBPg6twjjZCBqrnWNXbsy5mdpG1gacIv2V3E5wwAZwh2FQpGD5uK6Ug8CQQDgocjYzvU1tg8f916z+9gDk7TW/K+CCKpGDByo0GxZJAi4vTRiX82EtiE8hPvXmAcJdAFHFQfPV8P1HgMaIml1AkEAqIVMmoaETzGtYLupMIPB7kdIh3JylleG4mSREMo61iv5Hgztqt649Oobs4iEBy8Q10W7krajX38D1PB6pY6SDwJBAJXBMJCJ+M55X2qk6c1SkAJieI9TH6wFxtldaHCK8uYYBdB+Iuw/3lh5a32t/TplWgZNVi9jWoo6gqNpV2bBm6MCQHBY3bxZrYohHkB9G3WtK/Qvha+hobmPr0GYYLXcJzlyphQInnHp0KNGvSJbAq90teTZJ7ckbOpUrTigUcO0YV8CQQDeM10N8XhwkZ1nIXcSGqnkJHp7a9hRtXK8HtWkjeV5sNGPvOSIlL8aMVmcIso0vdLG5LnV+OFXOGOkHwD3qtn3";
  32. public override void OnActionExecuting(ActionExecutingContext filterContext)
  33. {
  34. base.OnActionExecuting(filterContext);
  35. var para = filterContext.ActionParameters;
  36. if (para != null && para.Count > 0)
  37. {
  38. foreach (var item in para)
  39. {
  40. var objectType = item.Value.GetType();
  41. // 检查 item.Value 是否是泛型类型 DecryInput<>
  42. if (objectType.IsGenericType && objectType.GetGenericTypeDefinition() == typeof(DecryInput<>))
  43. {
  44. // 获取 DecryInput<> 的类型参数,即 baseType
  45. var baseType = item.Value.GetType().GetGenericArguments()[0];
  46. var input = item.Value;
  47. // 使用 dynamic 以便在运行时解析 Str 属性
  48. var content = ((dynamic)input).Str;
  49. if (!string.IsNullOrEmpty(content))
  50. {
  51. // 使用 rsa.DecryptByKey 方法解密 content
  52. var newContent = rsa.DecryptByKey(content, privateKey, false);
  53. // 使用反射获取 Strings 类中的 JsonToModel<T> 方法的 MethodInfo
  54. var valueType = typeof(Strings).GetMethod("JsonToModel")
  55. // 将 baseType 作为泛型参数传递给 JsonToModel<T>
  56. .MakeGenericMethod(baseType)
  57. // 调用 JsonToModel<T>(newContent)
  58. .Invoke(null, new[] { newContent });
  59. // 设置 input 对象的 Value 属性为转换后的值
  60. input.GetType().GetProperty("Value").SetValue(input, valueType);
  61. //这两句等价于 input.Value = Strings.JsonToModel<T>(newContent);
  62. }
  63. }
  64. }
  65. }
  66. }
  67. public override void OnResultExecuting(ResultExecutingContext filterContext)
  68. {
  69. base.OnResultExecuting(filterContext);
  70. var result = filterContext.Result;
  71. if (result is ContentResult)
  72. {
  73. var contentResult = (result as ContentResult);
  74. var content = contentResult.Content;
  75. if (!string.IsNullOrEmpty(content))
  76. {
  77. contentResult.Content = rsa.EncryptByKey(content, privateKey, false);
  78. }
  79. }
  80. }
  81. }
  82. public class DecryInput<T>
  83. {
  84. public string Str { get; set; }
  85. public T Value { get; set; }
  86. }
  87. public class RSATool
  88. {
  89. /// <summary>
  90. /// KEY 结构体
  91. /// </summary>
  92. public struct RSAKEY
  93. {
  94. /// <summary>
  95. /// 公钥
  96. /// </summary>
  97. public string PublicKey { get; set; }
  98. /// <summary>
  99. /// 私钥
  100. /// </summary>
  101. public string PrivateKey { get; set; }
  102. }
  103. public RSAKEY GetKey()
  104. {
  105. //RSA密钥对的构造器
  106. RsaKeyPairGenerator keyGenerator = new RsaKeyPairGenerator();
  107. //RSA密钥构造器的参数
  108. RsaKeyGenerationParameters param = new RsaKeyGenerationParameters(
  109. Org.BouncyCastle.Math.BigInteger.ValueOf(3),
  110. new Org.BouncyCastle.Security.SecureRandom(),
  111. 1024, //密钥长度
  112. 25);
  113. //用参数初始化密钥构造器
  114. keyGenerator.Init(param);
  115. //产生密钥对
  116. AsymmetricCipherKeyPair keyPair = keyGenerator.GenerateKeyPair();
  117. //获取公钥和密钥
  118. AsymmetricKeyParameter publicKey = keyPair.Public;
  119. AsymmetricKeyParameter privateKey = keyPair.Private;
  120. SubjectPublicKeyInfo subjectPublicKeyInfo = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicKey);
  121. PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
  122. Asn1Object asn1ObjectPublic = subjectPublicKeyInfo.ToAsn1Object();
  123. byte[] publicInfoByte = asn1ObjectPublic.GetEncoded("UTF-8");
  124. Asn1Object asn1ObjectPrivate = privateKeyInfo.ToAsn1Object();
  125. byte[] privateInfoByte = asn1ObjectPrivate.GetEncoded("UTF-8");
  126. RSAKEY item = new RSAKEY()
  127. {
  128. PublicKey = Convert.ToBase64String(publicInfoByte),
  129. PrivateKey = Convert.ToBase64String(privateInfoByte)
  130. };
  131. return item;
  132. }
  133. private AsymmetricKeyParameter GetPublicKeyParameter(string s)
  134. {
  135. s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
  136. byte[] publicInfoByte = Convert.FromBase64String(s);
  137. Asn1Object pubKeyObj = Asn1Object.FromByteArray(publicInfoByte);//这里也可以从流中读取,从本地导入
  138. AsymmetricKeyParameter pubKey = PublicKeyFactory.CreateKey(publicInfoByte);
  139. return pubKey;
  140. }
  141. private AsymmetricKeyParameter GetPrivateKeyParameter(string s)
  142. {
  143. s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
  144. byte[] privateInfoByte = Convert.FromBase64String(s);
  145. // Asn1Object priKeyObj = Asn1Object.FromByteArray(privateInfoByte);//这里也可以从流中读取,从本地导入
  146. // PrivateKeyInfo privateKeyInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(privateKey);
  147. AsymmetricKeyParameter priKey = PrivateKeyFactory.CreateKey(privateInfoByte);
  148. return priKey;
  149. }
  150. /// <summary>
  151. /// 加密
  152. /// </summary>
  153. /// <param name="s"></param>
  154. /// <param name="key"></param>
  155. /// <param name="isPublic"></param>
  156. /// <returns></returns>
  157. public string EncryptByKey(string s, string key, bool isPublic)
  158. {
  159. //非对称加密算法,加解密用
  160. IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
  161. //加密
  162. try
  163. {
  164. engine.Init(true, isPublic ? GetPublicKeyParameter(key) : GetPrivateKeyParameter(key));
  165. byte[] byteData = System.Text.Encoding.UTF8.GetBytes(s);
  166. int inputLen = byteData.Length;
  167. MemoryStream ms = new MemoryStream();
  168. int offSet = 0;
  169. byte[] cache;
  170. int i = 0;
  171. // 对数据分段加密
  172. while (inputLen - offSet > 0)
  173. {
  174. if (inputLen - offSet > 117)
  175. {
  176. cache = engine.ProcessBlock(byteData, offSet, 117);
  177. }
  178. else
  179. {
  180. cache = engine.ProcessBlock(byteData, offSet, inputLen - offSet);
  181. }
  182. ms.Write(cache, 0, cache.Length);
  183. i++;
  184. offSet = i * 117;
  185. }
  186. byte[] encryptedData = ms.ToArray();
  187. //var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
  188. return Convert.ToBase64String(encryptedData);
  189. //Console.WriteLine("密文(base64编码):" + Convert.ToBase64String(testData) + Environment.NewLine);
  190. }
  191. catch (Exception ex)
  192. {
  193. return ex.Message;
  194. }
  195. }
  196. /// <summary>
  197. /// 解密
  198. /// </summary>
  199. /// <param name="s"></param>
  200. /// <param name="key"></param>
  201. /// <param name="isPublic"></param>
  202. /// <returns></returns>
  203. public string DecryptByKey(string s, string key, bool isPublic)
  204. {
  205. s = s.Replace("\r", "").Replace("\n", "").Replace(" ", "");
  206. //非对称加密算法,加解密用
  207. IAsymmetricBlockCipher engine = new Pkcs1Encoding(new RsaEngine());
  208. //加密
  209. try
  210. {
  211. engine.Init(false, isPublic ? GetPublicKeyParameter(key) : GetPrivateKeyParameter(key));
  212. byte[] byteData = Convert.FromBase64String(s);
  213. int inputLen = byteData.Length;
  214. MemoryStream ms = new MemoryStream();
  215. int offSet = 0;
  216. byte[] cache;
  217. int i = 0;
  218. // 对数据分段加密
  219. while (inputLen - offSet > 0)
  220. {
  221. if (inputLen - offSet > 128)
  222. {
  223. cache = engine.ProcessBlock(byteData, offSet, 128);
  224. }
  225. else
  226. {
  227. cache = engine.ProcessBlock(byteData, offSet, inputLen - offSet);
  228. }
  229. ms.Write(cache, 0, cache.Length);
  230. i++;
  231. offSet = i * 128;
  232. }
  233. byte[] encryptedData = ms.ToArray();
  234. //var ResultData = engine.ProcessBlock(byteData, 0, byteData.Length);
  235. return Encoding.UTF8.GetString(ms.ToArray());
  236. //Console.WriteLine("密文(base64编码):" + Convert.ToBase64String(testData) + Environment.NewLine);
  237. }
  238. catch (Exception ex)
  239. {
  240. return ex.Message;
  241. }
  242. }
  243. /// <summary>
  244. /// 签名
  245. /// </summary>
  246. /// <param name="data">数据</param>
  247. /// <param name="key">密匙</param>
  248. /// <returns></returns>
  249. public string SignByPrivateKey(string data, string key)
  250. {
  251. AsymmetricKeyParameter priKey = GetPrivateKeyParameter(key);
  252. byte[] byteData = System.Text.Encoding.UTF8.GetBytes(data);
  253. ISigner normalSig = SignerUtilities.GetSigner("SHA1WithRSA");
  254. normalSig.Init(true, priKey);
  255. normalSig.BlockUpdate(byteData, 0, data.Length);
  256. byte[] normalResult = normalSig.GenerateSignature(); //签名结果
  257. return Convert.ToBase64String(normalResult);
  258. //return System.Text.Encoding.UTF8.GetString(normalResult);
  259. }
  260. /// <summary>
  261. /// 验签
  262. /// </summary>
  263. /// <param name="plainData">验证数据</param>
  264. /// <param name="sign">签名</param>
  265. /// <param name="key">公匙</param>
  266. /// <returns></returns>
  267. public bool ValidationPublicKey(string plainData, string sign, string key)
  268. {
  269. AsymmetricKeyParameter priKey = GetPublicKeyParameter(key);
  270. byte[] signBytes = Convert.FromBase64String(sign);
  271. byte[] plainBytes = Encoding.UTF8.GetBytes(plainData);
  272. ISigner verifier = SignerUtilities.GetSigner("SHA1WithRSA");
  273. verifier.Init(false, priKey);
  274. verifier.BlockUpdate(plainBytes, 0, plainBytes.Length);
  275. return verifier.VerifySignature(signBytes); //验签结果
  276. }
  277. }
  278. }