Esempio n. 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 == null)
            {
                throw new ArgumentNullException("key");
            }
            if (key.IsPrivate)
            {
                throw new ArgumentException("Private key passed - public key expected.", "key");
            }

            if (key is ElGamalPublicKeyParameters)
            {
                ElGamalPublicKeyParameters _key = (ElGamalPublicKeyParameters)key;
                ElGamalParameters          kp   = _key.Parameters;

                SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
                    new AlgorithmIdentifier(
                        OiwObjectIdentifiers.ElGamalAlgorithm,
                        new ElGamalParameter(kp.P, kp.G).ToAsn1Object()),
                    new DerInteger(_key.Y));

                return(info);
            }

            if (key is DsaPublicKeyParameters)
            {
                DsaPublicKeyParameters _key = (DsaPublicKeyParameters)key;
                DsaParameters          kp   = _key.Parameters;
                Asn1Encodable          ae   = kp == null
                                        ?       null
                                        :       new DsaParameter(kp.P, kp.Q, kp.G).ToAsn1Object();

                return(new SubjectPublicKeyInfo(
                           new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, ae),
                           new DerInteger(_key.Y)));
            }

            if (key is DHPublicKeyParameters)
            {
                DHPublicKeyParameters _key = (DHPublicKeyParameters)key;
                DHParameters          kp   = _key.Parameters;

                SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
                    new AlgorithmIdentifier(
                        X9ObjectIdentifiers.DHPublicNumber,
                        new DHParameter(kp.P, kp.G, kp.L).ToAsn1Object()),
                    new DerInteger(_key.Y));

                return(info);
            } // End of DH

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

                SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
                    new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance),
                    new RsaPublicKeyStructure(_key.Modulus, _key.Exponent).ToAsn1Object());

                return(info);
            } // End of RSA.

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

                if (_key.AlgorithmName == "ECGOST3410")
                {
                    if (_key.PublicKeyParamSet == null)
                    {
                        throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
                    }

                    ECPoint    q  = _key.Q;
                    BigInteger bX = q.X.ToBigInteger();
                    BigInteger bY = q.Y.ToBigInteger();

                    byte[] encKey = new byte[64];
                    ExtractBytes(encKey, 0, bX);
                    ExtractBytes(encKey, 32, bY);

                    Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
                        _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);

                    AlgorithmIdentifier algID = new AlgorithmIdentifier(
                        CryptoProObjectIdentifiers.GostR3410x2001,
                        gostParams.ToAsn1Object());

                    return(new SubjectPublicKeyInfo(algID, new DerOctetString(encKey)));
                }
                else
                {
                    ECDomainParameters kp = _key.Parameters;

                    X9ECParameters  ecP  = new X9ECParameters(kp.Curve, kp.G, kp.N, kp.H, kp.GetSeed());
                    X962Parameters  x962 = new X962Parameters(ecP);
                    Asn1OctetString p    = (Asn1OctetString)(new X9ECPoint(_key.Q).ToAsn1Object());

                    AlgorithmIdentifier algID = new AlgorithmIdentifier(
                        X9ObjectIdentifiers.IdECPublicKey, x962.ToAsn1Object());

                    return(new SubjectPublicKeyInfo(algID, p.GetOctets()));
                }
            }             // End of EC

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

                if (_key.PublicKeyParamSet == null)
                {
                    throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
                }

                byte[] keyEnc   = _key.Y.ToByteArrayUnsigned();
                byte[] keyBytes = new byte[keyEnc.Length];

                for (int i = 0; i != keyBytes.Length; i++)
                {
                    keyBytes[i] = keyEnc[keyEnc.Length - 1 - i];                     // must be little endian
                }

                Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters(
                    _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);

                AlgorithmIdentifier algID = new AlgorithmIdentifier(
                    CryptoProObjectIdentifiers.GostR3410x94,
                    algParams.ToAsn1Object());

                return(new SubjectPublicKeyInfo(algID, new DerOctetString(keyBytes)));
            }

            throw new ArgumentException("Class provided no convertible: " + key.GetType().FullName);
        }
        private void DoTestGp(
            int size,
            int privateValueSize,
            IBigInteger g,
            IBigInteger p)
        {
            IAsymmetricCipherKeyPairGenerator keyGen = GeneratorUtilities.GetKeyPairGenerator("ElGamal");

//			DHParameterSpec elParams = new DHParameterSpec(p, g);
//			keyGen.initialize(elParams);
            ElGamalParameters elParams           = new ElGamalParameters(p, g, privateValueSize);
            ElGamalKeyGenerationParameters elKgp = new ElGamalKeyGenerationParameters(
                new SecureRandom(), elParams);

            keyGen.Init(elKgp);

            IAsymmetricCipherKeyPair keyPair = keyGen.GenerateKeyPair();
            SecureRandom             rand    = new SecureRandom();

            checkKeySize(privateValueSize, keyPair);

            IBufferedCipher cipher = CipherUtilities.GetCipher("ElGamal");

            cipher.Init(true, new ParametersWithRandom(keyPair.Public, rand));

            byte[] inBytes = Encoding.ASCII.GetBytes("This is a test");

            if (cipher.GetOutputSize(inBytes.Length) != (size / 8) * 2)
            {
                Fail("getOutputSize wrong on encryption");
            }

            byte[] outBytes = cipher.DoFinal(inBytes);

            cipher.Init(false, keyPair.Private);

            if (cipher.GetOutputSize(outBytes.Length) != (size / 8) - 1)
            {
                Fail("GetOutputSize wrong on decryption");
            }


            //
            // No Padding - maximum length
            //
            byte[] modBytes = ((ElGamalPublicKeyParameters)keyPair.Public).Parameters.P.ToByteArray();
            byte[] maxInput = new byte[modBytes.Length - 1];

            maxInput[0] |= 0x7f;

            cipher.Init(true, new ParametersWithRandom(keyPair.Public, rand));

            outBytes = cipher.DoFinal(maxInput);

            cipher.Init(false, keyPair.Private);

            outBytes = cipher.DoFinal(outBytes);

            if (!AreEqual(outBytes, maxInput))
            {
                Fail("NoPadding test failed on decrypt expected "
                     + Hex.ToHexString(maxInput) + " got "
                     + Hex.ToHexString(outBytes));
            }


            //
            // encrypt/decrypt
            //
            IBufferedCipher c1 = CipherUtilities.GetCipher("ElGamal");
            IBufferedCipher c2 = CipherUtilities.GetCipher("ElGamal");

            c1.Init(true, new ParametersWithRandom(keyPair.Public, rand));

            byte[] out1 = c1.DoFinal(inBytes);

            c2.Init(false, keyPair.Private);

            byte[] out2 = c2.DoFinal(out1);

            if (!AreEqual(inBytes, out2))
            {
                Fail(size + " encrypt test failed");
            }


            //
            // encrypt/decrypt with update
            //
            int outLen = c1.ProcessBytes(inBytes, 0, 2, out1, 0);

            outLen += c1.DoFinal(inBytes, 2, inBytes.Length - 2, out1, outLen);

            outLen = c2.ProcessBytes(out1, 0, 2, out2, 0);

            outLen += c2.DoFinal(out1, 2, out1.Length - 2, out2, outLen);

            if (!AreEqual(inBytes, out2))
            {
                Fail(size + " encrypt with update test failed");
            }



            //
            // public key encoding test
            //
//			byte[] pubEnc = keyPair.Public.GetEncoded();
            byte[] pubEnc = SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(keyPair.Public).GetDerEncoded();

//			KeyFactory keyFac = KeyFactory.GetInstance("ElGamal");
//			X509EncodedKeySpec pubX509 = new X509EncodedKeySpec(pubEnc);
//			DHPublicKeyParameters pubKey = (DHPublicKeyParameters)keyFac.generatePublic(pubX509);
            ElGamalPublicKeyParameters pubKey = (ElGamalPublicKeyParameters)
                                                PublicKeyFactory.CreateKey(pubEnc);
            ElGamalParameters spec = pubKey.Parameters;

            if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P))
            {
                Fail(size + " bit public key encoding/decoding test failed on parameters");
            }

            if (!((ElGamalPublicKeyParameters)keyPair.Public).Y.Equals(pubKey.Y))
            {
                Fail(size + " bit public key encoding/decoding test failed on y value");
            }

