コード例 #1
0
        /// <summary>
        /// 以ECC演算法加密資料
        /// </summary>
        /// <param name="originalData">原始資料</param>
        /// <param name="anotherPubKey">解密者使用的公鑰資料</param>
        /// <param name="derivation">The derivation parameter for the KDF function.</param>
        /// <param name="encoding">The encoding parameter for the KDF function.</param>
        public byte[] EncryptData(byte[] originalData, byte[] anotherPubKey, byte[] derivation, byte[] encoding)
        {
            if (_ecLocalKeyPair == null)
            {
                Debug.WriteLine(String.Format("[EncryptData] Local key pair not create."));
                return(null);
            }

            byte[] ret = null;

            //ECPublicKeyParameters = public key header(24byte) + another public key(key field size - 24byte,)
            byte[] anoPubKeyInfoBytes            = ArrayHelpers.ConcatArrays(this.PubKeyHeaderBytes, anotherPubKey);
            ECPublicKeyParameters anoPubKeyParam = PublicKeyFactory.CreateKey(anoPubKeyInfoBytes) as ECPublicKeyParameters;

            IesEngine ies = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha256Digest()),
                new HMac(new Sha256Digest()));
            IesParameters iesParam = new IesParameters(derivation, encoding, 256);

            try
            {
                ies.Init(true, _ecLocalKeyPair.Private, anoPubKeyParam, iesParam);
                ret = ies.ProcessBlock(originalData, 0, originalData.Length);
            }
            catch (Exception e)
            {
                Debug.WriteLine(String.Format("[EncryptData] Init IES Enging fail:{0}", e.Message));
                return(null);
            }

            return(ret);
        }
コード例 #2
0
        /// <summary>
        /// 解密函数
        /// </summary>
        /// <param name="privKey">椭圆曲线私钥</param>
        /// <param name="pubRand">加密所用随机密钥对的公钥</param>
        /// <param name="ciphertext">密文</param>
        /// <returns>明文</returns>
        public byte[] Decrypt(ECPrivateKeyParameters privKey, ECPublicKeyParameters pubRand, byte[] ciphertext)
        {
            IesEngine engine = IesEngineFactory();

            engine.Init(false, privKey, pubRand, iesParam);
            return(engine.ProcessBlock(ciphertext, 0, ciphertext.Length));
        }
コード例 #3
0
        /// <summary>
        /// 加密函数
        /// </summary>
        /// <param name="pubKey">椭圆曲线公钥</param>
        /// <param name="privRand">一个随机密钥对的私钥</param>
        /// <param name="message">明文</param>
        /// <returns>密文</returns>
        public byte[] Encrypt(ECPublicKeyParameters pubKey, ECPrivateKeyParameters privRand, byte[] message)
        {
            IesEngine engine = IesEngineFactory();

            engine.Init(true, privRand, pubKey, iesParam);
            return(engine.ProcessBlock(message, 0, message.Length));
        }
コード例 #4
0
 public BufferedIesCipher(IesEngine engine)
 {
     if (engine == null)
     {
         throw new ArgumentNullException("engine");
     }
     this.engine = engine;
 }
コード例 #5
0
 public BufferedIesCipher(IesEngine engine)
 {
     //IL_0001: Unknown result type (might be due to invalid IL or missing references)
     //IL_000b: Expected O, but got Unknown
     //IL_0019: Unknown result type (might be due to invalid IL or missing references)
     if (engine == null)
     {
         throw new ArgumentNullException("engine");
     }
     this.engine = engine;
 }
コード例 #6
0
        protected static IesEngine CreateCipherEngine(bool encrypt, ICipherParameters privParameters, ICipherParameters pubParameters)
        {
            var engine = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha256Digest()),
                new HMac(new Sha256Digest()),
                new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesFastEngine())));

            var parameterSpec = new IesWithCipherParameters(derivation, encoding, 256, 256);

            engine.Init(encrypt, privParameters, pubParameters, parameterSpec);
            return(engine);
        }
