RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密

RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。 RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。

.NET提供常用的加密算法类,支持RSA的类是RSACryptoServiceProvider(命名空间:System.Security.Cryptography),但只支持公钥加密,私钥解密。RSACryptoServiceProvider类包括:Modulus、Exponent、P、Q、DP、DQ、InverseQ、D等8个属性,其中Modulus和Exponent就是公钥,Modulus和D就是私钥,RSACryptoServiceProvider类提供导出公钥的方法,也提供导出私钥的方法,但导出的私钥包含上面8个属性RSA不对称加密,公钥加密私钥解密,私钥加密公钥解密,显然要用RSACryptoServiceProvider实现私钥加密公钥是不可行的。

从RSA的原理来看,公钥加密私钥解密和私钥加密公钥解密应该是等价的,在某些情况下,比如共享软件加密,我们需要用私钥加密注册码或注册文件,发给用户,用户用公钥解密注册码或注册文件进行合法性验证。

不对称密钥

.NET Framework 为不对称加密提供了 RSACryptoServiceProvider 和 DSACryptoServiceProvider 类。这些类在您使用默认构造函数创建新实例时创建一个公钥/私钥对。既可以存储不对称密钥以用在多个会话中,也可以只为一个会话生成不对称密钥。公钥可以被广泛地使用,私钥应被严密地保护起来。

每当创建不对称算法类的新实例时,都生成一个公钥/私钥对。创建该类的新实例后,可以用以下两种方法之一提取密钥信息:

两个方法都接受布尔值,该值指示是只返回公钥信息还是同时返回公钥和私钥信息。通过使用 ImportParameters 方法,可以将 RSACryptoServiceProvider 类初始化为 RSAParameters 结构的值。

下面的代码示例创建 RSACryptoServiceProvider 类的一个新实例,创建一个公钥/私钥对,并将公钥信息保存在RSAParameters 结构中

  1. //Generate a public/private key pair.
  2. RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
  3. //Save the public key information to an RSAParameters structure.
  4. RSAParameters RSAKeyInfo = RSA.ExportParameters(false);