/*
 *                      //
 *                      // public key serialisation test
 *                      //
 *                      // TODO Is there some standard this serialization must conform to?
 *                      BinaryFormatter formatter = new BinaryFormatter();
 *
 *                      MemoryStream bOut = new MemoryStream();
 * //			ObjectOutputStream oOut = new ObjectOutputStream(bOut);
 * //			oOut.writeObject(keyPair.Public);
 *                      formatter.Serialize(bOut, keyPair.Public);
 *
 *                      MemoryStream bIn = new MemoryStream(bOut.ToArray(), false);
 * //			ObjectInputStream oIn = new ObjectInputStream(bIn);
 * //			pubKey = (DHPublicKeyParameters)oIn.readObject();
 *                      pubKey = (ElGamalPublicKeyParameters) formatter.Deserialize(bIn);
 *                      spec = pubKey.Parameters;
 *
 *                      if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P))
 *                      {
 *                              Fail(size + " bit public key serialisation test failed on parameters");
 *                      }
 *
 *                      if (!((ElGamalPublicKeyParameters )keyPair.Public).Y.Equals(pubKey.Y))
 *                      {
 *                              Fail(size + " bit public key serialisation test failed on y value");
 *                      }
 */

            //
            // private key encoding test
            //
            // TODO Keys don't support GetEncoded
