public override bool Equals(object obj) { RsaPrivateKey kp = obj as RsaPrivateKey; if (kp != null) { return(kp.DP.Equals(dP) && kp.DQ.Equals(dQ) && kp.Exponent.Equals(this.Exponent) && kp.Modulus.Equals(this.Modulus) && kp.P.Equals(p) && kp.Q.Equals(q) && kp.PublicExponent.Equals(e) && kp.QInv.Equals(qInv)); } return(false); }
public static RsaKeyPair GenerateKeyPair(int strength, int certainity, BigInteger publicExponent) { BigInteger p, q, n, d, e, pSub1, qSub1, phi; // This is cryptographic stuff, we want to use the secure random provider Random rand = RandomGenerator.GetSecureRandomGenerator(); // // p and q values should have a length of half the strength in bits // int pbitlength = (strength + 1) / 2; int qbitlength = (strength - pbitlength); e = publicExponent; // // Generate p, prime and (p-1) relatively prime to e // for (; ;) { p = new BigInteger(pbitlength, certainity, rand); if (e.Gcd(p.Subtract(BigInteger.One)).Equals(BigInteger.One)) { break; } } // // Generate a modulus of the required length // for (; ;) { // Generate q, prime and (q-1) relatively prime to e, // and not equal to p // for (; ;) { q = new BigInteger(qbitlength, certainity, rand); if (e.Gcd(q.Subtract(BigInteger.One)).Equals(BigInteger.One) && !p.Equals(q)) { break; } } // // calculate the modulus // n = p.Multiply(q); if (n.BitLength() == strength) { break; } // // if we Get here our primes aren't big enough, make the largest // of the two p and try again // p = p.Max(q); } pSub1 = p.Subtract(BigInteger.One); qSub1 = q.Subtract(BigInteger.One); phi = pSub1.Multiply(qSub1); // // calculate the private exponent // d = e.ModInverse(phi); // // calculate the CRT factors // BigInteger dP, dQ, qInv; dP = d.Remainder(pSub1); dQ = d.Remainder(qSub1); qInv = q.ModInverse(p); RsaKey publicKey = new RsaKey(false, n, e); RsaPrivateKey privateKey = new RsaPrivateKey(n, e, d, p, q, dP, dQ, qInv); RsaKeyPair pair = new RsaKeyPair(privateKey, publicKey); return(pair); }
/** * Process a single block using the basic RSA algorithm. * * @param in the input array. * @return the result of the RSA process. * @exception Exception the input block is too large. */ internal byte[] ProcessText(byte[] input) { int length = input.Length; int inOff = 0; if (length > (GetInputBlockSize() + 1)) { throw new ArgumentException("input too large for RSA cipher.\n"); } else if (length == (GetInputBlockSize() + 1) && (input[inOff] & 0x80) != 0) { throw new ArgumentException("input too large for RSA cipher.\n"); } byte[] block; if (inOff != 0 || length != input.Length) { block = new byte[length]; Array.Copy(input, inOff, block, 0, length); } else { block = input; } BigInteger value = new BigInteger(1, block); byte[] output; if (typeof(RsaPrivateKey).IsInstanceOfType(key)) { // // we have the extra factors, use the Chinese Remainder Theorem - the author // wishes to express his thanks to Dirk Bonekaemper at rtsffm.com for // advice regarding the expression of this. // RsaPrivateKey crtKey = (RsaPrivateKey)key; BigInteger p = crtKey.P; BigInteger q = crtKey.Q; BigInteger dP = crtKey.DP; BigInteger dQ = crtKey.DQ; BigInteger qInv = crtKey.QInv; BigInteger mP, mQ, h, m; // mP = ((input mod p) ^ dP)) mod p mP = (value.Remainder(p)).ModPow(dP, p); // mQ = ((input mod q) ^ dQ)) mod q mQ = (value.Remainder(q)).ModPow(dQ, q); // h = qInv * (mP - mQ) mod p h = mP.Subtract(mQ); h = h.Multiply(qInv); h = h.Mod(p); // mod (in Java) returns the positive residual // m = h * q + mQ m = h.Multiply(q); m = m.Add(mQ); output = m.ToByteArray(); } else { output = value.ModPow( key.Exponent, key.Modulus).ToByteArray(); } if (forEncryption) { if (output[0] == 0 && output.Length > GetOutputBlockSize()) // have ended up with an extra zero byte, copy down. { byte[] tmp = new byte[output.Length - 1]; Array.Copy(output, 1, tmp, 0, tmp.Length); return(tmp); } if (output.Length < GetOutputBlockSize()) // have ended up with less bytes than normal, lengthen { byte[] tmp = new byte[GetOutputBlockSize()]; Array.Copy(output, 0, tmp, tmp.Length - output.Length, output.Length); return(tmp); } } else { if (output[0] == 0) // have ended up with an extra zero byte, copy down. { byte[] tmp = new byte[output.Length - 1]; Array.Copy(output, 1, tmp, 0, tmp.Length); return(tmp); } } return(output); }