一、公钥加密私钥解密

  1. /// <summary>
  2. /// 公钥加密,私钥解密
  3. /// </summary>
  4. public class RSAEncryptHelper
  5. {
  6. /// <summary>
  7. /// 将字符串使用base64算法加密
  8. /// </summary>
  9. /// <param name="code_type">编码类型</param>
  10. /// <param name="code">待加密的字符串</param>
  11. /// <returns>加密后的字符串</returns>
  12. public string EncodeBase64(string code_type, string code)
  13. {
  14. string encode = "";
  15. byte[] bytes = Encoding.GetEncoding(code_type).GetBytes(code); //将一组字符编码为一个字节序列.
  16. try
  17. {
  18. encode = Convert.ToBase64String(bytes); //将8位无符号整数数组的子集转换为其等效的,以64为基的数字编码的字符串形式.
  19. }
  20. catch
  21. {
  22. encode = code;
  23. }
  24. return encode;
  25. }
  26. /// <summary>
  27. /// 将字符串使用base64算法解密
  28. /// </summary>
  29. /// <param name="code_type">编码类型</param>
  30. /// <param name="code">已用base64算法加密的字符串</param>
  31. /// <returns>解密后的字符串</returns>
  32. public string DecodeBase64(string code_type, string code)
  33. {
  34. string decode = "";
  35. byte[] bytes = Convert.FromBase64String(code); //将2进制编码转换为8位无符号整数数组.
  36. try
  37. {
  38. decode = Encoding.GetEncoding(code_type).GetString(bytes); //将指定字节数组中的一个字节序列解码为一个字符串。
  39. }
  40. catch
  41. {
  42. decode = code;
  43. }
  44. return decode;
  45. }
  46. /// <summary>
  47. /// 获取本机的MAC地址
  48. /// </summary>
  49. /// <returns></returns>
  50. public static string GetLocalMac()
  51. {
  52. string mac = null;
  53. ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration");
  54. ManagementObjectCollection queryCollection = query.Get();
  55. foreach (ManagementObject mo in queryCollection)
  56. {
  57. if (mo["IPEnabled"].ToString() == "True")
  58. mac = mo["MacAddress"].ToString();
  59. }
  60. return (mac);
  61. }
  62. /// <summary>
  63. /// 得到CPU序列号
  64. /// </summary>
  65. /// <returns></returns>
  66. public static string GetCpuID()
  67. {
  68. try
  69. {
  70. //获取CPU序列号代码
  71. string cpuInfo = "";//cpu序列号
  72. ManagementClass mc = new ManagementClass("Win32_Processor");
  73. ManagementObjectCollection moc = mc.GetInstances();
  74. foreach (ManagementObject mo in moc)
  75. {
  76. cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
  77. }
  78. moc = null;
  79. mc = null;
  80. return cpuInfo;
  81. }
  82. catch
  83. {
  84. return "unknow";
  85. }
  86. finally
  87. {
  88. }
  89. }
  90. /// <summary>
  91. /// 生成公私钥
  92. /// </summary>
  93. /// <param name="PrivateKeyPath"></param>
  94. /// <param name="PublicKeyPath"></param>
  95. public void RSAKey(string PrivateKeyPath, string PublicKeyPath)
  96. {
  97. try
  98. {
  99. RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
  100. this.CreatePrivateKeyXML(PrivateKeyPath, provider.ToXmlString(true));
  101. this.CreatePublicKeyXML(PublicKeyPath, provider.ToXmlString(false));
  102. }
  103. catch (Exception exception)
  104. {
  105. throw exception;
  106. }
  107. }
  108. /// <summary>
  109. /// 对原始数据进行MD5加密
  110. /// </summary>
  111. /// <param name="m_strSource">待加密数据</param>
  112. /// <returns>返回机密后的数据</returns>
  113. public string GetHash(string m_strSource)
  114. {
  115. HashAlgorithm algorithm = HashAlgorithm.Create("MD5");
  116. byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(m_strSource);
  117. byte[] inArray = algorithm.ComputeHash(bytes);
  118. return Convert.ToBase64String(inArray);
  119. }
  120. /// <summary>
  121. /// RSA加密
  122. /// </summary>
  123. /// <param name="xmlPublicKey">公钥</param>
  124. /// <param name="m_strEncryptString">MD5加密后的数据</param>
  125. /// <returns>RSA公钥加密后的数据</returns>
  126. public string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
  127. {
  128. string str2;
  129. try
  130. {
  131. RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
  132. provider.FromXmlString(xmlPublicKey);
  133. byte[] bytes = new UnicodeEncoding().GetBytes(m_strEncryptString);
  134. str2 = Convert.ToBase64String(provider.Encrypt(bytes, false));
  135. }
  136. catch (Exception exception)
  137. {
  138. throw exception;
  139. }
  140. return str2;
  141. }
  142. /// <summary>
  143. /// RSA解密
  144. /// </summary>
  145. /// <param name="xmlPrivateKey">私钥</param>
  146. /// <param name="m_strDecryptString">待解密的数据</param>
  147. /// <returns>解密后的结果</returns>
  148. public string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)
  149. {
  150. string str2;
  151. try
  152. {
  153. RSACryptoServiceProvider provider = new RSACryptoServiceProvider();
  154. provider.FromXmlString(xmlPrivateKey);
  155. byte[] rgb = Convert.FromBase64String(m_strDecryptString);
  156. byte[] buffer2 = provider.Decrypt(rgb, false);
  157. str2 = new UnicodeEncoding().GetString(buffer2);
  158. }
  159. catch (Exception exception)
  160. {
  161. throw exception;
  162. }
  163. return str2;
  164. }
  165. /// <summary>
  166. /// 对MD5加密后的密文进行签名
  167. /// </summary>
  168. /// <param name="p_strKeyPrivate">私钥</param>
  169. /// <param name="m_strHashbyteSignature">MD5加密后的密文</param>
  170. /// <returns></returns>
  171. public string SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature)
  172. {
  173. byte[] rgbHash = Convert.FromBase64String(m_strHashbyteSignature);
  174. RSACryptoServiceProvider key = new RSACryptoServiceProvider();
  175. key.FromXmlString(p_strKeyPrivate);
  176. RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
  177. formatter.SetHashAlgorithm("MD5");
  178. byte[] inArray = formatter.CreateSignature(rgbHash);
  179. return Convert.ToBase64String(inArray);
  180. }
  181. /// <summary>
  182. /// 签名验证
  183. /// </summary>
  184. /// <param name="p_strKeyPublic">公钥</param>
  185. /// <param name="p_strHashbyteDeformatter">待验证的用户名</param>
  186. /// <param name="p_strDeformatterData">注册码</param>
  187. /// <returns></returns>
  188. public bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, string p_strDeformatterData)
  189. {
  190. try
  191. {
  192. byte[] rgbHash = Convert.FromBase64String(p_strHashbyteDeformatter);
  193. RSACryptoServiceProvider key = new RSACryptoServiceProvider();
  194. key.FromXmlString(p_strKeyPublic);
  195. RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
  196. deformatter.SetHashAlgorithm("MD5");
  197. byte[] rgbSignature = Convert.FromBase64String(p_strDeformatterData);
  198. if (deformatter.VerifySignature(rgbHash, rgbSignature))
  199. {
  200. return true;
  201. }
  202. return false;
  203. }
  204. catch
  205. {
  206. return false;
  207. }
  208. }
  209. /// <summary>
  210. /// 获取硬盘ID
  211. /// </summary>
  212. /// <returns>硬盘ID</returns>
  213. public string GetHardID()
  214. {
  215. string HDInfo = "";
  216. ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive");
  217. ManagementObjectCollection moc1 = cimobject1.GetInstances();
  218. foreach (ManagementObject mo in moc1)
  219. {
  220. HDInfo = (string)mo.Properties["Model"].Value;
  221. }
  222. return HDInfo;
  223. }
  224. /// <summary>
  225. /// 读注册表中指定键的值
  226. /// </summary>
  227. /// <param name="key">键名</param>
  228. /// <returns>返回键值</returns>
  229. private string ReadReg(string key)
  230. {
  231. string temp = "";
  232. try
  233. {
  234. RegistryKey myKey = Registry.LocalMachine;
  235. RegistryKey subKey = myKey.OpenSubKey(@"SOFTWARE/JX/Register");
  236. temp = subKey.GetValue(key).ToString();
  237. subKey.Close();
  238. myKey.Close();
  239. return temp;
  240. }
  241. catch (Exception)
  242. {
  243. throw;//可能没有此注册项;
  244. }
  245. }
  246. /// <summary>
  247. /// 创建注册表中指定的键和值
  248. /// </summary>
  249. /// <param name="key">键名</param>
  250. /// <param name="value">键值</param>
  251. private void WriteReg(string key, string value)
  252. {
  253. try
  254. {
  255. RegistryKey rootKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");
  256. rootKey.SetValue(key, value);
  257. rootKey.Close();
  258. }
  259. catch (Exception)
  260. {
  261. throw;
  262. }
  263. }
  264. /// <summary>
  265. /// 创建公钥文件
  266. /// </summary>
  267. /// <param name="path"></param>
  268. /// <param name="publickey"></param>
  269. public void CreatePublicKeyXML(string path, string publickey)
  270. {
  271. try
  272. {
  273. FileStream publickeyxml = new FileStream(path, FileMode.Create);
  274. StreamWriter sw = new StreamWriter(publickeyxml);
  275. sw.WriteLine(publickey);
  276. sw.Close();
  277. publickeyxml.Close();
  278. }
  279. catch
  280. {
  281. throw;
  282. }
  283. }
  284. /// <summary>
  285. /// 创建私钥文件
  286. /// </summary>
  287. /// <param name="path"></param>
  288. /// <param name="privatekey"></param>
  289. public void CreatePrivateKeyXML(string path, string privatekey)
  290. {
  291. try
  292. {
  293. FileStream privatekeyxml = new FileStream(path, FileMode.Create);
  294. StreamWriter sw = new StreamWriter(privatekeyxml);
  295. sw.WriteLine(privatekey);
  296. sw.Close();
  297. privatekeyxml.Close();
  298. }
  299. catch
  300. {
  301. throw;
  302. }
  303. }
  304. /// <summary>
  305. /// 读取公钥
  306. /// </summary>
  307. /// <param name="path"></param>
  308. /// <returns></returns>
  309. public string ReadPublicKey(string path)
  310. {
  311. StreamReader reader = new StreamReader(path);
  312. string publickey = reader.ReadToEnd();
  313. reader.Close();
  314. return publickey;
  315. }
  316. /// <summary>
  317. /// 读取私钥
  318. /// </summary>
  319. /// <param name="path"></param>
  320. /// <returns></returns>
  321. public string ReadPrivateKey(string path)
  322. {
  323. StreamReader reader = new StreamReader(path);
  324. string privatekey = reader.ReadToEnd();
  325. reader.Close();
  326. return privatekey;
  327. }
  328. /// <summary>
  329. /// 初始化注册表,程序运行时调用,在调用之前更新公钥xml
  330. /// </summary>
  331. /// <param name="path">公钥路径</param>
  332. public void InitialReg(string path)
  333. {
  334. Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");
  335. Random ra = new Random();
  336. string publickey = this.ReadPublicKey(path);
  337. if (Registry.LocalMachine.OpenSubKey(@"SOFTWARE/JX/Register").ValueCount <= 0)
  338. {
  339. this.WriteReg("RegisterRandom", ra.Next(1, 100000).ToString());
  340. this.WriteReg("RegisterPublicKey", publickey);
  341. }
  342. else
  343. {
  344. this.WriteReg("RegisterPublicKey", publickey);
  345. }
  346. }
  347. }

