Example #1
0
        /// <summary>
        /// Create a Subject Public Key Info object for a given public key.
        /// </summary>
        /// <param name="key">One of ElGammalPublicKeyParameters, DSAPublicKeyParameter, DHPublicKeyParameters, RSAKeyParameters or ECPublicKeyParameters</param>
        /// <returns>A subject public key info object.</returns>
        /// <exception cref="Exception">Throw exception if object provided is not one of the above.</exception>
        public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo(AsymmetricKeyParameter key)
        {
            if (key.isPrivate())
            {
                throw (new Exception("Private key passed - public key expected."));
            }

            if (key is ElGamalPublicKeyParameters)
            {
                ElGamalPublicKeyParameters _key = (ElGamalPublicKeyParameters)key;
                SubjectPublicKeyInfo       info =
                    new SubjectPublicKeyInfo(
                        new AlgorithmIdentifier(
                            OIWObjectIdentifiers.elGamalAlgorithm,
                            new ElGamalParameter(
                                _key.getParameters().getP(),
                                _key.getParameters().getG()
                                ).toASN1Object()), new DERInteger(_key.getY()));

                return(info);
            }


            if (key is DSAPublicKeyParameters)
            {
                DSAPublicKeyParameters _key = (DSAPublicKeyParameters)key;
                SubjectPublicKeyInfo   info =
                    new SubjectPublicKeyInfo(
                        new AlgorithmIdentifier(
                            X9ObjectIdentifiers.id_dsa,
                            new DSAParameter(_key.getParameters().getP(), _key.getParameters().getQ(), _key.getParameters().getG()).toASN1Object()),
                        new DERInteger(_key.getY())
                        );

                return(info);
            }


            if (key is DHPublicKeyParameters)
            {
                DHPublicKeyParameters _key = (DHPublicKeyParameters)key;
                SubjectPublicKeyInfo  info = new SubjectPublicKeyInfo(
                    new AlgorithmIdentifier(X9ObjectIdentifiers.dhpublicnumber,
                                            new DHParameter(_key.getParameters().getP(),
                                                            _key.getParameters().getG(),
                                                            _key.getParameters().getJ()).toASN1Object()), new DERInteger(_key.getY()));

                return(info);
            } // End of DH

            if (key is RSAKeyParameters)
            {
                RSAKeyParameters _key = (RSAKeyParameters)key;
                if (_key.isPrivate())
                {
                    throw (new Exception("Private RSA Key provided."));
                }

                SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(PKCSObjectIdentifiers.rsaEncryption, new DERNull()), new RSAPublicKeyStructure(_key.getModulus(), _key.getExponent()).toASN1Object());
                return(info);
            } // End of RSA.

            if (key is ECPublicKeyParameters)
            {
                ECPublicKeyParameters _key = (ECPublicKeyParameters)key;
                X9ECParameters        ecP  = new X9ECParameters(
                    _key.getParameters().getCurve(),
                    _key.getParameters().getG(),
                    _key.getParameters().getN(),
                    _key.getParameters().getH(),
                    _key.getParameters().getSeed());
                X962Parameters       x962 = new X962Parameters(ecP);
                ASN1OctetString      p    = (ASN1OctetString)(new X9ECPoint(_key.getQ()).toASN1Object());
                SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, x962.toASN1Object()), p.getOctets());
                return(info);
            } // End of EC

            throw (new Exception("Class provided no convertable:" + key.GetType()));
        }
Example #2
0
        /**
         * Process a single block using the basic RSA algorithm.
         *
         * @param in the input array.
         * @param inOff the offset into the input buffer where the data starts.
         * @param inLen the length of the data to be processed.
         * @return the result of the RSA process.
         * @exception DataLengthException the input block is too large.
         */
        public byte[] processBlock(
            byte[]  inBytes,
            int inOff,
            int inLen)
        {
            if (inLen > (getInputBlockSize() + 1))
            {
                throw new DataLengthException("input too large for RSA cipher.\n");
            }
            else if (inLen == (getInputBlockSize() + 1) && (inBytes[inOff] & 0x80) != 0)
            {
                throw new DataLengthException("input too large for RSA cipher.\n");
            }

            byte[] block;

            if (inOff != 0 || inLen != inBytes.Length)
            {
                block = new byte[inLen];

                Array.Copy(inBytes, inOff, block, 0, inLen);
            }
            else
            {
                block = inBytes;
            }

            BigInteger input = new BigInteger(1, block);

            byte[] output;

            if (typeof(RSAPrivateCrtKeyParameters).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.
                //
                RSAPrivateCrtKeyParameters crtKey = (RSAPrivateCrtKeyParameters)key;

                BigInteger p    = crtKey.getP();
                BigInteger q    = crtKey.getQ();
                BigInteger dP   = crtKey.getDP();
                BigInteger dQ   = crtKey.getDQ();
                BigInteger qInv = crtKey.getQInv();

                BigInteger mP, mQ, h, m;

                // mP = ((input mod p) ^ dP)) mod p
                mP = (input.remainder(p)).modPow(dP, p);

                // mQ = ((input mod q) ^ dQ)) mod q
                mQ = (input.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 = input.modPow(
                    key.getExponent(), key.getModulus()).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);
        }