//			byte[] privEnc = keyPair.Private.GetEncoded();
            byte[] privEnc = PrivateKeyInfoFactory.CreatePrivateKeyInfo(keyPair.Private).GetDerEncoded();

//			PKCS8EncodedKeySpec privPKCS8 = new PKCS8EncodedKeySpec(privEnc);
//			DHPrivateKeyParameters privKey = (DHPrivateKeyParameters)keyFac.generatePrivate(privPKCS8);
            ElGamalPrivateKeyParameters privKey = (ElGamalPrivateKeyParameters)
                                                  PrivateKeyFactory.CreateKey(privEnc);

            spec = privKey.Parameters;

            if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P))
            {
                Fail(size + " bit private key encoding/decoding test failed on parameters");
            }

            if (!((ElGamalPrivateKeyParameters)keyPair.Private).X.Equals(privKey.X))
            {
                Fail(size + " bit private key encoding/decoding test failed on y value");
            }

/*
 *                      //
 *                      // private key serialisation test
 *                      //
 *                      bOut = new MemoryStream();
 * //			oOut = new ObjectOutputStream(bOut);
 * //			oOut.writeObject(keyPair.Private);
 *                      formatter.Serialize(bOut, keyPair.Private);
 *
 *                      bIn = new MemoryStream(bOut.ToArray(), false);
 * //			oIn = new ObjectInputStream(bIn);
 * //			privKey = (DHPrivateKeyParameters)oIn.readObject();
 *                      privKey = (ElGamalPrivateKeyParameters) formatter.Deserialize(bIn);
 *                      spec = privKey.Parameters;
 *
 *                      if (!spec.G.Equals(elParams.G) || !spec.P.Equals(elParams.P))
 *                      {
 *                              Fail(size + " bit private key serialisation test failed on parameters");
 *                      }
 *
 *                      if (!((ElGamalPrivateKeyParameters) keyPair.Private).X.Equals(privKey.X))
 *                      {
 *                              Fail(size + " bit private key serialisation test failed on y value");
 *                      }
 */
        }