二、私钥加密公钥解密

  1. /// <summary>
  2. /// 非对称RSA加密类 可以参考
  3. /// http://www.cnblogs.com/hhh/archive/2011/06/03/2070692.html
  4. /// http://blog.csdn.net/zhilunchen/article/details/2943158
  5. /// http://www.cnblogs.com/yyl8781697/archive/2013/04/28/RSA.html
  6. /// 若是私匙加密 则需公钥解密
  7. /// 反正公钥加密 私匙来解密
  8. /// 需要BigInteger类来辅助
  9. /// </summary>
  10. public static class RSAHelper
  11. {
  12. /// <summary>
  13. /// RSA的容器 可以解密的源字符串长度为 DWKEYSIZE/8-11
  14. /// </summary>
  15. public const int DWKEYSIZE = 1024;
  16. /// <summary>
  17. /// RSA加密的密匙结构  公钥和私匙
  18. /// </summary>
  19. //public struct RSAKey
  20. //{
  21. //    public string PublicKey { get; set; }
  22. //    public string PrivateKey { get; set; }
  23. //}
  24. #region 得到RSA的解谜的密匙对
  25. /// <summary>
  26. /// 得到RSA的解谜的密匙对
  27. /// </summary>
  28. /// <returns></returns>
  29. //public static RSAKey GetRASKey()
  30. //{
  31. //    RSACryptoServiceProvider.UseMachineKeyStore = true;
  32. //    //声明一个指定大小的RSA容器
  33. //    RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(DWKEYSIZE);
  34. //    //取得RSA容易里的各种参数
  35. //    RSAParameters p = rsaProvider.ExportParameters(true);
  36. //    return new RSAKey()
  37. //    {
  38. //        PublicKey = ComponentKey(p.Exponent, p.Modulus),
  39. //        PrivateKey = ComponentKey(p.D, p.Modulus)
  40. //    };
  41. //}
  42. #endregion
  43. #region 检查明文的有效性 DWKEYSIZE/8-11 长度之内为有效 中英文都算一个字符
  44. /// <summary>
  45. /// 检查明文的有效性 DWKEYSIZE/8-11 长度之内为有效 中英文都算一个字符
  46. /// </summary>
  47. /// <param name="source"></param>
  48. /// <returns></returns>
  49. public static bool CheckSourceValidate(string source)
  50. {
  51. return (DWKEYSIZE / 8 - 11) >= source.Length;
  52. }
  53. #endregion
  54. #region 组合解析密匙
  55. /// <summary>
  56. /// 组合成密匙字符串
  57. /// </summary>
  58. /// <param name="b1"></param>
  59. /// <param name="b2"></param>
  60. /// <returns></returns>
  61. public static string ComponentKey(byte[] b1, byte[] b2)
  62. {
  63. List<byte> list = new List<byte>();
  64. //在前端加上第一个数组的长度值 这样今后可以根据这个值分别取出来两个数组
  65. list.Add((byte)b1.Length);
  66. list.AddRange(b1);
  67. list.AddRange(b2);
  68. byte[] b = list.ToArray<byte>();
  69. return Convert.ToBase64String(b);
  70. }
  71. /// <summary>
  72. /// 解析密匙
  73. /// </summary>
  74. /// <param name="key">密匙</param>
  75. /// <param name="b1">RSA的相应参数1</param>
  76. /// <param name="b2">RSA的相应参数2</param>
  77. private static void ResolveKey(string key, out byte[] b1, out byte[] b2)
  78. {
  79. //从base64字符串 解析成原来的字节数组
  80. byte[] b = Convert.FromBase64String(key);
  81. //初始化参数的数组长度
  82. b1 = new byte[b[0]];
  83. b2 = new byte[b.Length - b[0] - 1];
  84. //将相应位置是值放进相应的数组
  85. for (int n = 1, i = 0, j = 0; n < b.Length; n++)
  86. {
  87. if (n <= b[0])
  88. {
  89. b1[i++] = b[n];
  90. }
  91. else
  92. {
  93. b2[j++] = b[n];
  94. }
  95. }
  96. }
  97. #endregion
  98. #region 字符串加密解密 公开方法
  99. /// <summary>
  100. /// 字符串加密
  101. /// </summary>
  102. /// <param name="source">源字符串 明文</param>
  103. /// <param name="key">密匙</param>
  104. /// <returns>加密遇到错误将会返回原字符串</returns>
  105. public static string EncryptString(string source, string key)
  106. {
  107. string encryptString = string.Empty;
  108. byte[] d;
  109. byte[] n;
  110. try
  111. {
  112. if (!CheckSourceValidate(source))
  113. {
  114. throw new Exception("source string too long");
  115. }
  116. //解析这个密钥
  117. ResolveKey(key, out d, out n);
  118. BigInteger biN = new BigInteger(n);
  119. BigInteger biD = new BigInteger(d);
  120. encryptString = EncryptString(source, biD, biN);
  121. }
  122. catch
  123. {
  124. encryptString = source;
  125. }
  126. return encryptString;
  127. }
  128. /// <summary>
  129. /// 字符串解密
  130. /// </summary>
  131. /// <param name="encryptString">密文</param>
  132. /// <param name="key">密钥</param>
  133. /// <returns>遇到解密失败将会返回空字符串</returns>
  134. public static string DecryptString(string encryptString, string key)
  135. {
  136. string source = string.Empty;
  137. byte[] e;
  138. byte[] n;
  139. try
  140. {
  141. //解析这个密钥
  142. ResolveKey(key, out e, out n);
  143. BigInteger biE = new BigInteger(e);
  144. BigInteger biN = new BigInteger(n);
  145. source = DecryptString(encryptString, biE, biN);
  146. }
  147. catch
  148. {
  149. }
  150. return source;
  151. }
  152. #endregion
  153. #region 字符串加密解密 私有  实现加解密的实现方法
  154. /// <summary>
  155. /// 用指定的密匙加密
  156. /// </summary>
  157. /// <param name="source">明文</param>
  158. /// <param name="d">可以是RSACryptoServiceProvider生成的D</param>
  159. /// <param name="n">可以是RSACryptoServiceProvider生成的Modulus</param>
  160. /// <returns>返回密文</returns>
  161. private static string EncryptString(string source, BigInteger d, BigInteger n)
  162. {
  163. int len = source.Length;
  164. int len1 = 0;
  165. int blockLen = 0;
  166. if ((len % 128) == 0)
  167. len1 = len / 128;
  168. else
  169. len1 = len / 128 + 1;
  170. string block = "";
  171. StringBuilder result = new StringBuilder();
  172. for (int i = 0; i < len1; i++)
  173. {
  174. if (len >= 128)
  175. blockLen = 128;
  176. else
  177. blockLen = len;
  178. block = source.Substring(i * 128, blockLen);
  179. byte[] oText = System.Text.Encoding.Default.GetBytes(block);
  180. BigInteger biText = new BigInteger(oText);
  181. BigInteger biEnText = biText.modPow(d, n);
  182. string temp = biEnText.ToHexString();
  183. result.Append(temp).Append("@");
  184. len -= blockLen;
  185. }
  186. return result.ToString().TrimEnd('@');
  187. }
  188. /// <summary>
  189. /// 用指定的密匙加密
  190. /// </summary>
  191. /// <param name="source">密文</param>
  192. /// <param name="e">可以是RSACryptoServiceProvider生成的Exponent</param>
  193. /// <param name="n">可以是RSACryptoServiceProvider生成的Modulus</param>
  194. /// <returns>返回明文</returns>
  195. private static string DecryptString(string encryptString, BigInteger e, BigInteger n)
  196. {
  197. StringBuilder result = new StringBuilder();
  198. string[] strarr1 = encryptString.Split(new char[] { '@' }, StringSplitOptions.RemoveEmptyEntries);
  199. for (int i = 0; i < strarr1.Length; i++)
  200. {
  201. string block = strarr1[i];
  202. BigInteger biText = new BigInteger(block, 16);
  203. BigInteger biEnText = biText.modPow(e, n);
  204. string temp = System.Text.Encoding.Default.GetString(biEnText.getBytes());
  205. result.Append(temp);
  206. }
  207. return result.ToString();
  208. }
  209. #endregion
  210. /// <summary>
  211. /// 将字符串使用base64算法加密
  212. /// </summary>
  213. /// <param name="code_type">编码类型</param>
  214. /// <param name="code">待加密的字符串</param>
  215. /// <returns>加密后的字符串</returns>
  216. public static string EncodeBase64(string code_type, string code)
  217. {
  218. string encode = "";
  219. byte[] bytes = Encoding.GetEncoding(code_type).GetBytes(code); //将一组字符编码为一个字节序列.
  220. try
  221. {
  222. encode = Convert.ToBase64String(bytes); //将8位无符号整数数组的子集转换为其等效的,以64为基的数字编码的字符串形式.
  223. }
  224. catch
  225. {
  226. encode = code;
  227. }
  228. return encode;
  229. }
  230. /// <summary>
  231. /// 将字符串使用base64算法解密
  232. /// </summary>
  233. /// <param name="code_type">编码类型</param>
  234. /// <param name="code">已用base64算法加密的字符串</param>
  235. /// <returns>解密后的字符串</returns>
  236. public static string DecodeBase64(string code_type, string code)
  237. {
  238. string decode = "";
  239. byte[] bytes = Convert.FromBase64String(code); //将2进制编码转换为8位无符号整数数组.
  240. try
  241. {
  242. decode = Encoding.GetEncoding(code_type).GetString(bytes); //将指定字节数组中的一个字节序列解码为一个字符串。
  243. }
  244. catch
  245. {
  246. decode = code;
  247. }
  248. return decode;
  249. }
  250. /// <summary>
  251. /// 读取公钥或私钥
  252. /// </summary>
  253. /// <param name="includePrivateparameters">为True则包含私钥</param>
  254. /// <param name="path">Xml格式保存的完整公/私钥路径</param>
  255. /// <returns>公钥或私钥参数形式 </returns>
  256. public static RSAParameters ReadKey(bool includePrivateparameters,string path)
  257. {
  258. using (StreamReader reader = new StreamReader(path))
  259. {
  260. string publickey = reader.ReadToEnd();
  261. RSACryptoServiceProvider rcp = new RSACryptoServiceProvider();
  262. rcp.FromXmlString(publickey);
  263. return rcp.ExportParameters(includePrivateparameters);
  264. }
  265. }
  266. /// <summary>
  267. /// 获取本机的MAC地址
  268. /// </summary>
  269. /// <returns></returns>
  270. public static string GetLocalMac()
  271. {
  272. string mac = null;
  273. ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_NetworkAdapterConfiguration");
  274. ManagementObjectCollection queryCollection = query.Get();
  275. foreach (ManagementObject mo in queryCollection)
  276. {
  277. if (mo["IPEnabled"].ToString() == "True")
  278. mac = mo["MacAddress"].ToString();
  279. }
  280. return (mac);
  281. }
  282. /// <summary>
  283. /// 得到CPU序列号
  284. /// </summary>
  285. /// <returns></returns>
  286. public static string GetCpuID()
  287. {
  288. try
  289. {
  290. //获取CPU序列号代码
  291. string cpuInfo = "";//cpu序列号
  292. ManagementClass mc = new ManagementClass("Win32_Processor");
  293. ManagementObjectCollection moc = mc.GetInstances();
  294. foreach (ManagementObject mo in moc)
  295. {
  296. cpuInfo = mo.Properties["ProcessorId"].Value.ToString();
  297. }
  298. moc = null;
  299. mc = null;
  300. return cpuInfo;
  301. }
  302. catch
  303. {
  304. return "unknow";
  305. }
  306. finally
  307. {
  308. }
  309. }
  310. /// <summary>
  311. /// 获取硬盘ID
  312. /// </summary>
  313. /// <returns>硬盘ID</returns>
  314. public static string GetHardID()
  315. {
  316. string HDInfo = "";
  317. ManagementClass cimobject1 = new ManagementClass("Win32_DiskDrive");
  318. ManagementObjectCollection moc1 = cimobject1.GetInstances();
  319. foreach (ManagementObject mo in moc1)
  320. {
  321. HDInfo = (string)mo.Properties["Model"].Value;
  322. }
  323. return HDInfo;
  324. }
  325. /// <summary>
  326. /// 读注册表中指定键的值
  327. /// </summary>
  328. /// <param name="key">键名</param>
  329. /// <returns>返回键值</returns>
  330. private static string ReadReg(string key)
  331. {
  332. string temp = "";
  333. try
  334. {
  335. RegistryKey myKey = Registry.LocalMachine;
  336. RegistryKey subKey = myKey.OpenSubKey(@"SOFTWARE/JX/Register");
  337. temp = subKey.GetValue(key).ToString();
  338. subKey.Close();
  339. myKey.Close();
  340. return temp;
  341. }
  342. catch (Exception)
  343. {
  344. throw;//可能没有此注册项;
  345. }
  346. }
  347. /// <summary>
  348. /// 创建注册表中指定的键和值
  349. /// </summary>
  350. /// <param name="key">键名</param>
  351. /// <param name="value">键值</param>
  352. private static void WriteReg(string key, string value)
  353. {
  354. try
  355. {
  356. RegistryKey rootKey = Registry.LocalMachine.CreateSubKey(@"SOFTWARE/JX/Register");
  357. rootKey.SetValue(key, value);
  358. rootKey.Close();
  359. }
  360. catch (Exception)
  361. {
  362. throw;
  363. }
  364. }
  365. }

