c# - How to calculate RSA's additional private key parameters from P and Q? -
when reading rsa private key blob, lacks several rsa parameters (dp, dq, inverseq, d), how can calculate these missing parameters are supplied? i've read it's possible calculate these p , q are supplied, don't know how calculate them.
when importing key, errors when trying use private key claiming data isn't there (of course p , q supplied though).
i need able on multiple platforms, i'm afraid puts me in camp of needing own actual code calculate them.
in c#
here c# code can construct full set of rsaparameters p, q, , public key data. assume parameters method big-endian (as rsaparameters).
private static rsaparameters create(byte[] p, byte[] q, byte[] exponent, byte[] modulus) { var addlparameters = getfullprivateparameters( p: new biginteger(copyandreverse(p)), q: new biginteger(copyandreverse(q)), e: new biginteger(copyandreverse(exponent)), modulus: new biginteger(copyandreverse(modulus))); return new rsaparameters { p = p, q = q, exponent = exponent, modulus = modulus, d = addlparameters.d, dp = addlparameters.dp, dq = addlparameters.dq, inverseq = addlparameters.inverseq, }; } private static rsaparameters getfullprivateparameters(biginteger p, biginteger q, biginteger e, biginteger modulus) { var n = p * q; var phiofn = n - p - q + 1; // or: (p - 1) * (q - 1); var d = modinverse(e, phiofn); assert.equal(1, (d * e) % phiofn); var dp = d % (p - 1); var dq = d % (q - 1); var qinv = modinverse(q, p); //assert.equal(1, (qinv * q) % p); return new rsaparameters { d = copyandreverse(d.tobytearray()), dp = copyandreverse(dp.tobytearray()), dq = copyandreverse(dq.tobytearray()), inverseq = copyandreverse(qinv.tobytearray()), }; } /// <summary> /// calculates modular multiplicative inverse of <paramref name="a"/> modulo <paramref name="m"/> /// using extended euclidean algorithm. /// </summary> /// <remarks> /// implementation comes pseudocode defining inverse(a, n) function @ /// https://en.wikipedia.org/wiki/extended_euclidean_algorithm /// </remarks> public static biginteger modinverse(biginteger a, biginteger n) { biginteger t = 0, nt = 1, r = n, nr = a; if (n < 0) { n = -n; } if (a < 0) { = n - (-a % n); } while (nr != 0) { var quot = r / nr; var tmp = nt; nt = t - quot * nt; t = tmp; tmp = nr; nr = r - quot * nr; r = tmp; } if (r > 1) throw new argumentexception(nameof(a) + " not convertible."); if (t < 0) t = t + n; return t; } private static byte[] copyandreverse(byte[] data) { byte[] reversed = new byte[data.length]; array.copy(data, 0, reversed, 0, data.length); array.reverse(reversed); return reversed; }
Comments
Post a Comment