Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        /**
         * 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);
        }