C# 根据私有指数(d)、公共指数(e)和模(n)计算素数p和q
如何根据e公钥、d私钥和模数计算p和q参数 我手头有大整数键,我可以将粘贴复制到代码中。一个公钥、一个私钥和一个模数 我需要从这里计算RSA参数p和q。但我怀疑有一个图书馆是我用谷歌找不到的。有什么想法吗?谢谢 这不一定是暴力,因为我不是在寻找私钥。我只是有一个遗留系统,它存储了一个公钥、私钥对和一个模数,我需要将它们输入到c中,以便与RSACryptoServiceProvider一起使用 所以归结起来就是通过C# 根据私有指数(d)、公共指数(e)和模(n)计算素数p和q,c#,cryptography,rsa,C#,Cryptography,Rsa,如何根据e公钥、d私钥和模数计算p和q参数 我手头有大整数键,我可以将粘贴复制到代码中。一个公钥、一个私钥和一个模数 我需要从这里计算RSA参数p和q。但我怀疑有一个图书馆是我用谷歌找不到的。有什么想法吗?谢谢 这不一定是暴力,因为我不是在寻找私钥。我只是有一个遗留系统,它存储了一个公钥、私钥对和一个模数,我需要将它们输入到c中,以便与RSACryptoServiceProvider一起使用 所以归结起来就是通过 public BigInteger _pPlusq() {
public BigInteger _pPlusq()
{
int k = (this.getExponent() * this.getD() / this.getModulus()).IntValue();
BigInteger phiN = (this.getExponent() * this.getD() - 1) / k;
return phiN - this.getModulus() - 1;
}
但这似乎不起作用。你能发现问题吗
5小时后…:
嗯。如何从C中的Zn*中选择一个随机数 假设e很小,这是常见的情况;传统的公众指数是65537。我们还假设ed=1 mod phin,其中phin=p-1q-1,这不一定是这种情况;RSA要求ed=1模lcmp-1,q-1和phin仅为lcmp-1,q-1的倍数
现在对于某个整数k,有ed=k*phin+1。因为d比phin小,你知道k
// Step 1: Let k = de – 1. If k is odd, then go to Step 4
BigInteger k = d.multiply(e).subtract(ONE);
if (isEven(k)) {
// Step 2 (express k as (2^t)r, where r is the largest odd integer
// dividing k and t >= 1)
BigInteger r = k;
BigInteger t = ZERO;
do {
r = r.divide(TWO);
t = t.add(ONE);
} while (isEven(r));
// Step 3
Random random = new Random();
boolean success = false;
BigInteger y = null;
step3loop: for (int i = 1; i <= 100; i++) {
// 3a
BigInteger g = getRandomBi(n, random);
// 3b
y = g.modPow(r, n);
// 3c
if (y.equals(ONE) || y.equals(n.subtract(ONE))) {
// 3g
continue step3loop;
}
// 3d
for (BigInteger j = ONE; j.compareTo(t) <= 0; j = j.add(ONE)) {
// 3d1
BigInteger x = y.modPow(TWO, n);
// 3d2
if (x.equals(ONE)) {
success = true;
break step3loop;
}
// 3d3
if (x.equals(n.subtract(ONE))) {
// 3g
continue step3loop;
}
// 3d4
y = x;
}
// 3e
BigInteger x = y.modPow(TWO, n);
if (x.equals(ONE)) {
success = true;
break step3loop;
}
// 3g
// (loop again)
}
if (success) {
// Step 5
p = y.subtract(ONE).gcd(n);
q = n.divide(p);
return;
}
}
// Step 4
throw new RuntimeException("Prime factors not found");
我实现了由Thomas Pornin描述的
该课程是Chew Keong TAN的C版本检查代码项目错误修复注释
/// EXAMPLE (Hex Strings)
/// N(MODULUS) = "DB2CB41E112BACFA2BD7C3D3D7967E84FB9434FC261F9D090A8983947DAF8488D3DF8FBDCC1F92493585E134A1B42DE519F463244D7ED384E26D516CC7A4FF7895B1992140043AACADFC12E856B202346AF8226B1A882137DC3C5A57F0D2815C1FCD4BB46FA9157FDFFD79EC3A10A824CCC1EB3CE0B6B4396AE236590016BA69"
/// D(PRIVATE EXPONENT) = "18B44A3D155C61EBF4E3261C8BB157E36F63FE30E9AF28892B59E2ADEB18CC8C8BAD284B9165819CA4DEC94AA06B69BCE81706D1C1B668EB128695E5F7FEDE18A908A3011A646A481D3EA71D8A387D474609BD57A882B182E047DE80E04B4221416BD39DFA1FAC0300641962ADB109E28CAF50061B68C9CABD9B00313C0F46ED"
/// E(PUBLIC EXPONENT) = "010001"
/// RESULTS:
/// DP = "899324E9A8B70CA05612D8BAE70844BBF239D43E2E9CCADFA11EBD43D0603FE70A63963FE3FFA38550B5FEB3DA870D2677927B91542D148FA4BEA6DCD6B2FF57"
/// DQ = "E43C98265BF97066FC078FD464BFAC089628765A0CE18904F8C15318A6850174F1A4596D3E8663440115D0EEB9157481E40DCA5EE569B1F7F4EE30AC0439C637"
/// INVERSEQ = "395B8CF3240C325B0F5F86A05ABCF0006695FAB9235589A56759ECBF2CD3D3DFDE0D6F16F0BE5C70CEF22348D2D09FA093C01D909D25BC1DB11DF8A4F0CE552"
/// P = "ED6CF6699EAC99667E0AFAEF8416F902C00B42D6FFA2C3C18C7BE4CF36013A91F6CF23047529047660DE14A77D13B74FF31DF900541ED37A8EF89340C623759B"
/// Q = "EC52382046AA660794CC1A907F8031FDE1A554CDE17E8AA216AEDC92DB2E58B0529C76BD0498E00BAA792058B2766C40FD7A9CC2F6782942D91471905561324B"
public static RSACryptoServiceProvider CreateRSAPrivateKey(string mod, string privExponent, string pubExponent)
{
var rsa = new RSACryptoServiceProvider
{
PersistKeyInCsp = false
};
var n = new BigInteger(mod, 16);
var d = new BigInteger(privExponent, 16);
var e = new BigInteger(pubExponent, 16);
var zero = new BigInteger(0);
var one = new BigInteger(1);
var two = new BigInteger(2);
var four = new BigInteger(4);
BigInteger de = e*d;
BigInteger modulusplus1 = n + one;
BigInteger deminus1 = de - one;
BigInteger p = zero;
BigInteger q = zero;
BigInteger kprima = de/n;
var ks = new[] {kprima, kprima - one, kprima + one};
bool bfound = false;
foreach (BigInteger k in ks)
{
BigInteger fi = deminus1/k;
BigInteger pplusq = modulusplus1 - fi;
BigInteger delta = pplusq*pplusq - n*four;
BigInteger sqrt = delta.sqrt();
p = (pplusq + sqrt)/two;
if (n%p != zero) continue;
q = (pplusq - sqrt)/two;
bfound = true;
break;
}
if (bfound)
{
BigInteger dp = d%(p - one);
BigInteger dq = d%(q - one);
BigInteger inverseq = q.modInverse(p);
var pars = new RSAParameters
{
D = d.getBytes(),
DP = dp.getBytes(),
DQ = dq.getBytes(),
Exponent = e.getBytes(),
Modulus = n.getBytes(),
P = p.getBytes(),
Q = q.getBytes(),
InverseQ = inverseq.getBytes()
};
rsa.ImportParameters(pars);
return rsa;
}
throw new CryptographicException("Error generating the private key");
}
如果有人感兴趣,我已经改编了C语言:
public static void RecoverPQ(
BigInteger n,
BigInteger e,
BigInteger d,
out BigInteger p,
out BigInteger q
)
{
int nBitCount = (int)(BigInteger.Log(n, 2)+1);
// Step 1: Let k = de – 1. If k is odd, then go to Step 4
BigInteger k = d * e - 1;
if (k.IsEven)
{
// Step 2 (express k as (2^t)r, where r is the largest odd integer
// dividing k and t >= 1)
BigInteger r = k;
BigInteger t = 0;
do
{
r = r / 2;
t = t + 1;
} while (r.IsEven);
// Step 3
var rng = new RNGCryptoServiceProvider();
bool success = false;
BigInteger y = 0;
for (int i = 1; i <= 100; i++) {
// 3a
BigInteger g;
do
{
byte[] randomBytes = new byte[nBitCount / 8 + 1]; // +1 to force a positive number
rng.GetBytes(randomBytes);
randomBytes[randomBytes.Length - 1] = 0;
g = new BigInteger(randomBytes);
} while (g >= n);
// 3b
y = BigInteger.ModPow(g, r, n);
// 3c
if (y == 1 || y == n-1) {
// 3g
continue;
}
// 3d
BigInteger x;
for (BigInteger j = 1; j < t; j = j + 1) {
// 3d1
x = BigInteger.ModPow(y, 2, n);
// 3d2
if (x == 1) {
success = true;
break;
}
// 3d3
if (x == n-1) {
// 3g
continue;
}
// 3d4
y = x;
}
// 3e
x = BigInteger.ModPow(y, 2, n);
if (x == 1) {
success = true;
break;
}
// 3g
// (loop again)
}
if (success) {
// Step 5
p = BigInteger.GreatestCommonDivisor((y - 1), n);
q = n / p;
return;
}
}
throw new Exception("Cannot compute P and Q");
}
请把这个问题说得更清楚些。你有两个大整数键,你想用它们做什么?避免帮助,它很难看,也不需要。书中的哪个附件与你提出的解决方案有关?@MaartenBodewes啊,是的,这比我当前的偶数测试要简洁得多。感谢您指出这一点。我很高兴地将此代码与您结合,希望您不介意:
public static void RecoverPQ(
BigInteger n,
BigInteger e,
BigInteger d,
out BigInteger p,
out BigInteger q
)
{
int nBitCount = (int)(BigInteger.Log(n, 2)+1);
// Step 1: Let k = de – 1. If k is odd, then go to Step 4
BigInteger k = d * e - 1;
if (k.IsEven)
{
// Step 2 (express k as (2^t)r, where r is the largest odd integer
// dividing k and t >= 1)
BigInteger r = k;
BigInteger t = 0;
do
{
r = r / 2;
t = t + 1;
} while (r.IsEven);
// Step 3
var rng = new RNGCryptoServiceProvider();
bool success = false;
BigInteger y = 0;
for (int i = 1; i <= 100; i++) {
// 3a
BigInteger g;
do
{
byte[] randomBytes = new byte[nBitCount / 8 + 1]; // +1 to force a positive number
rng.GetBytes(randomBytes);
randomBytes[randomBytes.Length - 1] = 0;
g = new BigInteger(randomBytes);
} while (g >= n);
// 3b
y = BigInteger.ModPow(g, r, n);
// 3c
if (y == 1 || y == n-1) {
// 3g
continue;
}
// 3d
BigInteger x;
for (BigInteger j = 1; j < t; j = j + 1) {
// 3d1
x = BigInteger.ModPow(y, 2, n);
// 3d2
if (x == 1) {
success = true;
break;
}
// 3d3
if (x == n-1) {
// 3g
continue;
}
// 3d4
y = x;
}
// 3e
x = BigInteger.ModPow(y, 2, n);
if (x == 1) {
success = true;
break;
}
// 3g
// (loop again)
}
if (success) {
// Step 5
p = BigInteger.GreatestCommonDivisor((y - 1), n);
q = n / p;
return;
}
}
throw new Exception("Cannot compute P and Q");
}
BigInteger n = BigInteger.Parse("9086945041514605868879747720094842530294507677354717409873592895614408619688608144774037743497197616416703125668941380866493349088794356554895149433555027");
BigInteger e = 65537;
BigInteger d = BigInteger.Parse("8936505818327042395303988587447591295947962354408444794561435666999402846577625762582824202269399672579058991442587406384754958587400493169361356902030209");
BigInteger p;
BigInteger q;
RecoverPQ(n, e, d, out p, out q);
Assert.AreEqual(n, p * q);