コード例 #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="forEncryption"></param>
        /// <param name="publicKeyBytes"></param>
        /// <returns></returns>
        protected IesEngine CreateIesEngine(bool forEncryption, byte[] publicKeyBytes)
        {
            // TODO ensure parameters are safe enough
            IesEngine iesEngine = new IesEngine(new ECDHBasicAgreement(), new Kdf2BytesGenerator(new Sha1Digest()), new HMac(new Sha1Digest()));

            byte[]        d          = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            byte[]        e          = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
            IesParameters parameters = new IesParameters(d, e, 64);

            ECPublicKeyParameters publicKey = new ECPublicKeyParameters(X9.Curve.DecodePoint(publicKeyBytes), EcSpec);

            iesEngine.Init(forEncryption, KeyPair.Private, (AsymmetricKeyParameter)publicKey, parameters);
            return(iesEngine);
        }
コード例 #8
0
        public static string DecryptElliptical(this string data, string publicKey, string myPrivateKey)
        {
            var d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            var e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
            var p = new IesWithCipherParameters(d, e, 64, 128);

            IesEngine e2 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha256Digest()),                                        // #1
                new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesEngine()))); // #6

            e2.Init(false, ConvertPrivateToParameters(myPrivateKey), ConvertPublicToParameters(publicKey), p);
            var bytes = Convert.FromBase64String(data);

            return(Encoding.UTF8.GetString(e2.ProcessBlock(bytes, 0, bytes.Length)));
        }
コード例 #9
0
        public static string EncryptElliptical(this string data, string publicKey, string myPrivateKey)
        {
            IesEngine e1 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha256Digest()),                                        // #1
                new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesEngine()))); // #6
            var d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            var e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
            var p = new IesWithCipherParameters(d, e, 64, 128);

            //IesWithCipherParameters parameterSpec = new IesWithCipherParameters(null, null, 256, 256);
            e1.Init(true, ConvertPrivateToParameters(myPrivateKey), ConvertPublicToParameters(publicKey), p);
            byte[] bytes = Encoding.UTF8.GetBytes(data);
            return(Convert.ToBase64String(e1.ProcessBlock(bytes, 0, bytes.Length)));
            ////BufferedIesCipher c1 = new BufferedIesCipher(e1);
            ////c1.engineSetMode("DHAES");
            ////c1.Init(true, keyParameters);
            ////var ciphertext = c1.DoFinal(Encoding.UTF8.GetBytes(@"test"));

            //IesEngine e2 = new IesEngine(
            //   new ECDHBasicAgreement(),
            //   new Kdf2BytesGenerator(new Sha1Digest()),
            //   new HMac(new Sha256Digest()), // #1
            //   new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesEngine()))); // #6
            //e2.Init(false, privateParameters, publicParameters, p);
            //var result = e2.ProcessBlock(ct, 0, ct.Length);
            //var text = Encoding.UTF8.GetString(result);
            ////IesParameterSpec parameterSpec = new IESParameterSpec(null, null, macKeySize, cipherKeySize);

            ////byte[] pubaddr = new byte[65];
            ////byte[] Y = dd.Y.ToBigInteger().ToByteArray();
            ////Array.Copy(Y, 0, pubaddr, 64 - Y.Length + 1, Y.Length);
            ////byte[] X = dd.X.ToBigInteger().ToByteArray();
            ////Array.Copy(X, 0, pubaddr, 32 - X.Length + 1, X.Length);
            ////pubaddr[0] = 4;

            //return null;
        }