Esempio n. 3
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 length 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[]  input,
            int inOff,
            int length)
        {
            if (key == null)
            {
                throw new InvalidOperationException("ElGamal engine not initialised");
            }

            int maxLength = forEncryption
                                ?       (bitSize - 1 + 7) / 8
                                :       GetInputBlockSize();

            if (length > maxLength)
            {
                throw new DataLengthException("input too large for ElGamal cipher.\n");
            }

            BigInteger p = key.Parameters.P;

            byte[] output;
            if (key is ElGamalPrivateKeyParameters)             // decryption
            {
                int        halfLength = length / 2;
                BigInteger gamma      = new BigInteger(1, input, inOff, halfLength);
                BigInteger phi        = new BigInteger(1, input, inOff + halfLength, halfLength);

                ElGamalPrivateKeyParameters priv = (ElGamalPrivateKeyParameters)key;

                // a shortcut, which generally relies on p being prime amongst other things.
                // if a problem with this shows up, check the p and g values!
                BigInteger m = gamma.ModPow(p.Subtract(BigInteger.One).Subtract(priv.X), p).Multiply(phi).Mod(p);

                output = m.ToByteArrayUnsigned();
            }
            else             // encryption
            {
                BigInteger tmp = new BigInteger(1, input, inOff, length);

                if (tmp.BitLength >= p.BitLength)
                {
                    throw new DataLengthException("input too large for ElGamal cipher.\n");
                }


                ElGamalPublicKeyParameters pub = (ElGamalPublicKeyParameters)key;

                BigInteger pSub2 = p.Subtract(BigInteger.Two);

                // TODO In theory, a series of 'k', 'g.ModPow(k, p)' and 'y.ModPow(k, p)' can be pre-calculated
                BigInteger k;
                do
                {
                    k = new BigInteger(p.BitLength, random);
                }while (k.SignValue == 0 || k.CompareTo(pSub2) > 0);

                BigInteger g     = key.Parameters.G;
                BigInteger gamma = g.ModPow(k, p);
                BigInteger phi   = tmp.Multiply(pub.Y.ModPow(k, p)).Mod(p);

                output = new byte[this.GetOutputBlockSize()];

                // TODO Add methods to allow writing BigInteger to existing byte array?
                byte[] out1 = gamma.ToByteArrayUnsigned();
                byte[] out2 = phi.ToByteArrayUnsigned();
                out1.CopyTo(output, output.Length / 2 - out1.Length);
                out2.CopyTo(output, output.Length - out2.Length);
            }

            return(output);
        }
