Пример #1
0
        private byte[] GetDecodeKey(byte[] salt, byte[] pin)
        {
            byte[] pincode4 = new byte[pin.Length * 4];
            for (int i = 0; i < pin.Length; ++i)
            {
                pincode4[i * 4] = pin[i];
            }

            IDigest digest =
                ProviderType == ProviderType.CryptoPro_2001
                    ? new Gost3411Digest(Gost28147Engine.GetSBox("D-A")) as IDigest
                    : new Gost3411_2012_256Digest();

            digest.BlockUpdate(salt, 0, salt.Length);
            if (pin.Length > 0)
            {
                digest.BlockUpdate(pincode4, 0, pincode4.Length);
            }

            byte[] result = new byte[digest.GetDigestSize()];
            digest.DoFinal(result, 0);

            int len = ProviderType == ProviderType.CryptoPro_2001 ? 32 : 64;

            byte[] material36 = new byte[len];
            byte[] material5c = new byte[len];
            byte[] current    = new byte[len];

            Array.Copy(Encoding.ASCII.GetBytes("DENEFH028.760246785.IUEFHWUIO.EF"), current, 32);

            len = pin.Length > 0 ? 2000 : 2;
            for (int i = 0; i < len; ++i)
            {
                XorMaterial(material36, material5c, current);
                digest.Reset();
                digest.BlockUpdate(material36, 0, material36.Length);
                digest.BlockUpdate(result, 0, result.Length);
                digest.BlockUpdate(material5c, 0, material5c.Length);
                digest.BlockUpdate(result, 0, result.Length);
                digest.DoFinal(current, 0);
            }

            XorMaterial(material36, material5c, current);
            digest.Reset();
            digest.BlockUpdate(material36, 0, 32);
            digest.BlockUpdate(salt, 0, salt.Length);
            digest.BlockUpdate(material5c, 0, 32);
            if (pin.Length > 0)
            {
                digest.BlockUpdate(pincode4, 0, pincode4.Length);
            }
            digest.DoFinal(current, 0);

            byte[] result_key = new byte[digest.GetDigestSize()];
            digest.Reset();
            digest.BlockUpdate(current, 0, 32);
            digest.DoFinal(result_key, 0);

            return(result_key);
        }
Пример #2
0
        /**
         * Standard constructor
         */
        public Gost3411Digest()
        {
            sBox = Gost28147Engine.GetSBox("D-A");
            cipher.Init(true, new ParametersWithSBox(null, sBox));

            Reset();
        }
        private static byte[] DecryptKey(byte[] key, byte[] cek, byte[] iv = null)
        {
            var cipher             = CipherUtilities.GetCipher("GOST/CFB/NOPADDING");
            ICipherParameters prms = ParameterUtilities.CreateKeyParameter("GOST", key);

            prms = new ParametersWithSBox(prms, Gost28147Engine.GetSBox("E-A"));
            cipher.Init(false, iv == null ? prms : new ParametersWithIV(prms, iv));
            return(cipher.ProcessBytes(cek));
        }
        private byte[] GetDecodeKey(byte[] salt, byte[] pin)
        {
            var pincode4 = new byte[pin.Length * 4];

            for (int i = 0; i < pin.Length; ++i)
            {
                pincode4[i * 4] = pin[i];
            }

            var digest = new Gost3411Digest(Gost28147Engine.GetSBox("D-A"));

            digest.BlockUpdate(salt, 0, salt.Length);
            if (pin.Length > 0)
            {
                digest.BlockUpdate(pincode4, 0, pincode4.Length);
            }

            var result = new byte[32];

            digest.DoFinal(result, 0);

            var current    = Encoding.ASCII.GetBytes("DENEFH028.760246785.IUEFHWUIO.EF");
            var material36 = new byte[32];
            var material5c = new byte[32];
            int len        = pin.Length > 0 ? 2000 : 2;

            for (int i = 0; i < len; ++i)
            {
                XorMaterial(material36, material5c, current);
                digest.Reset();
                digest.BlockUpdate(material36, 0, 32);
                digest.BlockUpdate(result, 0, 32);
                digest.BlockUpdate(material5c, 0, 32);
                digest.BlockUpdate(result, 0, 32);
                digest.DoFinal(current, 0);
            }

            XorMaterial(material36, material5c, current);
            digest.Reset();
            digest.BlockUpdate(material36, 0, 32);
            digest.BlockUpdate(salt, 0, 12);
            digest.BlockUpdate(material5c, 0, 32);
            if (pin.Length > 0)
            {
                digest.BlockUpdate(pincode4, 0, pincode4.Length);
            }
            digest.DoFinal(current, 0);

            var result_key = new byte[32];

            digest.Reset();
            digest.BlockUpdate(current, 0, 32);
            digest.DoFinal(result_key, 0);

            return(result_key);
        }
Пример #5
0
        /**
         * Standard constructor
         */
        public Gost3411Digest()
        {
            // TODO Is it possible to declare multi-dimensional arrays as in Java?
            for (int i = 0; i < 4; ++i)
            {
                C[i] = new byte[32];
            }

            cipher.Init(true, new ParametersWithSBox(null, Gost28147Engine.GetSBox("D-A")));

            Reset();
        }