コード例 #10
0
ファイル: ECIESTest.cs プロジェクト: eigenvector11/TestClient
        private void StaticTest()
        {
            FpCurve curve = new FpCurve(
                new BigInteger("6277101735386680763835789423207666416083908700390324961279"),           // q
                new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16),                 // a
                new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16));                // b

            ECDomainParameters parameters = new ECDomainParameters(
                curve,
                curve.DecodePoint(Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")),           // G
                new BigInteger("6277101735386680763835789423176059013767194773182842284081"));                 // n

            ECPrivateKeyParameters priKey = new ECPrivateKeyParameters(
                "ECDH",
                new BigInteger("651056770906015076056810763456358567190100156695615665659"),                 // d
                parameters);

            ECPublicKeyParameters pubKey = new ECPublicKeyParameters(
                "ECDH",
                curve.DecodePoint(Hex.Decode("0262b12d60690cdcf330babab6e69763b471f994dd702d16a5")),                 // Q
                parameters);

            AsymmetricCipherKeyPair p1 = new AsymmetricCipherKeyPair(pubKey, priKey);
            AsymmetricCipherKeyPair p2 = new AsymmetricCipherKeyPair(pubKey, priKey);

            //
            // stream test
            //
            IesEngine i1 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()));
            IesEngine i2 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()));

            byte[]        d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            byte[]        e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
            IesParameters p = new IesParameters(d, e, 64);

            i1.Init(true, p1.Private, p2.Public, p);
            i2.Init(false, p2.Private, p1.Public, p);

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

            byte[] out1 = i1.ProcessBlock(message, 0, message.Length);

            if (!AreEqual(out1, Hex.Decode("2442ae1fbf90dd9c06b0dcc3b27e69bd11c9aee4ad4cfc9e50eceb44")))
            {
                Fail("stream cipher test failed on enc");
            }

            byte[] out2 = i2.ProcessBlock(out1, 0, out1.Length);

            if (!AreEqual(out2, message))
            {
                Fail("stream cipher test failed");
            }

            //
            // twofish with CBC
            //
            BufferedBlockCipher c1 = new PaddedBufferedBlockCipher(
                new CbcBlockCipher(new TwofishEngine()));
            BufferedBlockCipher c2 = new PaddedBufferedBlockCipher(
                new CbcBlockCipher(new TwofishEngine()));

            i1 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()),
                c1);
            i2 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()),
                c2);
            d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
            p = new IesWithCipherParameters(d, e, 64, 128);

            i1.Init(true, p1.Private, p2.Public, p);
            i2.Init(false, p2.Private, p1.Public, p);

            message = Hex.Decode("1234567890abcdef");

            out1 = i1.ProcessBlock(message, 0, message.Length);

            if (!AreEqual(out1, Hex.Decode("2ea288651e21576215f2424bbb3f68816e282e3931b44bd1c429ebdb5f1b290cf1b13309")))
            {
                Fail("twofish cipher test failed on enc");
            }

            out2 = i2.ProcessBlock(out1, 0, out1.Length);

            if (!AreEqual(out2, message))
            {
                Fail("twofish cipher test failed");
            }
        }
コード例 #11
0
ファイル: ECIESTest.cs プロジェクト: eigenvector11/TestClient
        private void DoTest(
            AsymmetricCipherKeyPair p1,
            AsymmetricCipherKeyPair p2)
        {
            //
            // stream test
            //
            IesEngine i1 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()));
            IesEngine i2 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()));

            byte[]        d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            byte[]        e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
            IesParameters p = new IesParameters(d, e, 64);

            i1.Init(true, p1.Private, p2.Public, p);
            i2.Init(false, p2.Private, p1.Public, p);

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

            byte[] out1 = i1.ProcessBlock(message, 0, message.Length);

            byte[] out2 = i2.ProcessBlock(out1, 0, out1.Length);

            if (!AreEqual(out2, message))
            {
                Fail("stream cipher test failed");
            }

            //
            // twofish with CBC
            //
            BufferedBlockCipher c1 = new PaddedBufferedBlockCipher(
                new CbcBlockCipher(new TwofishEngine()));
            BufferedBlockCipher c2 = new PaddedBufferedBlockCipher(
                new CbcBlockCipher(new TwofishEngine()));

            i1 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()),
                c1);
            i2 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()),
                c2);
            d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
            p = new IesWithCipherParameters(d, e, 64, 128);

            i1.Init(true, p1.Private, p2.Public, p);
            i2.Init(false, p2.Private, p1.Public, p);

            message = Hex.Decode("1234567890abcdef");

            out1 = i1.ProcessBlock(message, 0, message.Length);

            out2 = i2.ProcessBlock(out1, 0, out1.Length);

            if (!AreEqual(out2, message))
            {
                Fail("twofish cipher test failed");
            }
        }