Esempio n. 4
0
        /// <summary>
        /// Create a PgpPublicKey from the passed in lightweight one.
        /// </summary>
        /// <remarks>
        /// Note: the time passed in affects the value of the key's keyId, so you probably only want
        /// to do this once for a lightweight key, or make sure you keep track of the time you used.
        /// </remarks>
        /// <param name="algorithm">Asymmetric algorithm type representing the public key.</param>
        /// <param name="pubKey">Actual public key to associate.</param>
        /// <param name="time">Date of creation.</param>
        /// <exception cref="ArgumentException">If <c>pubKey</c> is not public.</exception>
        /// <exception cref="PgpException">On key creation problem.</exception>
        public PgpPublicKey(
            PublicKeyAlgorithmTag algorithm,
            AsymmetricKeyParameter pubKey,
            DateTime time)
        {
            if (pubKey.IsPrivate)
            {
                throw new ArgumentException("Expected a public key", "pubKey");
            }

            IBcpgKey bcpgKey;

            if (pubKey is RsaKeyParameters)
            {
                RsaKeyParameters rK = (RsaKeyParameters)pubKey;

                bcpgKey = new RsaPublicBcpgKey(rK.Modulus, rK.Exponent);
            }
            else if (pubKey is DsaPublicKeyParameters)
            {
                DsaPublicKeyParameters dK = (DsaPublicKeyParameters)pubKey;
                DsaParameters          dP = dK.Parameters;

                bcpgKey = new DsaPublicBcpgKey(dP.P, dP.Q, dP.G, dK.Y);
            }
            else if (pubKey is ECPublicKeyParameters)
            {
                ECPublicKeyParameters ecK = (ECPublicKeyParameters)pubKey;

                if (algorithm == PublicKeyAlgorithmTag.ECDH)
                {
                    bcpgKey = new ECDHPublicBcpgKey(ecK.PublicKeyParamSet, ecK.Q, HashAlgorithmTag.Sha256, SymmetricKeyAlgorithmTag.Aes128);
                }
                else if (algorithm == PublicKeyAlgorithmTag.ECDsa)
                {
                    bcpgKey = new ECDsaPublicBcpgKey(ecK.PublicKeyParamSet, ecK.Q);
                }
                else
                {
                    throw new PgpException("unknown EC algorithm");
                }
            }
            else if (pubKey is ElGamalPublicKeyParameters)
            {
                ElGamalPublicKeyParameters eK = (ElGamalPublicKeyParameters)pubKey;
                ElGamalParameters          eS = eK.Parameters;

                bcpgKey = new ElGamalPublicBcpgKey(eS.P, eS.G, eK.Y);
            }
            else
            {
                throw new PgpException("unknown key class");
            }

            this.publicPk = new PublicKeyPacket(algorithm, time, bcpgKey);
            this.ids      = Platform.CreateArrayList();
            this.idSigs   = Platform.CreateArrayList();

            try
            {
                Init();
            }
            catch (IOException e)
            {
                throw new PgpException("exception calculating keyId", e);
            }
        }
        /// <summary>
        /// Create a Subject Public Key Info object for a given public key.
        /// </summary>
        /// <param name="publicKey">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 publicKey)
        {
            if (publicKey == null)
            {
                throw new ArgumentNullException("publicKey");
            }
            if (publicKey.IsPrivate)
            {
                throw new ArgumentException("Private key passed - public key expected.", "publicKey");
            }

            if (publicKey is ElGamalPublicKeyParameters)
            {
                ElGamalPublicKeyParameters _key = (ElGamalPublicKeyParameters)publicKey;
                ElGamalParameters          kp   = _key.Parameters;

                SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
                    new AlgorithmIdentifier(
                        OiwObjectIdentifiers.ElGamalAlgorithm,
                        new ElGamalParameter(kp.P, kp.G).ToAsn1Object()),
                    new DerInteger(_key.Y));

                return(info);
            }

            if (publicKey is DsaPublicKeyParameters)
            {
                DsaPublicKeyParameters _key = (DsaPublicKeyParameters)publicKey;
                DsaParameters          kp   = _key.Parameters;
                Asn1Encodable          ae   = kp == null
                    ?   null
                    :   new DsaParameter(kp.P, kp.Q, kp.G).ToAsn1Object();

                return(new SubjectPublicKeyInfo(
                           new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, ae),
                           new DerInteger(_key.Y)));
            }

            if (publicKey is DHPublicKeyParameters)
            {
                DHPublicKeyParameters _key = (DHPublicKeyParameters)publicKey;
                DHParameters          kp   = _key.Parameters;

                SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
                    new AlgorithmIdentifier(
                        _key.AlgorithmOid,
                        new DHParameter(kp.P, kp.G, kp.L).ToAsn1Object()),
                    new DerInteger(_key.Y));

                return(info);
            } // End of DH

            if (publicKey is RsaKeyParameters)
            {
                RsaKeyParameters _key = (RsaKeyParameters)publicKey;

                SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
                    new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance),
                    new RsaPublicKeyStructure(_key.Modulus, _key.Exponent).ToAsn1Object());

                return(info);
            } // End of RSA.

            if (publicKey is ECPublicKeyParameters)
            {
                ECPublicKeyParameters _key = (ECPublicKeyParameters)publicKey;


                if (_key.Parameters is ECGost3410Parameters)
                {
                    ECGost3410Parameters gostParams = (ECGost3410Parameters)_key.Parameters;

                    BigInteger bX    = _key.Q.AffineXCoord.ToBigInteger();
                    BigInteger bY    = _key.Q.AffineYCoord.ToBigInteger();
                    bool       is512 = (bX.BitLength > 256);

                    Gost3410PublicKeyAlgParameters parameters = new Gost3410PublicKeyAlgParameters(
                        gostParams.PublicKeyParamSet,
                        gostParams.DigestParamSet,
                        gostParams.EncryptionParamSet);

                    int encKeySize;
                    int offset;
                    DerObjectIdentifier algIdentifier;
                    if (is512)
                    {
                        encKeySize    = 128;
                        offset        = 64;
                        algIdentifier = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_512;
                    }
                    else
                    {
                        encKeySize    = 64;
                        offset        = 32;
                        algIdentifier = RosstandartObjectIdentifiers.id_tc26_gost_3410_12_256;
                    }

                    byte[] encKey = new byte[encKeySize];

                    ExtractBytes(encKey, encKeySize / 2, 0, bX);
                    ExtractBytes(encKey, encKeySize / 2, offset, bY);

                    return(new SubjectPublicKeyInfo(new AlgorithmIdentifier(algIdentifier, parameters), new DerOctetString(encKey)));
                } // End of ECGOST3410_2012



                if (_key.AlgorithmName == "ECGOST3410")
                {
                    if (_key.PublicKeyParamSet == null)
                    {
                        throw BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
                    }

                    ECPoint    q  = _key.Q.Normalize();
                    BigInteger bX = q.AffineXCoord.ToBigInteger();
                    BigInteger bY = q.AffineYCoord.ToBigInteger();

                    byte[] encKey = new byte[64];
                    ExtractBytes(encKey, 0, bX);
                    ExtractBytes(encKey, 32, bY);

                    Gost3410PublicKeyAlgParameters gostParams = new Gost3410PublicKeyAlgParameters(
                        _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);

                    AlgorithmIdentifier algID = new AlgorithmIdentifier(
                        CryptoProObjectIdentifiers.GostR3410x2001,
                        gostParams.ToAsn1Object());

                    return(new SubjectPublicKeyInfo(algID, new DerOctetString(encKey)));
                }
                else
                {
                    X962Parameters x962;
                    if (_key.PublicKeyParamSet == null)
                    {
                        ECDomainParameters kp  = _key.Parameters;
                        X9ECParameters     ecP = new X9ECParameters(kp.Curve, kp.G, kp.N, kp.H, kp.GetSeed());

                        x962 = new X962Parameters(ecP);
                    }
                    else
                    {
                        x962 = new X962Parameters(_key.PublicKeyParamSet);
                    }

                    byte[] pubKey = _key.Q.GetEncoded(false);

                    AlgorithmIdentifier algID = new AlgorithmIdentifier(
                        X9ObjectIdentifiers.IdECPublicKey, x962.ToAsn1Object());

                    return(new SubjectPublicKeyInfo(algID, pubKey));
                }
            } // End of EC

            if (publicKey is Gost3410PublicKeyParameters)
            {
                Gost3410PublicKeyParameters _key = (Gost3410PublicKeyParameters)publicKey;

                if (_key.PublicKeyParamSet == null)
                {
                    throw BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
                }

                byte[] keyEnc   = _key.Y.ToByteArrayUnsigned();
                byte[] keyBytes = new byte[keyEnc.Length];

                for (int i = 0; i != keyBytes.Length; i++)
                {
                    keyBytes[i] = keyEnc[keyEnc.Length - 1 - i]; // must be little endian
                }

                Gost3410PublicKeyAlgParameters algParams = new Gost3410PublicKeyAlgParameters(
                    _key.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);

                AlgorithmIdentifier algID = new AlgorithmIdentifier(
                    CryptoProObjectIdentifiers.GostR3410x94,
                    algParams.ToAsn1Object());

                return(new SubjectPublicKeyInfo(algID, new DerOctetString(keyBytes)));
            }

            if (publicKey is X448PublicKeyParameters)
            {
                X448PublicKeyParameters key = (X448PublicKeyParameters)publicKey;

                return(new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X448), key.GetEncoded()));
            }

            if (publicKey is X25519PublicKeyParameters)
            {
                X25519PublicKeyParameters key = (X25519PublicKeyParameters)publicKey;

                return(new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_X25519), key.GetEncoded()));
            }

            if (publicKey is Ed448PublicKeyParameters)
            {
                Ed448PublicKeyParameters key = (Ed448PublicKeyParameters)publicKey;

                return(new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed448), key.GetEncoded()));
            }

            if (publicKey is Ed25519PublicKeyParameters)
            {
                Ed25519PublicKeyParameters key = (Ed25519PublicKeyParameters)publicKey;

                return(new SubjectPublicKeyInfo(new AlgorithmIdentifier(EdECObjectIdentifiers.id_Ed25519), key.GetEncoded()));
            }

            throw new ArgumentException("Class provided no convertible: " + BestHTTP.SecureProtocol.Org.BouncyCastle.Utilities.Platform.GetTypeName(publicKey));
        }
