예제 #1
0
        public static PrivateKeyInfo createPrivateKeyInfo(AsymmetricKeyParameter key)
        {
            /*
             *  Process DH private key.
             *  The value for L was set to zero implicitly.
             *  This is the same action as found in JCEDHPrivateKey getEncoded method.
             */

            if (key is ElGamalPrivateKeyParameters)
            {
                ElGamalPrivateKeyParameters _key = (ElGamalPrivateKeyParameters)key;
                PrivateKeyInfo info =
                    new PrivateKeyInfo(
                        new AlgorithmIdentifier(
                            OIWObjectIdentifiers.elGamalAlgorithm,
                            new ElGamalParameter(
                                _key.getParameters().getP(),
                                _key.getParameters().getG()).toASN1Object()), new DERInteger(_key.getX()));
                return(info);
            }


            if (key is DSAPrivateKeyParameters)
            {
                DSAPrivateKeyParameters _key = (DSAPrivateKeyParameters)key;
                PrivateKeyInfo          info =
                    new PrivateKeyInfo(
                        new AlgorithmIdentifier(
                            X9ObjectIdentifiers.id_dsa,
                            new DSAParameter(
                                _key.getParameters().getP(),
                                _key.getParameters().getQ(),
                                _key.getParameters().getG()).toASN1Object()), new DERInteger(_key.getX()));

                return(info);
            }


            if (key is DHPrivateKeyParameters)
            {
                DHPrivateKeyParameters _key = (DHPrivateKeyParameters)key;


                PrivateKeyInfo info = new PrivateKeyInfo(
                    new AlgorithmIdentifier(
                        PKCSObjectIdentifiers.dhKeyAgreement, new DHParameter(
                            _key.getParameters().getP(),
                            _key.getParameters().getG(),
                            0
                            ).toASN1Object()
                        )
                    , new DERInteger(_key.getX()));

                return(info);
            }


            if (key is RSAPrivateCrtKeyParameters)
            {
                RSAPrivateCrtKeyParameters _key = (RSAPrivateCrtKeyParameters)key;
                PrivateKeyInfo             info = new PrivateKeyInfo(
                    new AlgorithmIdentifier(
                        PKCSObjectIdentifiers.rsaEncryption, new DERNull()),
                    new RSAPrivateKeyStructure(
                        _key.getModulus(),
                        _key.getPublicExponent(),
                        _key.getExponent(),
                        _key.getP(),
                        _key.getQ(),
                        _key.getDP(),
                        _key.getDQ(),
                        _key.getQInv()).toASN1Object());

                return(info);
            }

            if (key is ECPrivateKeyParameters)
            {
                ECPrivateKeyParameters _key = (ECPrivateKeyParameters)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);


                PrivateKeyInfo info = new PrivateKeyInfo(
                    new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, x962.toASN1Object()),
                    new ECPrivateKeyStructure(_key.getD()).toASN1Object());


                return(info);
            }

            throw (new Exception("Class provided is not convertable:" + key.GetType()));
        }
예제 #2
0
        /**
         * Process a single block using the basic ElGamal 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 ElGamal 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 ElGamal cipher.\n");
            }
            else if (inLen == (getInputBlockSize() + 1) && (inBytes[inOff] & 0x80) != 0)
            {
                throw new DataLengthException("input too large for ElGamal 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);
            BigInteger g     = key.getParameters().getG();
            BigInteger p     = key.getParameters().getP();

            if (typeof(ElGamalPrivateKeyParameters).IsInstanceOfType(key))
            {
                byte[] in1 = new byte[inBytes.Length / 2];
                byte[] in2 = new byte[inBytes.Length / 2];

                Array.Copy(inBytes, 0, in1, 0, in1.Length);
                Array.Copy(inBytes, in1.Length, in2, 0, in2.Length);

                BigInteger gamma = new BigInteger(1, in1);
                BigInteger phi   = new BigInteger(1, in2);

                ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters)key;

                BigInteger m = gamma.modPow(p.subtract(ONE).subtract(priv.getX()), p).multiply(phi).mod(p);

                byte[] outBytes = m.toByteArray();

                if (outBytes[0] != 0)
                {
                    return(outBytes);
                }
                else
                {
                    byte[] output = new byte[outBytes.Length - 1];
                    Array.Copy(outBytes, 1, output, 0, output.Length);

                    return(output);
                }
            }
            else
            {
                ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters)key;

                BigInteger k = new BigInteger(p.bitLength(), random);

                while (k.Equals(ZERO) || (k.compareTo(p.subtract(TWO)) > 0))
                {
                    k = new BigInteger(p.bitLength(), random);
                }

                BigInteger gamma = g.modPow(k, p);
                BigInteger phi   = input.multiply(pub.getY().modPow(k, p)).mod(p);

                byte[] out1   = gamma.toByteArray();
                byte[] out2   = phi.toByteArray();
                byte[] output = new byte[this.getOutputBlockSize()];

                if (out1[0] == 0)
                {
                    Array.Copy(out1, 1, output, output.Length / 2 - (out1.Length - 1), out1.Length - 1);
                }
                else
                {
                    Array.Copy(out1, 0, output, output.Length / 2 - out1.Length, out1.Length);
                }

                if (out2[0] == 0)
                {
                    Array.Copy(out2, 1, output, output.Length - (out2.Length - 1), out2.Length - 1);
                }
                else
                {
                    Array.Copy(out2, 0, output, output.Length - out2.Length, out2.Length);
                }

                return(output);
            }
        }