コード例 #12
0
        private void StaticTest()
        {
            BigInteger n = new BigInteger("6277101735386680763835789423176059013767194773182842284081");

            FpCurve curve = new FpCurve(
                new BigInteger("6277101735386680763835789423207666416083908700390324961279"), // q
                new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16),       // a
                new BigInteger("64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", 16),       // b
                n, BigInteger.One);

            ECDomainParameters parameters = new ECDomainParameters(
                curve,
                curve.DecodePoint(Hex.Decode("03188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012")), // G
                n, BigInteger.One);

            ECPrivateKeyParameters priKey = new ECPrivateKeyParameters(
                "ECDH",
                new BigInteger("651056770906015076056810763456358567190100156695615665659"), // d
                parameters);

            ECPublicKeyParameters pubKey = new ECPublicKeyParameters(
                "ECDH",
                curve.DecodePoint(Hex.Decode("0262b12d60690cdcf330babab6e69763b471f994dd702d16a5")), // Q
                parameters);

            AsymmetricCipherKeyPair p1 = new AsymmetricCipherKeyPair(pubKey, priKey);
            AsymmetricCipherKeyPair p2 = new AsymmetricCipherKeyPair(pubKey, priKey);

            //
            // stream test
            //
            IesEngine i1 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()));
            IesEngine i2 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()));

            byte[]        d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            byte[]        e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
            IesParameters p = new IesParameters(d, e, 64);

            i1.Init(true, p1.Private, p2.Public, p);
            i2.Init(false, p2.Private, p1.Public, p);

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

            byte[] out1 = i1.ProcessBlock(message, 0, message.Length);

            if (!AreEqual(out1, Hex.Decode("468d89877e8238802403ec4cb6b329faeccfa6f3a730f2cdb3c0a8e8")))
            {
                Fail("stream cipher test failed on enc");
            }

            byte[] out2 = i2.ProcessBlock(out1, 0, out1.Length);

            if (!AreEqual(out2, message))
            {
                Fail("stream cipher test failed");
            }

            //
            // twofish with CBC
            //
            BufferedBlockCipher c1 = new PaddedBufferedBlockCipher(
                new CbcBlockCipher(new TwofishEngine()));
            BufferedBlockCipher c2 = new PaddedBufferedBlockCipher(
                new CbcBlockCipher(new TwofishEngine()));

            i1 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()),
                c1);
            i2 = new IesEngine(
                new ECDHBasicAgreement(),
                new Kdf2BytesGenerator(new Sha1Digest()),
                new HMac(new Sha1Digest()),
                c2);
            d = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 };
            e = new byte[] { 8, 7, 6, 5, 4, 3, 2, 1 };
            p = new IesWithCipherParameters(d, e, 64, 128);

            i1.Init(true, p1.Private, p2.Public, p);
            i2.Init(false, p2.Private, p1.Public, p);

            message = Hex.Decode("1234567890abcdef");

            out1 = i1.ProcessBlock(message, 0, message.Length);

            if (!AreEqual(out1, Hex.Decode("b8a06ea5c2b9df28b58a0a90a734cde8c9c02903e5c220021fe4417410d1e53a32a71696")))
            {
                Fail("twofish cipher test failed on enc");
            }

            out2 = i2.ProcessBlock(out1, 0, out1.Length);

            if (!AreEqual(out2, message))
            {
                Fail("twofish cipher test failed");
            }
        }
コード例 #13
0
        /// <summary>
        /// Decrypts data using receiver public key and own keypair
        /// </summary>
        /// <param name="senderPublicKeyBytes">key to decrypt with</param>
        /// <param name="encodedData">data to decrypt</param>
        /// <returns>decrypted data</returns>
        protected byte[] DecryptData(byte[] senderPublicKeyBytes, byte[] encodedData)
        {
            IesEngine iesEngine = CreateIesEngine(false, senderPublicKeyBytes);

            return(iesEngine.ProcessBlock(encodedData, 0, encodedData.Length));
        }
コード例 #14
0
        /// <summary>
        /// Encrypts data using receiver public key and own keypair
        /// </summary>
        /// <param name="receiverPublicKeyBytes">key to encrypt with</param>
        /// <param name="data">data to encrypt</param>
        /// <returns>encrypted data</returns>
        protected byte[] EncryptData(byte[] receiverPublicKeyBytes, byte[] data)
        {
            IesEngine iesEngine = CreateIesEngine(true, receiverPublicKeyBytes);

            return(iesEngine.ProcessBlock(data, 0, data.Length));
        }