Пример #6
0
        // https://tools.ietf.org/html/rfc4357#section-6.4
        public byte[] UnwrapKey(byte[] kek)
        {
            var cipher  = CipherUtilities.GetCipher("GOST/ECB/NOPADDING");
            var kek_ukm = KEKDiversification(kek, UKM);
            var prms    = ParameterUtilities.CreateKeyParameter("GOST", kek_ukm);

            cipher.Init(false, new ParametersWithSBox(prms, Gost28147Engine.GetSBox("E-A")));

            var cekDecrypted = cipher.ProcessBytes(CEK);

            CheckMac(cekDecrypted, kek_ukm);

            return(cekDecrypted);
        }
        private BigInteger DecodePrimaryKey(byte[] decodeKey, byte[] primaryKey)
        {
            var engine = new Gost28147Engine();
            var param  = new ParametersWithSBox(
                new KeyParameter(decodeKey),
                Gost28147Engine.GetSBox("E-A"));

            engine.Init(false, param);

            var buf = new byte[32];

            engine.ProcessBlock(primaryKey, 0, buf, 0);
            engine.ProcessBlock(primaryKey, 8, buf, 8);
            engine.ProcessBlock(primaryKey, 16, buf, 16);
            engine.ProcessBlock(primaryKey, 24, buf, 24);

            return(new BigInteger(1, buf.Reverse().ToArray()));
        }
        // https://tools.ietf.org/html/rfc4357#section-6.5
        protected override byte[] KEKDiversification(byte[] kek, byte[] ukm)
        {
            var cipher = CipherUtilities.GetCipher("GOST/CFB/NOPADDING");
            var result = new byte[32];

            Array.Copy(kek, result, 32);
            var S = new byte[8];

            for (int i = 0; i < 8; ++i)
            {
                int sum1 = 0;
                int sum2 = 0;

                for (int j = 0, mask = 1; j < 8; ++j, mask <<= 1)
                {
                    var kj = (result[4 * j]) | (result[4 * j + 1] << 8) | (result[4 * j + 2] << 16) | (result[4 * j + 3] << 24);
                    if ((mask & ukm[i]) != 0)
                    {
                        sum1 += kj;
                    }
                    else
                    {
                        sum2 += kj;
                    }
                }

                S[0] = (byte)(sum1 & 0xff);
                S[1] = (byte)((sum1 >> 8) & 0xff);
                S[2] = (byte)((sum1 >> 16) & 0xff);
                S[3] = (byte)((sum1 >> 24) & 0xff);
                S[4] = (byte)(sum2 & 0xff);
                S[5] = (byte)((sum2 >> 8) & 0xff);
                S[6] = (byte)((sum2 >> 16) & 0xff);
                S[7] = (byte)((sum2 >> 24) & 0xff);

                var key  = ParameterUtilities.CreateKeyParameter("GOST", result);
                var sbox = new ParametersWithSBox(key, Gost28147Engine.GetSBox("E-A"));
                var prms = new ParametersWithIV(sbox, S);
                cipher.Init(true, prms);
                result = cipher.ProcessBytes(result);
            }

            return(result);
        }
Пример #9
0
        public ITestResult Perform()
        {
            // test1
            IMac         mac = new Gost28147Mac();
            KeyParameter key = new KeyParameter(gkeyBytes1);

            mac.Init(key);

            mac.BlockUpdate(input3, 0, input3.Length);

            byte[] outBytes = new byte[4];

            mac.DoFinal(outBytes, 0);

            if (!Arrays.AreEqual(outBytes, output7))
            {
                return(new SimpleTestResult(false, Name + ": Failed test 1 - expected "
                                            + Hex.ToHexString(output7)
                                            + " got " + Hex.ToHexString(outBytes)));
            }

            // test2
            key = new KeyParameter(gkeyBytes2);

            ParametersWithSBox gparam = new ParametersWithSBox(key, Gost28147Engine.GetSBox("E-A"));

            mac.Init(gparam);

            mac.BlockUpdate(input4, 0, input4.Length);

            outBytes = new byte[4];

            mac.DoFinal(outBytes, 0);

            if (!Arrays.AreEqual(outBytes, output8))
            {
                return(new SimpleTestResult(false, Name + ": Failed test 2 - expected "
                                            + Hex.ToHexString(output8)
                                            + " got " + Hex.ToHexString(outBytes)));
            }

            return(new SimpleTestResult(true, Name + ": Okay"));
        }
Пример #10
0
 public Gost3411Digest()
 {
     this.H      = new byte[0x20];
     this.L      = new byte[0x20];
     this.M      = new byte[0x20];
     this.Sum    = new byte[0x20];
     this.C      = MakeC();
     this.xBuf   = new byte[0x20];
     this.cipher = new Gost28147Engine();
     this.K      = new byte[0x20];
     this.a      = new byte[8];
     this.wS     = new short[0x10];
     this.w_S    = new short[0x10];
     this.S      = new byte[0x20];
     this.U      = new byte[0x20];
     this.V      = new byte[0x20];
     this.W      = new byte[0x20];
     this.sBox   = Gost28147Engine.GetSBox("D-A");
     this.cipher.Init(true, new ParametersWithSBox(null, this.sBox));
     this.Reset();
 }
Пример #11
0
        private BigInteger DecodePrimaryKey(byte[] decodeKey, byte[] primaryKey)
        {
            Gost28147Engine engine = new Gost28147Engine();

            byte[] sbox =
                ProviderType == ProviderType.CryptoPro_2001
                    ? Gost28147Engine.GetSBox("E-A")
                    : Gost28147_TC26ParamSetZ;

            ParametersWithSBox param = new ParametersWithSBox(
                new KeyParameter(decodeKey), sbox);

            engine.Init(false, param);

            byte[] buf = new byte[primaryKey.Length];
            for (int i = 0; i < primaryKey.Length; i += 8)
            {
                engine.ProcessBlock(primaryKey, i, buf, i);
            }

            return(new BigInteger(1, buf.Reverse().ToArray()));
        }