使用场景:如共享软件加密,我们需要用私钥加密注册码或注册文件,发给用户,用户用公钥解密注册码或注册文件进行合法性验证。

RSA算法实现激活码注册方式的原理如下:

1. 生成一对公钥E和私钥D(供软件注册模板和注册机使用);

2. 用户安装软件后,软件注册模板提取用户机器指纹信息(如:MAC地址、CPU序列号、硬盘序列号等),并通过其它的编码算法(如BASE64)生成一个申请码C;

3. 用户将申请码C发给软件开发商。软件开发商通过注册机采用私钥D加密申请码C后生成激活码F。软件供应商将激活码F发给用户。

4. 用户输入激活码F,软件注册模板采用公钥E对激活码F解码后生成G(即:用户机器特征信息),然后软件注册模板提取用户机器的特定信息后进行编码。将编码的结果与G进行比较,如果相等则用户合法,完成授权,否则授权失败。

  1. //应用程序注册模块
  2. public partial class Form1 : Form
  3. {
  4. public Form1()
  5. {
  6. InitializeComponent();
  7. }
  8. private void Form1_Load(object sender, EventArgs e)
  9. {
  10. string cpu = RSAHelper.GetCpuID();
  11. string _申请码C = RSAHelper.EncodeBase64("utf-8", cpu);
  12. textEdit申请码.Text = _申请码C;
  13. }
  14. private void simpleButton注册_Click(object sender, EventArgs e)
  15. {
  16. string publicKeyPath = @"C://PublicKey.xml";
  17. RSAParameters pm = RSAHelper.ReadKey(false, publicKeyPath);
  18. string _PublicKey = RSAHelper.ComponentKey(pm.Exponent, pm.Modulus);
  19. string cpu = RSAHelper.DecryptString(textEdit激活码.Text, _PublicKey);
  20. if (cpu == textEdit申请码.Text)
  21. {
  22. MessageBox.Show("注册成功");
  23. }
  24. else
  25. {
  26. MessageBox.Show("注册失败");
  27. }
  28. }
  29. }
    1. /// <summary>
    2. /// 注册机
    3. /// </summary>
    4. public partial class Form1 : Form
    5. {
    6. public Form1()
    7. {
    8. InitializeComponent();
    9. }
    10. private void simpleButton生成激活码_Click(object sender, EventArgs e)
    11. {
    12. string privateKeyPath = @"C://PrivateKey.xml";
    13. RSAParameters pm = RSAHelper.ReadKey(true, privateKeyPath);
    14. string _PrivateKey = RSAHelper.ComponentKey(pm.D, pm.Modulus);
    15. textEdit激活码.Text = RSAHelper.EncryptString(textEdit申请码.Text, _PrivateKey);
    16. }
    17. }
上一篇:Java进阶开发-基于Base64的加密与解密操作


下一篇:Codeforces Round #342 (Div. 2)-A. Guest From the Past