/// <summary> /// 人为素数的密钥生成方法 如果参数不能通过素性检测则抛出异常 /// </summary> /// <param name="p"></param> /// <param name="q"></param> /// <returns></returns> public static BigInteger[] GenKey(ulong p, ulong q) { PrimeGen pgen = new PrimeGen(); if (!pgen.RabinMiller(p, 100)) { throw new NotPrimeNumberException(p.ToString()); } if (!pgen.RabinMiller(q, 100)) { throw new NotPrimeNumberException(q.ToString()); } BigInteger N = p * q; BigInteger r = (p - 1) * (q - 1); BigInteger e = pgen.Gen(); e %= r; while (RSA_Math.SteinGCD(e, r) != 1) { e = pgen.Gen(); e %= r; } BigInteger d = RSA_Math.ExEuclid(e, r); return(new BigInteger[] { N, e, d }); }
/// <summary> /// RSA密钥生成方法 除密钥外还返回了大素数p和q /// </summary> /// <returns>[n e d p q]</returns> public static BigInteger[] GenKeyAdd() { PrimeGen pgen = new PrimeGen(); BigInteger p = pgen.Gen(); BigInteger q = pgen.Gen(); BigInteger N = p * q; BigInteger r = (p - 1) * (q - 1); BigInteger e = pgen.Gen(); e %= r; while (RSA_Math.SteinGCD(e, r) != 1) { e = pgen.Gen(); e %= r; } BigInteger d = RSA_Math.ExEuclid(e, r); return(new BigInteger[] { N, e, d, p, q }); }
/// <summary> /// Rabin-Miller素性检测 /// </summary> /// <param name="biN">被检数</param> /// <param name="iK">测试轮数 默认50</param> /// <returns>true:biN为素数,false:biN不是素数</returns> public bool RabinMiller(BigInteger biN, int iK = 50) { if ((biN & 1) == 0) { return(false); } BigInteger s = 0, i = 1; BigInteger t = biN - 1; while ((t & 1) == 0) { t >>= 1; ++s; } while (iK-- != 0) { RNGCryptoServiceProvider csp = new RNGCryptoServiceProvider(); byte[] baCsp = new byte[8]; csp.GetNonZeroBytes(baCsp); BigInteger b = BitConverter.ToUInt64(baCsp, 0) % (biN - 2) + 2; BigInteger y = RSA_Math.RepeatMod(b, t, biN); if (y == 1) { return(true); } while (y != biN - 1) { if (i == s) { return(false); } y = RSA_Math.RepeatMod(y, 2, biN); ++i; } } return(true); }
/// <summary> /// RSA解密基本方法 /// </summary> /// <param name="biCipher"></param> /// <param name="d"></param> /// <param name="N"></param> /// <returns></returns> public static BigInteger Decrypt(BigInteger biCipher, BigInteger d, BigInteger N) { return(RSA_Math.RepeatMod(biCipher, d, N)); }
/// <summary> /// RSA加密基本方法 /// </summary> /// <param name="biPlain"></param> /// <param name="e"></param> /// <param name="N"></param> /// <returns></returns> public static BigInteger Encrypt(BigInteger biPlain, BigInteger e, BigInteger N) { return(RSA_Math.RepeatMod(biPlain, e, N)); }