Пример #12
0
        private static byte[] GetSBox(Gost28147SBox sBox)
        {
            switch (sBox)
            {
            case Gost28147SBox.Default: return(null);

            case Gost28147SBox.D_Test: return(Gost28147Engine.GetSBox("D-Test"));

            case Gost28147SBox.D_A: return(Gost28147Engine.GetSBox("D-A"));

            case Gost28147SBox.E_Test: return(Gost28147Engine.GetSBox("E-Test"));

            case Gost28147SBox.E_A: return(Gost28147Engine.GetSBox("E-A"));

            case Gost28147SBox.E_B: return(Gost28147Engine.GetSBox("E-B"));

            case Gost28147SBox.E_C: return(Gost28147Engine.GetSBox("E-C"));

            case Gost28147SBox.E_D: return(Gost28147Engine.GetSBox("E-D"));

            default: throw new CryptographicException("Unsupported substitution box.");
            }
        }
Пример #13
0
        public static IBufferedCipher GetCipher(string algorithm)
        {
            //IL_0008: Unknown result type (might be due to invalid IL or missing references)
            //IL_0469: Unknown result type (might be due to invalid IL or missing references)
            //IL_0495: Unknown result type (might be due to invalid IL or missing references)
            //IL_07f1: Unknown result type (might be due to invalid IL or missing references)
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }
            algorithm = Platform.ToUpperInvariant(algorithm);
            string text = (string)algorithms.get_Item((object)algorithm);

            if (text != null)
            {
                algorithm = text;
            }
            IBasicAgreement basicAgreement = null;

            if (algorithm == "IES")
            {
                basicAgreement = new DHBasicAgreement();
            }
            else if (algorithm == "ECIES")
            {
                basicAgreement = new ECDHBasicAgreement();
            }
            if (basicAgreement != null)
            {
                return(new BufferedIesCipher(new IesEngine(basicAgreement, new Kdf2BytesGenerator(new Sha1Digest()), new HMac(new Sha1Digest()))));
            }
            if (Platform.StartsWith(algorithm, "PBE"))
            {
                if (Platform.EndsWith(algorithm, "-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 ((Platform.EndsWith(algorithm, "-BC") || Platform.EndsWith(algorithm, "-OPENSSL")) && 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())));
                }
            }
            string[] array = algorithm.Split(new char[1] {
                '/'
            });
            IBlockCipher           blockCipher           = null;
            IAsymmetricBlockCipher asymmetricBlockCipher = null;
            IStreamCipher          streamCipher          = null;
            string text2 = array[0];
            string text3 = (string)algorithms.get_Item((object)text2);

            if (text3 != null)
            {
                text2 = text3;
            }
            CipherAlgorithm cipherAlgorithm;

            try
            {
                cipherAlgorithm = (CipherAlgorithm)Enums.GetEnumValue(typeof(CipherAlgorithm), text2);
            }
            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:
                asymmetricBlockCipher = 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:
                blockCipher = new IdeaEngine();
                break;

            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:
                asymmetricBlockCipher = 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.THREEFISH_256:
                blockCipher = new ThreefishEngine(256);
                break;

            case CipherAlgorithm.THREEFISH_512:
                blockCipher = new ThreefishEngine(512);
                break;

            case CipherAlgorithm.THREEFISH_1024:
                blockCipher = new ThreefishEngine(1024);
                break;

            case CipherAlgorithm.TNEPRES:
                blockCipher = new TnepresEngine();
                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 (array.Length > 1)
                {
                    throw new ArgumentException("Modes and paddings not used for stream ciphers");
                }
                return(new BufferedStreamCipher(streamCipher));
            }
            bool flag  = false;
            bool flag2 = true;
            IBlockCipherPadding blockCipherPadding = null;
            IAeadBlockCipher    aeadBlockCipher    = null;

            if (array.Length > 2)
            {
                if (streamCipher != null)
                {
                    throw new ArgumentException("Paddings not used for stream ciphers");
                }
                string        text4 = array[2];
                CipherPadding cipherPadding;
                if (text4 == "")
                {
                    cipherPadding = CipherPadding.RAW;
                }
                else if (text4 == "X9.23PADDING")
                {
                    cipherPadding = CipherPadding.X923PADDING;
                }
                else
                {
                    try
                    {
                        cipherPadding = (CipherPadding)Enums.GetEnumValue(typeof(CipherPadding), text4);
                    }
                    catch (ArgumentException)
                    {
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                    }
                }
                switch (cipherPadding)
                {
                case CipherPadding.NOPADDING:
                    flag2 = false;
                    break;

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

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

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

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

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

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

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

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

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

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

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

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

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

                case CipherPadding.WITHCTS:
                    flag = true;
                    break;

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

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

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

                case CipherPadding.RAW:
                    break;
                }
            }
            string text5 = "";

            if (array.Length > 1)
            {
                text5 = array[1];
                int    digitIndex = GetDigitIndex(text5);
                string text6      = ((digitIndex >= 0) ? text5.Substring(0, digitIndex) : text5);
                try
                {
                    switch ((text6 == "") ? CipherMode.NONE : ((CipherMode)Enums.GetEnumValue(typeof(CipherMode), text6)))
                    {
                    case CipherMode.CBC:
                        blockCipher = new CbcBlockCipher(blockCipher);
                        break;

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

                    case CipherMode.CFB:
                    {
                        int bitBlockSize = ((digitIndex < 0) ? (8 * blockCipher.GetBlockSize()) : int.Parse(text5.Substring(digitIndex)));
                        blockCipher = new CfbBlockCipher(blockCipher, bitBlockSize);
                        break;
                    }

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

                    case CipherMode.CTS:
                        flag        = 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.OCB:
                        aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm));
                        break;

                    case CipherMode.OFB:
                    {
                        int blockSize = ((digitIndex < 0) ? (8 * blockCipher.GetBlockSize()) : int.Parse(text5.Substring(digitIndex)));
                        blockCipher = new OfbBlockCipher(blockCipher, blockSize);
                        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.");

                    case CipherMode.ECB:
                    case CipherMode.NONE:
                        break;
                    }
                }
                catch (ArgumentException)
                {
                    throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                }
            }
            if (aeadBlockCipher != null)
            {
                if (flag)
                {
                    throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers.");
                }
                if (flag2 && array.Length > 2 && array[2] != "")
                {
                    throw new SecurityUtilityException("Bad padding specified for AEAD cipher.");
                }
                return(new BufferedAeadBlockCipher(aeadBlockCipher));
            }
            if (blockCipher != null)
            {
                if (flag)
                {
                    return(new CtsBlockCipher(blockCipher));
                }
                if (blockCipherPadding != null)
                {
                    return(new PaddedBufferedBlockCipher(blockCipher, blockCipherPadding));
                }
                if (!flag2 || blockCipher.IsPartialBlockOkay)
                {
                    return(new BufferedBlockCipher(blockCipher));
                }
                return(new PaddedBufferedBlockCipher(blockCipher));
            }
            if (asymmetricBlockCipher != null)
            {
                return(new BufferedAsymmetricBlockCipher(asymmetricBlockCipher));
            }
            throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
        }