コード例 #15
0
        public static IBufferedCipher GetCipher(string algorithm)
        {
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }

            algorithm = Platform.StringToUpper(algorithm);

            var aliased = (string)_algorithms[algorithm];

            if (aliased != null)
            {
                algorithm = aliased;
            }


            IesEngine iesEngine = null;

            switch (algorithm)
            {
            case "IES":
                iesEngine = new IesEngine(new DHBasicAgreement(), new Kdf2BytesGenerator(new Sha1Digest()), new HMac(new Sha1Digest()));
                break;

            case "ECIES":
                iesEngine = new IesEngine(new ECDHBasicAgreement(), new Kdf2BytesGenerator(new Sha1Digest()), new HMac(new Sha1Digest()));
                break;

            case "ECCCDHIES":
                iesEngine = new IesEngine(new ECDHBasicAgreement());
                break;
            }

            if (iesEngine != null)
            {
                return(new BufferedIesCipher(iesEngine));
            }

            if (algorithm.StartsWith("PBE"))
            {
                if (algorithm.EndsWith("-CBC"))
                {
                    if (algorithm == "PBEWITHSHA1ANDDES-CBC")
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new DesEngine())));
                    }
                    if (algorithm == "PBEWITHSHA1ANDRC2-CBC")
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new RC2Engine())));
                    }
                    if (Strings.IsOneOf(algorithm,
                                        "PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"))
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new DesEdeEngine())));
                    }
                    if (Strings.IsOneOf(algorithm,
                                        "PBEWITHSHAAND128BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC"))
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new RC2Engine())));
                    }
                }
                else if (algorithm.EndsWith("-BC") || algorithm.EndsWith("-OPENSSL"))
                {
                    if (Strings.IsOneOf(algorithm,
                                        "PBEWITHSHAAND128BITAES-CBC-BC",
                                        "PBEWITHSHAAND192BITAES-CBC-BC",
                                        "PBEWITHSHAAND256BITAES-CBC-BC",
                                        "PBEWITHSHA256AND128BITAES-CBC-BC",
                                        "PBEWITHSHA256AND192BITAES-CBC-BC",
                                        "PBEWITHSHA256AND256BITAES-CBC-BC",
                                        "PBEWITHMD5AND128BITAES-CBC-OPENSSL",
                                        "PBEWITHMD5AND192BITAES-CBC-OPENSSL",
                                        "PBEWITHMD5AND256BITAES-CBC-OPENSSL"))
                    {
                        return(new PaddedBufferedBlockCipher(new CbcBlockCipher(new AesFastEngine())));
                    }
                }
            }


            var parts = algorithm.Split('/');

            IBlockCipher           blockCipher     = null;
            IAsymmetricBlockCipher asymBlockCipher = null;
            IStreamCipher          streamCipher    = null;

            var             algorithmName = parts[0];
            CipherAlgorithm cipherAlgorithm;

            try
            {
                cipherAlgorithm = (CipherAlgorithm)Enums.GetEnumValue(typeof(CipherAlgorithm), algorithmName);
            }
            catch (ArgumentException)
            {
                throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }

            switch (cipherAlgorithm)
            {
            case CipherAlgorithm.AES:
                blockCipher = new AesFastEngine();
                break;

            case CipherAlgorithm.ARC4:
                streamCipher = new RC4Engine();
                break;

            case CipherAlgorithm.BLOWFISH:
                blockCipher = new BlowfishEngine();
                break;

            case CipherAlgorithm.CAMELLIA:
                blockCipher = new CamelliaEngine();
                break;

            case CipherAlgorithm.CAST5:
                blockCipher = new Cast5Engine();
                break;

            case CipherAlgorithm.CAST6:
                blockCipher = new Cast6Engine();
                break;

            case CipherAlgorithm.DES:
                blockCipher = new DesEngine();
                break;

            case CipherAlgorithm.DESEDE:
                blockCipher = new DesEdeEngine();
                break;

            case CipherAlgorithm.ELGAMAL:
                asymBlockCipher = new ElGamalEngine();
                break;

            case CipherAlgorithm.GOST28147:
                blockCipher = new Gost28147Engine();
                break;

            case CipherAlgorithm.HC128:
                streamCipher = new HC128Engine();
                break;

            case CipherAlgorithm.HC256:
                streamCipher = new HC256Engine();
                break;

            case CipherAlgorithm.IDEA:
#if INCLUDE_IDEA
                blockCipher = new IdeaEngine();
                break;
#else
                throw new SecurityUtilityException("Cipher " + algorithm + " not included.");
#endif
            case CipherAlgorithm.NOEKEON:
                blockCipher = new NoekeonEngine();
                break;

            case CipherAlgorithm.PBEWITHSHAAND128BITRC4:
            case CipherAlgorithm.PBEWITHSHAAND40BITRC4:
                streamCipher = new RC4Engine();
                break;

            case CipherAlgorithm.RC2:
                blockCipher = new RC2Engine();
                break;

            case CipherAlgorithm.RC5:
                blockCipher = new RC532Engine();
                break;

            case CipherAlgorithm.RC5_64:
                blockCipher = new RC564Engine();
                break;

            case CipherAlgorithm.RC6:
                blockCipher = new RC6Engine();
                break;

            case CipherAlgorithm.RIJNDAEL:
                blockCipher = new RijndaelEngine();
                break;

            case CipherAlgorithm.RSA:
                asymBlockCipher = new RsaBlindedEngine();
                break;

            case CipherAlgorithm.SALSA20:
                streamCipher = new Salsa20Engine();
                break;

            case CipherAlgorithm.SEED:
                blockCipher = new SeedEngine();
                break;

            case CipherAlgorithm.SERPENT:
                blockCipher = new SerpentEngine();
                break;

            case CipherAlgorithm.SKIPJACK:
                blockCipher = new SkipjackEngine();
                break;

            case CipherAlgorithm.TEA:
                blockCipher = new TeaEngine();
                break;

            case CipherAlgorithm.TWOFISH:
                blockCipher = new TwofishEngine();
                break;

            case CipherAlgorithm.VMPC:
                streamCipher = new VmpcEngine();
                break;

            case CipherAlgorithm.VMPC_KSA3:
                streamCipher = new VmpcKsa3Engine();
                break;

            case CipherAlgorithm.XTEA:
                blockCipher = new XteaEngine();
                break;

            default:
                throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
            }

            if (streamCipher != null)
            {
                if (parts.Length > 1)
                {
                    throw new ArgumentException("Modes and paddings not used for stream ciphers");
                }

                return(new BufferedStreamCipher(streamCipher));
            }


            var cts    = false;
            var padded = true;
            IBlockCipherPadding padding         = null;
            IAeadBlockCipher    aeadBlockCipher = null;

            if (parts.Length > 2)
            {
                var paddingName = parts[2];

                CipherPadding cipherPadding;
                switch (paddingName)
                {
                case "":
                    cipherPadding = CipherPadding.RAW;
                    break;

                case "X9.23PADDING":
                    cipherPadding = CipherPadding.X923PADDING;
                    break;

                default:
                    try
                    {
                        cipherPadding = (CipherPadding)Enums.GetEnumValue(typeof(CipherPadding), paddingName);
                    }
                    catch (ArgumentException)
                    {
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                    }
                    break;
                }

                switch (cipherPadding)
                {
                case CipherPadding.NOPADDING:
                    padded = false;
                    break;

                case CipherPadding.RAW:
                    break;

                case CipherPadding.ISO10126PADDING:
                case CipherPadding.ISO10126D2PADDING:
                case CipherPadding.ISO10126_2PADDING:
                    padding = new ISO10126d2Padding();
                    break;

                case CipherPadding.ISO7816_4PADDING:
                case CipherPadding.ISO9797_1PADDING:
                    padding = new ISO7816d4Padding();
                    break;

                case CipherPadding.ISO9796_1:
                case CipherPadding.ISO9796_1PADDING:
                    asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher);
                    break;

                case CipherPadding.OAEP:
                case CipherPadding.OAEPPADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher);
                    break;

                case CipherPadding.OAEPWITHMD5ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new MD5Digest());
                    break;

                case CipherPadding.OAEPWITHSHA1ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_1ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
                    break;

                case CipherPadding.OAEPWITHSHA224ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_224ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
                    break;

                case CipherPadding.OAEPWITHSHA256ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_256ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
                    break;

                case CipherPadding.OAEPWITHSHA384ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_384ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
                    break;

                case CipherPadding.OAEPWITHSHA512ANDMGF1PADDING:
                case CipherPadding.OAEPWITHSHA_512ANDMGF1PADDING:
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
                    break;

                case CipherPadding.PKCS1:
                case CipherPadding.PKCS1PADDING:
                    asymBlockCipher = new Pkcs1Encoding(asymBlockCipher);
                    break;

                case CipherPadding.PKCS5:
                case CipherPadding.PKCS5PADDING:
                case CipherPadding.PKCS7:
                case CipherPadding.PKCS7PADDING:
                    padding = new Pkcs7Padding();
                    break;

                case CipherPadding.TBCPADDING:
                    padding = new TbcPadding();
                    break;

                case CipherPadding.WITHCTS:
                    cts = true;
                    break;

                case CipherPadding.X923PADDING:
                    padding = new X923Padding();
                    break;

                case CipherPadding.ZEROBYTEPADDING:
                    padding = new ZeroBytePadding();
                    break;

                default:
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            if (parts.Length > 1)
            {
                var mode = parts[1];

                var di       = GetDigitIndex(mode);
                var modeName = di >= 0 ? mode.Substring(0, di) : mode;

                try
                {
                    var cipherMode = modeName == ""
                        ? CipherMode.NONE
                        : (CipherMode)Enums.GetEnumValue(typeof(CipherMode), modeName);

                    switch (cipherMode)
                    {
                    case CipherMode.ECB:
                    case CipherMode.NONE:
                        break;

                    case CipherMode.CBC:
                        blockCipher = new CbcBlockCipher(blockCipher);
                        break;

                    case CipherMode.CCM:
                        aeadBlockCipher = new CcmBlockCipher(blockCipher);
                        break;

                    case CipherMode.CFB:
                    {
                        var bits = (di < 0)
                                               ? 8 * blockCipher.GetBlockSize()
                                               : int.Parse(mode.Substring(di));

                        blockCipher = new CfbBlockCipher(blockCipher, bits);
                        break;
                    }

                    case CipherMode.CTR:
                        blockCipher = new SicBlockCipher(blockCipher);
                        break;

                    case CipherMode.CTS:
                        cts         = true;
                        blockCipher = new CbcBlockCipher(blockCipher);
                        break;

                    case CipherMode.EAX:
                        aeadBlockCipher = new EaxBlockCipher(blockCipher);
                        break;

                    case CipherMode.GCM:
                        aeadBlockCipher = new GcmBlockCipher(blockCipher);
                        break;

                    case CipherMode.GOFB:
                        blockCipher = new GOfbBlockCipher(blockCipher);
                        break;

                    case CipherMode.OFB:
                    {
                        var bits = (di < 0)
                                               ? 8 * blockCipher.GetBlockSize()
                                               : int.Parse(mode.Substring(di));

                        blockCipher = new OfbBlockCipher(blockCipher, bits);
                        break;
                    }

                    case CipherMode.OPENPGPCFB:
                        blockCipher = new OpenPgpCfbBlockCipher(blockCipher);
                        break;

                    case CipherMode.SIC:
                        if (blockCipher.GetBlockSize() < 16)
                        {
                            throw new ArgumentException(
                                      "Warning: SIC-Mode can become a twotime-pad if the blocksize of the cipher is too small. Use a cipher with a block size of at least 128 bits (e.g. AES)");
                        }
                        blockCipher = new SicBlockCipher(blockCipher);
                        break;

                    default:
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                    }
                }
                catch (ArgumentException)
                {
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }

            if (aeadBlockCipher != null)
            {
                if (cts)
                {
                    throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers.");
                }
                if (padded && parts.Length > 2 && parts[2] != "")
                {
                    throw new SecurityUtilityException("Bad padding specified for AEAD cipher.");
                }

                return(new BufferedAeadBlockCipher(aeadBlockCipher));
            }

            if (blockCipher != null)
            {
                if (cts)
                {
                    return(new CtsBlockCipher(blockCipher));
                }

                if (padding != null)
                {
                    return(new PaddedBufferedBlockCipher(blockCipher, padding));
                }

                if (!padded || blockCipher.IsPartialBlockOkay)
                {
                    return(new BufferedBlockCipher(blockCipher));
                }

                return(new PaddedBufferedBlockCipher(blockCipher));
            }

            if (asymBlockCipher != null)
            {
                return(new BufferedAsymmetricBlockCipher(asymBlockCipher));
            }

            throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
        }