Esempio n. 6
0
 public static SubjectPublicKeyInfo CreateSubjectPublicKeyInfo(AsymmetricKeyParameter key)
 {
     if (key == null)
     {
         throw new ArgumentNullException("key");
     }
     if (key.IsPrivate)
     {
         throw new ArgumentException("Private key passed - public key expected.", "key");
     }
     if (key is ElGamalPublicKeyParameters)
     {
         ElGamalPublicKeyParameters elGamalPublicKeyParameters = (ElGamalPublicKeyParameters)key;
         ElGamalParameters          parameters = elGamalPublicKeyParameters.Parameters;
         return(new SubjectPublicKeyInfo(new AlgorithmIdentifier(OiwObjectIdentifiers.ElGamalAlgorithm, new ElGamalParameter(parameters.P, parameters.G).ToAsn1Object()), new DerInteger(elGamalPublicKeyParameters.Y)));
     }
     if (key is DsaPublicKeyParameters)
     {
         DsaPublicKeyParameters dsaPublicKeyParameters = (DsaPublicKeyParameters)key;
         DsaParameters          parameters2            = dsaPublicKeyParameters.Parameters;
         Asn1Encodable          parameters3            = (parameters2 == null) ? null : new DsaParameter(parameters2.P, parameters2.Q, parameters2.G).ToAsn1Object();
         return(new SubjectPublicKeyInfo(new AlgorithmIdentifier(X9ObjectIdentifiers.IdDsa, parameters3), new DerInteger(dsaPublicKeyParameters.Y)));
     }
     if (key is DHPublicKeyParameters)
     {
         DHPublicKeyParameters dHPublicKeyParameters = (DHPublicKeyParameters)key;
         DHParameters          parameters4           = dHPublicKeyParameters.Parameters;
         return(new SubjectPublicKeyInfo(new AlgorithmIdentifier(dHPublicKeyParameters.AlgorithmOid, new DHParameter(parameters4.P, parameters4.G, parameters4.L).ToAsn1Object()), new DerInteger(dHPublicKeyParameters.Y)));
     }
     if (key is RsaKeyParameters)
     {
         RsaKeyParameters rsaKeyParameters = (RsaKeyParameters)key;
         return(new SubjectPublicKeyInfo(new AlgorithmIdentifier(PkcsObjectIdentifiers.RsaEncryption, DerNull.Instance), new RsaPublicKeyStructure(rsaKeyParameters.Modulus, rsaKeyParameters.Exponent).ToAsn1Object()));
     }
     if (key is ECPublicKeyParameters)
     {
         ECPublicKeyParameters eCPublicKeyParameters = (ECPublicKeyParameters)key;
         if (eCPublicKeyParameters.AlgorithmName == "ECGOST3410")
         {
             if (eCPublicKeyParameters.PublicKeyParamSet == null)
             {
                 throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
             }
             ECPoint    eCPoint = eCPublicKeyParameters.Q.Normalize();
             BigInteger bI      = eCPoint.AffineXCoord.ToBigInteger();
             BigInteger bI2     = eCPoint.AffineYCoord.ToBigInteger();
             byte[]     array   = new byte[64];
             ExtractBytes(array, 0, bI);
             ExtractBytes(array, 32, bI2);
             Gost3410PublicKeyAlgParameters gost3410PublicKeyAlgParameters = new Gost3410PublicKeyAlgParameters(eCPublicKeyParameters.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);
             AlgorithmIdentifier            algID = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x2001, gost3410PublicKeyAlgParameters.ToAsn1Object());
             return(new SubjectPublicKeyInfo(algID, new DerOctetString(array)));
         }
         X962Parameters x962Parameters;
         if (eCPublicKeyParameters.PublicKeyParamSet == null)
         {
             ECDomainParameters parameters5  = eCPublicKeyParameters.Parameters;
             X9ECParameters     ecParameters = new X9ECParameters(parameters5.Curve, parameters5.G, parameters5.N, parameters5.H, parameters5.GetSeed());
             x962Parameters = new X962Parameters(ecParameters);
         }
         else
         {
             x962Parameters = new X962Parameters(eCPublicKeyParameters.PublicKeyParamSet);
         }
         Asn1OctetString     asn1OctetString = (Asn1OctetString) new X9ECPoint(eCPublicKeyParameters.Q).ToAsn1Object();
         AlgorithmIdentifier algID2          = new AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, x962Parameters.ToAsn1Object());
         return(new SubjectPublicKeyInfo(algID2, asn1OctetString.GetOctets()));
     }
     if (key is Gost3410PublicKeyParameters)
     {
         Gost3410PublicKeyParameters gost3410PublicKeyParameters = (Gost3410PublicKeyParameters)key;
         if (gost3410PublicKeyParameters.PublicKeyParamSet == null)
         {
             throw Platform.CreateNotImplementedException("Not a CryptoPro parameter set");
         }
         byte[] array2 = gost3410PublicKeyParameters.Y.ToByteArrayUnsigned();
         byte[] array3 = new byte[array2.Length];
         for (int i = 0; i != array3.Length; i++)
         {
             array3[i] = array2[array2.Length - 1 - i];
         }
         Gost3410PublicKeyAlgParameters gost3410PublicKeyAlgParameters2 = new Gost3410PublicKeyAlgParameters(gost3410PublicKeyParameters.PublicKeyParamSet, CryptoProObjectIdentifiers.GostR3411x94CryptoProParamSet);
         AlgorithmIdentifier            algID3 = new AlgorithmIdentifier(CryptoProObjectIdentifiers.GostR3410x94, gost3410PublicKeyAlgParameters2.ToAsn1Object());
         return(new SubjectPublicKeyInfo(algID3, new DerOctetString(array3)));
     }
     throw new ArgumentException("Class provided no convertible: " + Platform.GetTypeName(key));
 }