Пример #14
0
        public static IBufferedCipher GetCipher(
            string algorithm)
        {
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }

            algorithm = Platform.ToUpperInvariant(algorithm);

            {
                string aliased = (string)algorithms[algorithm];

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

            IBasicAgreement iesAgreement = null;

            if (algorithm == "IES")
            {
                iesAgreement = new DHBasicAgreement();
            }
            else if (algorithm == "ECIES")
            {
                iesAgreement = new ECDHBasicAgreement();
            }

            if (iesAgreement != null)
            {
                return(new BufferedIesCipher(
                           new IesEngine(
                               iesAgreement,
                               new Kdf2BytesGenerator(
                                   new Sha1Digest()),
                               new HMac(
                                   new Sha1Digest()))));
            }



            if (Platform.StartsWith(algorithm, "PBE"))
            {
                if (Platform.EndsWith(algorithm, "-CBC"))
                {
                    if (algorithm == "PBEWITHSHA1ANDDES-CBC")
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new DesEngine())));
                    }
                    else if (algorithm == "PBEWITHSHA1ANDRC2-CBC")
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new RC2Engine())));
                    }
                    else if (Strings.IsOneOf(algorithm,
                                             "PBEWITHSHAAND2-KEYTRIPLEDES-CBC", "PBEWITHSHAAND3-KEYTRIPLEDES-CBC"))
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new DesEdeEngine())));
                    }
                    else if (Strings.IsOneOf(algorithm,
                                             "PBEWITHSHAAND128BITRC2-CBC", "PBEWITHSHAAND40BITRC2-CBC"))
                    {
                        return(new PaddedBufferedBlockCipher(
                                   new CbcBlockCipher(new RC2Engine())));
                    }
                }
                else if (Platform.EndsWith(algorithm, "-BC") || Platform.EndsWith(algorithm, "-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())));
                    }
                }
            }



            string[] parts = algorithm.Split('/');

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

            string algorithmName = parts[0];

            {
                string aliased = (string)algorithms[algorithmName];

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

            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:
                blockCipher = new IdeaEngine();
                break;

            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.THREEFISH_256:
                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_256);
                break;

            case CipherAlgorithm.THREEFISH_512:
                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_512);
                break;

            case CipherAlgorithm.THREEFISH_1024:
                blockCipher = new ThreefishEngine(ThreefishEngine.BLOCKSIZE_1024);
                break;

            case CipherAlgorithm.TNEPRES:
                blockCipher = new TnepresEngine();
                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));
            }


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

            if (parts.Length > 2)
            {
                if (streamCipher != null)
                {
                    throw new ArgumentException("Paddings not used for stream ciphers");
                }

                string paddingName = parts[2];

                CipherPadding cipherPadding;
                if (paddingName == "")
                {
                    cipherPadding = CipherPadding.RAW;
                }
                else if (paddingName == "X9.23PADDING")
                {
                    cipherPadding = CipherPadding.X923PADDING;
                }
                else
                {
                    try
                    {
                        cipherPadding = (CipherPadding)Enums.GetEnumValue(typeof(CipherPadding), paddingName);
                    }
                    catch (ArgumentException)
                    {
                        throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
                    }
                }

                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.");
                }
            }

            string mode = "";

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

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

                try
                {
                    CipherMode 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:
                    {
                        int 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.OCB:
                        aeadBlockCipher = new OcbBlockCipher(blockCipher, CreateBlockCipher(cipherAlgorithm));
                        break;

                    case CipherMode.OFB:
                    {
                        int 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.");
        }
        /// <summary>
        /// Build the engine
        /// </summary>
        /// <param name="algorithm">SymmetricBlockAlgorithm enum, algorithm name</param>
        /// <returns>IBlockCipher with the algorithm Engine</returns>
        internal IBlockCipher getCipherEngine(SymmetricBlockAlgorithm algorithm)
        {
            IBlockCipher engine = null;

            switch (algorithm)
            {
            case SymmetricBlockAlgorithm.AES:
                engine = new AesEngine();
                break;

            case SymmetricBlockAlgorithm.BLOWFISH:
                engine = new BlowfishEngine();
                break;

            case SymmetricBlockAlgorithm.CAMELLIA:
                engine = new CamelliaEngine();
                break;

            case SymmetricBlockAlgorithm.CAST5:
                engine = new Cast5Engine();
                break;

            case SymmetricBlockAlgorithm.CAST6:
                engine = new Cast6Engine();
                break;

            case SymmetricBlockAlgorithm.DES:
                engine = new DesEngine();
                break;

            case SymmetricBlockAlgorithm.TRIPLEDES:
                engine = new DesEdeEngine();
                break;

            case SymmetricBlockAlgorithm.DSTU7624_128:
                engine = new Dstu7624Engine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.DSTU7624_128, this.error));
                break;

            case SymmetricBlockAlgorithm.DSTU7624_256:
                engine = new Dstu7624Engine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.DSTU7624_256, this.error));
                break;

            case SymmetricBlockAlgorithm.DSTU7624_512:
                engine = new Dstu7624Engine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.DSTU7624_512, this.error));
                break;

            case SymmetricBlockAlgorithm.GOST28147:
                engine = new Gost28147Engine();
                break;

            case SymmetricBlockAlgorithm.NOEKEON:
                engine = new NoekeonEngine();
                break;

            case SymmetricBlockAlgorithm.RC2:
                engine = new RC2Engine();
                break;

            case SymmetricBlockAlgorithm.RC532:
                engine = new RC532Engine();
                break;

            case SymmetricBlockAlgorithm.RC564:
                engine = new RC564Engine();
                break;

            case SymmetricBlockAlgorithm.RC6:
                engine = new RC6Engine();
                break;

            case SymmetricBlockAlgorithm.RIJNDAEL_128:
                engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_128, this.error));
                break;

            case SymmetricBlockAlgorithm.RIJNDAEL_160:
                engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_160, this.error));
                break;

            case SymmetricBlockAlgorithm.RIJNDAEL_192:
                engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_192, this.error));
                break;

            case SymmetricBlockAlgorithm.RIJNDAEL_224:
                engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_224, this.error));
                break;

            case SymmetricBlockAlgorithm.RIJNDAEL_256:
                engine = new RijndaelEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.RIJNDAEL_256, this.error));
                break;

            case SymmetricBlockAlgorithm.SEED:
                engine = new SeedEngine();
                break;

            case SymmetricBlockAlgorithm.SERPENT:
                engine = new SerpentEngine();
                break;

            case SymmetricBlockAlgorithm.SKIPJACK:
                engine = new SkipjackEngine();
                break;

            case SymmetricBlockAlgorithm.SM4:
                engine = new SM4Engine();
                break;

            case SymmetricBlockAlgorithm.TEA:
                engine = new TeaEngine();
                break;

            case SymmetricBlockAlgorithm.THREEFISH_256:
                engine = new ThreefishEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.THREEFISH_256, this.error));
                break;

            case SymmetricBlockAlgorithm.THREEFISH_512:
                engine = new ThreefishEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.THREEFISH_512, this.error));
                break;

            case SymmetricBlockAlgorithm.THREEFISH_1024:
                engine = new ThreefishEngine(SymmetricBlockAlgorithmUtils.getBlockSize(SymmetricBlockAlgorithm.THREEFISH_1024, this.error));
                break;

            case SymmetricBlockAlgorithm.TWOFISH:
                engine = new TwofishEngine();
                break;

            case SymmetricBlockAlgorithm.XTEA:
                engine = new XteaEngine();
                break;

            default:
                this.error.setError("SB020", "Cipher " + algorithm + " not recognised.");
                break;
            }
            return(engine);
        }
        public static IBufferedCipher GetCipher(
            string algorithm)
        {
            if (algorithm == null)
            {
                throw new ArgumentNullException("algorithm");
            }

            algorithm = algorithm.ToUpper(CultureInfo.InvariantCulture);

            string aliased = (string)algorithms[algorithm];

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



            IBasicAgreement iesAgreement = null;

            if (algorithm == "IES")
            {
                iesAgreement = new DHBasicAgreement();
            }
            else if (algorithm == "ECIES")
            {
                iesAgreement = new ECDHBasicAgreement();
            }

            if (iesAgreement != null)
            {
                return(new BufferedIesCipher(
                           new IesEngine(
                               iesAgreement,
                               new Kdf2BytesGenerator(
                                   new Sha1Digest()),
                               new HMac(
                                   new Sha1Digest()))));
            }



            if (algorithm.StartsWith("PBE"))
            {
                switch (algorithm)
                {
                case "PBEWITHSHAAND2-KEYTRIPLEDES-CBC":
                case "PBEWITHSHAAND3-KEYTRIPLEDES-CBC":
                    return(new PaddedBufferedBlockCipher(
                               new CbcBlockCipher(new DesEdeEngine())));

                case "PBEWITHSHAAND128BITRC2-CBC":
                case "PBEWITHSHAAND40BITRC2-CBC":
                    return(new PaddedBufferedBlockCipher(
                               new CbcBlockCipher(new RC2Engine())));

                case "PBEWITHSHAAND128BITAES-CBC-BC":
                case "PBEWITHSHAAND192BITAES-CBC-BC":
                case "PBEWITHSHAAND256BITAES-CBC-BC":
                case "PBEWITHSHA256AND128BITAES-CBC-BC":
                case "PBEWITHSHA256AND192BITAES-CBC-BC":
                case "PBEWITHSHA256AND256BITAES-CBC-BC":
                case "PBEWITHMD5AND128BITAES-CBC-OPENSSL":
                case "PBEWITHMD5AND192BITAES-CBC-OPENSSL":
                case "PBEWITHMD5AND256BITAES-CBC-OPENSSL":
                    return(new PaddedBufferedBlockCipher(
                               new CbcBlockCipher(new AesFastEngine())));

                case "PBEWITHSHA1ANDDES-CBC":
                    return(new PaddedBufferedBlockCipher(
                               new CbcBlockCipher(new DesEngine())));

                case "PBEWITHSHA1ANDRC2-CBC":
                    return(new PaddedBufferedBlockCipher(
                               new CbcBlockCipher(new RC2Engine())));
                }
            }



            string[] parts = algorithm.Split('/');

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

            switch (parts[0])
            {
            case "AES":
                blockCipher = new AesFastEngine();
                break;

            case "ARC4":
                streamCipher = new RC4Engine();
                break;

            case "BLOWFISH":
                blockCipher = new BlowfishEngine();
                break;

            case "CAMELLIA":
                blockCipher = new CamelliaEngine();
                break;

            case "CAST5":
                blockCipher = new Cast5Engine();
                break;

            case "CAST6":
                blockCipher = new Cast6Engine();
                break;

            case "DES":
                blockCipher = new DesEngine();
                break;

            case "DESEDE":
                blockCipher = new DesEdeEngine();
                break;

            case "ELGAMAL":
                asymBlockCipher = new ElGamalEngine();
                break;

            case "GOST28147":
                blockCipher = new Gost28147Engine();
                break;

            case "HC128":
                streamCipher = new HC128Engine();
                break;

            case "HC256":
                streamCipher = new HC256Engine();
                break;

#if INCLUDE_IDEA
            case "IDEA":
                blockCipher = new IdeaEngine();
                break;
#endif
            case "NOEKEON":
                blockCipher = new NoekeonEngine();
                break;

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

            case "RC2":
                blockCipher = new RC2Engine();
                break;

            case "RC5":
                blockCipher = new RC532Engine();
                break;

            case "RC5-64":
                blockCipher = new RC564Engine();
                break;

            case "RC6":
                blockCipher = new RC6Engine();
                break;

            case "RIJNDAEL":
                blockCipher = new RijndaelEngine();
                break;

            case "RSA":
                asymBlockCipher = new RsaBlindedEngine();
                break;

            case "SALSA20":
                streamCipher = new Salsa20Engine();
                break;

            case "SEED":
                blockCipher = new SeedEngine();
                break;

            case "SERPENT":
                blockCipher = new SerpentEngine();
                break;

            case "SKIPJACK":
                blockCipher = new SkipjackEngine();
                break;

            case "TEA":
                blockCipher = new TeaEngine();
                break;

            case "TWOFISH":
                blockCipher = new TwofishEngine();
                break;

            case "VMPC":
                streamCipher = new VmpcEngine();
                break;

            case "VMPC-KSA3":
                streamCipher = new VmpcKsa3Engine();
                break;

            case "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));
            }


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

            if (parts.Length > 2)
            {
                if (streamCipher != null)
                {
                    throw new ArgumentException("Paddings not used for stream ciphers");
                }

                switch (parts[2])
                {
                case "NOPADDING":
                    padded = false;
                    break;

                case "":
                case "RAW":
                    break;

                case "ISO10126PADDING":
                case "ISO10126D2PADDING":
                case "ISO10126-2PADDING":
                    padding = new ISO10126d2Padding();
                    break;

                case "ISO7816-4PADDING":
                case "ISO9797-1PADDING":
                    padding = new ISO7816d4Padding();
                    break;

                case "ISO9796-1":
                case "ISO9796-1PADDING":
                    asymBlockCipher = new ISO9796d1Encoding(asymBlockCipher);
                    break;

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

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

                case "OAEPWITHSHA1ANDMGF1PADDING":
                case "OAEPWITHSHA-1ANDMGF1PADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha1Digest());
                    break;

                case "OAEPWITHSHA224ANDMGF1PADDING":
                case "OAEPWITHSHA-224ANDMGF1PADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha224Digest());
                    break;

                case "OAEPWITHSHA256ANDMGF1PADDING":
                case "OAEPWITHSHA-256ANDMGF1PADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha256Digest());
                    break;

                case "OAEPWITHSHA384ANDMGF1PADDING":
                case "OAEPWITHSHA-384ANDMGF1PADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha384Digest());
                    break;

                case "OAEPWITHSHA512ANDMGF1PADDING":
                case "OAEPWITHSHA-512ANDMGF1PADDING":
                    asymBlockCipher = new OaepEncoding(asymBlockCipher, new Sha512Digest());
                    break;

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

                case "PKCS5":
                case "PKCS5PADDING":
                case "PKCS7":
                case "PKCS7PADDING":
                    // NB: Padding defaults to Pkcs7Padding already
                    break;

                case "TBCPADDING":
                    padding = new TbcPadding();
                    break;

                case "WITHCTS":
                    cts = true;
                    break;

                case "X9.23PADDING":
                case "X923PADDING":
                    padding = new X923Padding();
                    break;

                case "ZEROBYTEPADDING":
                    padding = new ZeroBytePadding();
                    break;

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

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

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

                switch (modeName)
                {
                case "":
                case "ECB":
                case "NONE":
                    break;

                case "CBC":
                    blockCipher = new CbcBlockCipher(blockCipher);
                    break;

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

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

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

                case "CTR":
                    blockCipher = new SicBlockCipher(blockCipher);
                    break;

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

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

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

                case "GOFB":
                    blockCipher = new GOfbBlockCipher(blockCipher);
                    break;

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

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

                case "OPENPGPCFB":
                    blockCipher = new OpenPgpCfbBlockCipher(blockCipher);
                    break;

                case "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.");
                }
            }

            if (aeadBlockCipher != null)
            {
                if (cts)
                {
                    throw new SecurityUtilityException("CTS mode not valid for AEAD ciphers.");
                }
                if (padded && parts.Length > 1 && 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 (!padded || blockCipher.IsPartialBlockOkay)
                {
                    return(new BufferedBlockCipher(blockCipher));
                }

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

                return(new PaddedBufferedBlockCipher(blockCipher));
            }

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

            throw new SecurityUtilityException("Cipher " + algorithm + " not recognised.");
        }
Пример #17
0
        public override void PerformTest()
        {
            base.PerformTest();

            //advanced tests with Gost28147KeyGenerator:
            //encrypt on hesh message; ECB mode:
            byte[] inBytes  = Hex.Decode("4e6f77206973207468652074696d6520666f7220616c6c20");
            byte[] output   = Hex.Decode("8ad3c8f56b27ff1fbd46409359bdc796bc350e71aac5f5c0");
            byte[] outBytes = new byte[inBytes.Length];

            byte[] key = generateKey(Hex.Decode("0123456789abcdef"));              //!!! heshing start_key - get 256 bits !!!
            //        System.out.println(new string(Hex.Encode(key)));
            ICipherParameters param = new ParametersWithSBox(new KeyParameter(key), Gost28147Engine.GetSBox("E-A"));
            //CipherParameters  param = new Gost28147Parameters(key,"D-Test");
            BufferedBlockCipher cipher = new BufferedBlockCipher(new Gost28147Engine());

            cipher.Init(true, param);
            int len1 = cipher.ProcessBytes(inBytes, 0, inBytes.Length, outBytes, 0);

            try
            {
                cipher.DoFinal(outBytes, len1);
            }
            catch (CryptoException e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }

            if (outBytes.Length != output.Length)
            {
                Fail("failed - "
                     + "expected " + Hex.ToHexString(output) + " got "
                     + Hex.ToHexString(outBytes));
            }

            for (int i = 0; i != outBytes.Length; i++)
            {
                if (outBytes[i] != output[i])
                {
                    Fail("failed - "
                         + "expected " + Hex.ToHexString(output)
                         + " got " + Hex.ToHexString(outBytes));
                }
            }


            //encrypt on hesh message; CFB mode:
            inBytes  = Hex.Decode("bc350e71aac5f5c2");
            output   = Hex.Decode("0ebbbafcf38f14a5");
            outBytes = new byte[inBytes.Length];

            key   = generateKey(Hex.Decode("0123456789abcdef"));            //!!! heshing start_key - get 256 bits !!!
            param = new ParametersWithIV(
                new ParametersWithSBox(
                    new KeyParameter(key),                     //key
                    Gost28147Engine.GetSBox("E-A")),           //type S-box
                Hex.Decode("1234567890abcdef"));               //IV

            cipher = new BufferedBlockCipher(new CfbBlockCipher(new Gost28147Engine(), 64));

            cipher.Init(true, param);
            len1 = cipher.ProcessBytes(inBytes, 0, inBytes.Length, outBytes, 0);
            try
            {
                cipher.DoFinal(outBytes, len1);
            }
            catch (CryptoException e)
            {
                Fail("failed - exception " + e.ToString(), e);
            }
            if (outBytes.Length != output.Length)
            {
                Fail("failed - "
                     + "expected " + Hex.ToHexString(output)
                     + " got " + Hex.ToHexString(outBytes));
            }
            for (int i = 0; i != outBytes.Length; i++)
            {
                if (outBytes[i] != output[i])
                {
                    Fail("failed - "
                         + "expected " + Hex.ToHexString(output)
                         + " got " + Hex.ToHexString(outBytes));
                }
            }


            //encrypt on hesh message; CFB mode:
            inBytes  = Hex.Decode("000102030405060708090a0b0c0d0e0fff0102030405060708090a0b0c0d0e0f");
            output   = Hex.Decode("64988982819f0a1655e226e19ecad79d10cc73bac95c5d7da034786c12294225");
            outBytes = new byte[inBytes.Length];

            key   = generateKey(Hex.Decode("aafd12f659cae63489b479e5076ddec2f06cb58faafd12f659cae63489b479e5"));            //!!! heshing start_key - get 256 bits !!!
            param = new ParametersWithIV(
                new ParametersWithSBox(
                    new KeyParameter(key),                     //key
                    Gost28147Engine.GetSBox("E-A")),           //type S-box
                Hex.Decode("aafd12f659cae634"));               //IV

            cipher = new BufferedBlockCipher(new CfbBlockCipher(new Gost28147Engine(), 64));

            cipher.Init(true, param);
            len1 = cipher.ProcessBytes(inBytes, 0, inBytes.Length, outBytes, 0);

            cipher.DoFinal(outBytes, len1);

            if (outBytes.Length != output.Length)
            {
                Fail("failed - "
                     + "expected " + Hex.ToHexString(output)
                     + " got " + Hex.ToHexString(outBytes));
            }

            for (int i = 0; i != outBytes.Length; i++)
            {
                if (outBytes[i] != output[i])
                {
                    Fail("failed - "
                         + "expected " + Hex.ToHexString(output)
                         + " got " + Hex.ToHexString(outBytes));
                }
            }

            //encrypt on hesh message; OFB mode:
            inBytes  = Hex.Decode("bc350e71aa11345709acde");
            output   = Hex.Decode("1bcc2282707c676fb656dc");
            outBytes = new byte[inBytes.Length];

            key   = generateKey(Hex.Decode("0123456789abcdef"));            //!!! heshing start_key - get 256 bits !!!
            param = new ParametersWithIV(
                new ParametersWithSBox(
                    new KeyParameter(key),                     //key
                    Gost28147Engine.GetSBox("E-A")),           //type S-box
                Hex.Decode("1234567890abcdef"));               //IV

            cipher = new BufferedBlockCipher(new GOfbBlockCipher(new Gost28147Engine()));

            cipher.Init(true, param);
            len1 = cipher.ProcessBytes(inBytes, 0, inBytes.Length, outBytes, 0);

            cipher.DoFinal(outBytes, len1);

            if (outBytes.Length != output.Length)
            {
                Fail("failed - "
                     + "expected " + Hex.ToHexString(output)
                     + " got " + Hex.ToHexString(outBytes));
            }

            for (int i = 0; i != outBytes.Length; i++)
            {
                if (outBytes[i] != output[i])
                {
                    Fail("failed - "
                         + "expected " + Hex.ToHexString(output)
                         + " got " + Hex.ToHexString(outBytes));
                }
            }
        }
Пример #18
0
        //After doing a lot of comparisons, the MS hash algorithms are MUCH faster on large files compared to
        //BouncyCastle (around 10x). MS does not seem to support the number of algorithms that BC does, so the MS functions
        //are used whenever possible. Otherwise, BC is used.
        //Hashes tested against https://www.functions-online.com/hash.html

        public void computeHash(CheckBox cb, TextBox tb, string alg)
        {
            if (cb.Checked)
            {
                if (tb.Text == "" && tbPath.Text != "" || tbText.Text != "")
                {
                    colorTextBox(tb, true);
                    switch (alg)
                    {
                    case "md5":
                        if (tbText.Text != "")
                        {
                            tb.Text = getTextHashMS(tbText.Text, new MD5CryptoServiceProvider());
                        }
                        else
                        {
                            try {
                                tb.Text = getFileHashMS(tbPath.Text, new MD5CryptoServiceProvider());
                            }
                            catch (Exception e) {
                                tb.Text = e.Message;
                            }
                        }
                        tb.Refresh();
                        break;

                    case "sha1":
                        if (tbText.Text != "")
                        {
                            tb.Text = getTextHashMS(tbText.Text, new SHA1CryptoServiceProvider());
                        }
                        else
                        {
                            try {
                                tb.Text = getFileHashMS(tbPath.Text, new SHA1CryptoServiceProvider());
                            }
                            catch (Exception e) {
                                tb.Text = e.Message;
                            }
                        }
                        tb.Refresh();
                        break;

                    case "sha256":
                        if (tbText.Text != "")
                        {
                            tb.Text = getTextHashMS(tbText.Text, new SHA256CryptoServiceProvider());
                        }
                        else
                        {
                            try {
                                tb.Text = getFileHashMS(tbPath.Text, new SHA256CryptoServiceProvider());
                            }
                            catch (Exception e) {
                                tb.Text = e.Message;
                            }
                        }
                        tb.Refresh();
                        break;

                    case "sha512":
                        if (tbText.Text != "")
                        {
                            tb.Text = getTextHashMS(tbText.Text, new SHA512CryptoServiceProvider());
                        }
                        else
                        {
                            try {
                                tb.Text = getFileHashMS(tbPath.Text, new SHA512CryptoServiceProvider());
                            }
                            catch (Exception e) {
                                tb.Text = e.Message;
                            }
                        }
                        tb.Refresh();
                        break;

                    case "gost":
                        if (tbText.Text != "")
                        {
                            tb.Text = getTextHashBC(tbText.Text, new Gost3411Digest(Gost28147Engine.GetSBox("Default")));
                        }
                        else
                        {
                            try {
                                tb.Text = getFileHashBC(tbPath.Text, new Gost3411Digest(Gost28147Engine.GetSBox("Default")));
                            }
                            catch (Exception e) {
                                tb.Text = e.Message;
                            }
                        }
                        tb.Refresh();
                        break;

                    case "ripemd128":
                        if (tbText.Text != "")
                        {
                            tb.Text = getTextHashBC(tbText.Text, new RipeMD128Digest());
                        }
                        else
                        {
                            try {
                                tb.Text = getFileHashBC(tbPath.Text, new RipeMD128Digest());
                            }
                            catch (Exception e) {
                                tb.Text = e.Message;
                            }
                        }
                        tb.Refresh();
                        break;

                    case "ripemd160":
                        if (tbText.Text != "")
                        {
                            tb.Text = getTextHashBC(tbText.Text, new RipeMD160Digest());
                        }
                        else
                        {
                            try {
                                tb.Text = getFileHashBC(tbPath.Text, new RipeMD160Digest());
                            }
                            catch (Exception e) {
                                tb.Text = e.Message;
                            }
                        }
                        tb.Refresh();
                        break;

                    case "ripemd256":
                        if (tbText.Text != "")
                        {
                            tb.Text = getTextHashBC(tbText.Text, new RipeMD256Digest());
                        }
                        else
                        {
                            try {
                                tb.Text = getFileHashBC(tbPath.Text, new RipeMD256Digest());
                            }
                            catch (Exception e) {
                                tb.Text = e.Message;
                            }
                        }
                        tb.Refresh();
                        break;

                    case "ripemd320":
                        if (tbText.Text != "")
                        {
                            tb.Text = getTextHashBC(tbText.Text, new RipeMD320Digest());
                        }
                        else
                        {
                            try {
                                tb.Text = getFileHashBC(tbPath.Text, new RipeMD320Digest());
                            }
                            catch (Exception e) {
                                tb.Text = e.Message;
                            }
                        }
                        tb.Refresh();
                        break;

                    case "tiger":
                        if (tbText.Text != "")
                        {
                            tb.Text = getTextHashBC(tbText.Text, new TigerDigest());
                        }
                        else
                        {
                            try {
                                tb.Text = getFileHashBC(tbPath.Text, new TigerDigest());
                            }
                            catch (Exception e) {
                                tb.Text = e.Message;
                            }
                        }
                        tb.Refresh();
                        break;

                    case "whirlpool":
                        if (tbText.Text != "")
                        {
                            tb.Text = getTextHashBC(tbText.Text, new WhirlpoolDigest());
                        }
                        else
                        {
                            try {
                                tb.Text = getFileHashBC(tbPath.Text, new WhirlpoolDigest());
                            }
                            catch (Exception e) {
                                tb.Text = e.Message;
                            }
                        }
                        tb.Refresh();
                        break;
                    } // END OF SWITCH

                    Application.DoEvents();
                }
            }
            else
            {
                tb.Text = "";
            }
            colorTextBox(tb);
        }