Esempio n. 7
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);
            }
        }
Esempio n. 8
0
        private void doTestEnc(
            int size,
            int privateValueSize,
            IBigInteger g,
            IBigInteger p)
        {
            ElGamalParameters dhParams = new ElGamalParameters(p, g, privateValueSize);
            ElGamalKeyGenerationParameters ekgParams = new ElGamalKeyGenerationParameters(new SecureRandom(), dhParams);
            ElGamalKeyPairGenerator        kpGen     = new ElGamalKeyPairGenerator();

            kpGen.Init(ekgParams);

            //
            // generate pair
            //
            IAsymmetricCipherKeyPair pair = kpGen.GenerateKeyPair();

            ElGamalPublicKeyParameters  pu = (ElGamalPublicKeyParameters)pair.Public;
            ElGamalPrivateKeyParameters pv = (ElGamalPrivateKeyParameters)pair.Private;

            checkKeySize(privateValueSize, pv);

            ElGamalEngine e = new ElGamalEngine();

            e.Init(true, pu);

            if (e.GetOutputBlockSize() != size / 4)
            {
                Fail(size + " GetOutputBlockSize() on encryption failed.");
            }

            byte[] message = Hex.Decode("5468697320697320612074657374");

            byte[] pText = message;
            byte[] cText = e.ProcessBlock(pText, 0, pText.Length);

            e.Init(false, pv);

            if (e.GetOutputBlockSize() != (size / 8) - 1)
            {
                Fail(size + " GetOutputBlockSize() on decryption failed.");
            }

            pText = e.ProcessBlock(cText, 0, cText.Length);

            if (!Arrays.AreEqual(message, pText))
            {
                Fail(size + " bit test failed");
            }



            e.Init(true, pu);
            byte[] bytes = new byte[e.GetInputBlockSize() + 2];

            try
            {
                e.ProcessBlock(bytes, 0, bytes.Length);

                Fail("out of range block not detected");
            }
            catch (DataLengthException)
            {
                // expected
            }

            try
            {
                bytes[0] = (byte)0xff;

                e.ProcessBlock(bytes, 0, bytes.Length - 1);

                Fail("out of range block not detected");
            }
            catch (DataLengthException)
            {
                // expected
            }

            try
            {
                bytes[0] = (byte)0x7f;

                e.ProcessBlock(bytes, 0, bytes.Length - 1);
            }
            catch (DataLengthException)
            {
                Fail("in range block failed");
            }
        }