private void DHTest(BigInteger clientPrivateKey, BigInteger clientPublicKey, BigInteger serverPrivateKey, BigInteger serverPublicKey)
        {
            StackFrame[] frames          = new StackTrace().GetFrames();
            BigInteger   serverSecretKey = DiffieHellman.GenerateSecretKey(clientPublicKey, serverPrivateKey);
            BigInteger   clientSecretKey = serverPublicKey.ModPow(clientPrivateKey, OakleyGroup1.PrimeNumber);

            byte[] serverSecretkeyMD5 = Hash.MD5.Hash(serverSecretKey);
            byte[] clientSecretkeyMD5 = Hash.MD5.Hash(clientSecretKey);

            Assert.AreEqual(clientSecretKey, serverSecretKey);
            CollectionAssert.AreEqual(Hash.SHA256.Hash(clientSecretKey), Hash.SHA256.Hash(serverSecretKey));
            CollectionAssert.AreEqual(Hash.MD5.Hash(clientSecretKey), Hash.MD5.Hash(serverSecretKey));

            Console.WriteLine("============================================");
            Console.WriteLine(string.Format("[{0}]", frames[1].GetMethod().Name));
            Console.WriteLine("ClientPrivateKey : " + TestUtil.ToString(clientPrivateKey));
            Console.WriteLine("ClientPublicKey : " + TestUtil.ToString(clientPublicKey));
            Console.WriteLine("ServerPrivateKey : " + TestUtil.ToString(serverPrivateKey));
            Console.WriteLine("ServerPublicKey : " + TestUtil.ToString(serverPublicKey));
            Console.WriteLine("ServerSecretKey : " + TestUtil.ToString(serverSecretKey));
            Console.WriteLine("ClientSecretKey : " + TestUtil.ToString(clientSecretKey));
            Console.WriteLine("============================================");
            Console.WriteLine("ServerSecretKey(MD5) : " + TestUtil.ToString(serverSecretkeyMD5));
            Console.WriteLine("ClientSecretKey(MD5) : " + TestUtil.ToString(clientSecretkeyMD5));
            Console.WriteLine("============================================");
        }
예제 #2
0
        private ECPoint GetSharedKey(byte[] privateKey, ECPoint publicKey)
        {
            var dh        = new DiffieHellman(this.ellipticCurve);
            var sharedKey = dh.GetSharedKey(privateKey, publicKey);

            return(sharedKey);
        }
예제 #3
0
        private (byte[] privateKey, ECPoint publicKey) GenerateKeys()
        {
            var dh   = new DiffieHellman(this.ellipticCurve);
            var keys = dh.GenerateByteKeyPair();

            return(keys);
        }
        private DiffieHellman GenerateDiffieHellman()
        {
            DiffieHellman diffie = new DiffieHellman(256);

            diffie.GenerateRequest();
            return(diffie);
        }
 private void GenerateThread()
 {
     try
     {
         while (PrivateKeys.Count < Max_Private_Keys || DiffieHellmans.Count < Max_Private_Keys)
         {
             if (PrivateKeys.Count < Max_Private_Keys)
             {
                 RSAEncryption RSA = GenerateRsaKey();
                 lock (PrivateKeys)
                 {
                     PrivateKeys.Add(RSA);
                 }
             }
             if (DiffieHellmans.Count < Max_Private_Keys)
             {
                 DiffieHellman diffie = GenerateDiffieHellman();
                 lock (DiffieHellmans)
                 {
                     DiffieHellmans.Add(diffie);
                 }
             }
         }
     }
     catch
     {
     }
     GenThread = null;
 }
예제 #6
0
파일: Program.cs 프로젝트: jc4st3lls/DH
        private static void CreateEncryptFileFor(string aliasName, string fileName, string pubFileName, bool isBinary)
        {
            DHKeyPair _aliaskeys   = RestoreKeys(aliasName);
            PublicKey _publickeyto = RestorePublicKey(pubFileName);

            IDiffieHellman _dh      = new DiffieHellman();
            DHDerivedKey   _derived = _dh.GenerateDerivedKey(_aliaskeys, _publickeyto);

            Console.WriteLine($"Derived Key:\n {BitConverter.ToString(_derived.Value)}");
            byte[]  IV     = System.Text.Encoding.UTF8.GetBytes(fileName);
            ICypher cypher = new AesCypher(_derived.Value, IV);

            byte[] encrypted;
            if (isBinary)
            {
                var content = ReadBinFile(fileName);
                encrypted = cypher.Encrypt(Convert.ToBase64String(content));
            }
            else
            {
                encrypted = cypher.Encrypt(ReadTextFile(fileName));
            }


            WriteBinFile($"{fileName}{extfile}", encrypted);

            Console.WriteLine($"{fileName}{extfile} encrypt file created.");
        }
        public DiffieHellman GetDiffieHellman()
        {
            if (!GenerateInBackground)
            {
                return(GenerateDiffieHellman());
            }

            if (DiffieHellmans.Count == 0)
            {
                if (GenThread == null)
                {
                    GenThread = new Thread(new ThreadStart(GenerateThread));
                    GenThread.Start();
                }
                return(GenerateDiffieHellman());
            }
            else
            {
                lock (DiffieHellmans)
                {
                    //get a random key
                    int           index  = rnd.Next(0, DiffieHellmans.Count - 1);
                    DiffieHellman diffie = DiffieHellmans[index];
                    DiffieHellmans.RemoveAt(index);

                    if (DiffieHellmans.Count < Min_Private_Keys && GenThread == null)
                    {
                        GenThread = new Thread(new ThreadStart(GenerateThread));
                        GenThread.Start();
                    }
                    return(diffie);
                }
            }
        }
예제 #8
0
        public void Test_against_well_known_results()
        {
            var primeP = BigInteger.Parse(
                "32317006071311007300338913926423828248817941241140239112842009751400741706634354222619689417363569347117901737909704191754605873209195028853758986185622153212175412514901774520270235796078236248884246189477587641105928646099411723245426622522193230540919037680524235519125679715870117001058055877651038861847280257976054903569732561526167081339361799541336476559160368317896729073178384589680639671900977202194168647225871031411336429319536193471636533209717077448227988588565369208645296636077250268955505928362751121174096972998068410554359584866583291642136218231078990999448652468262416972035911852507045361090559");
            var primeG = 2;

            // Well known inputs
            var publicKeyA = BigInteger.Parse(
                "16428453901689311174406835429457614352149131480820814606112641749162650046154160335721379864411385528632019438902509157814200706062493374586063287172414190665332638992378261617325351180882041320307470593551646072474377878641984257780799839924855832129077529540835293783943730689922011709290843103151179985344516127747230985665149485674718135070425535512704941196438784396460314598697418809403784160603971605277453951697026605904451672993162168584425019633974228954913888533522579571876177351844336213083376100007173872157215792163324914952633720486776246713336194027578118386085155631307325675034868183575746215669017");
            var privateKeyB = BigInteger.Parse(
                "6613069657665132725246464674416626967814847789270511732153920138404502558419161452231064033783065518081120087482262648699449248725844190853405394370415215555753121974020933054263318571431735489635061130413831465735285677393247377148888841381226497879709898084741908757014541741029147966946395707074610452892001890884190368089685289931823630320756921252041961571241320436492694638582502471480887058785121023850135911685185196576270777539716337738304019266982029836194150504415828024197423759537800908924209753175640206646764556125280475452980539359806836287847410461780237281850073248139315083092664821627343007413317");

            // Calculate Public Key
            var publicKeyB = DiffieHellman.PublicKey(primeP, primeG, privateKeyB);

            // Should result in the following well known number
            Assert.Equal(publicKeyB,
                         BigInteger.Parse(
                             "13937492206031047726377677746757921023785865161711475317174852743458085972205230299198350504612922098487548140816754440307076166055257752333977500237623761651798309657163956423196446289209492990021148645911047877880418288215506315988031313308757685574136931332211416208698474521512055282419261914878127800815451795657625776361486208624055307330917667568520525506193865130553366132859605894136270581379193553757875072525875034653743007926569724507481311440697029586510437642238099656004667926545975053817946452156676950868454136633495486741131821585053777971482962860700849249057853674609970118970647438173499487768514"));

            // Calculate Secret
            var secretB = DiffieHellman.Secret(primeP, publicKeyA, privateKeyB);

            // Should Result in the following well known secret.
            Assert.Equal(secretB,
                         BigInteger.Parse(
                             "17574532284595554228770542578145458081719781058045063175688772743423924399411406200223997425795977226735712284391179978852253613346926080761628802664085045531796220784085311215093471160914442692274980632286568900367895454304533334450617380428362254473222831478193415222881689923861172428575632214297967550826460508634891791127942687630353829719246724903147169063379750256523005309264102997944008112551383251560153285483075803832550164760264165682355751637761390244202226339540318827287797180863284173748514677579269180126947721499144727772986832223499738071139796968492815538042908414723947769999062186130240163854083"));
        }
예제 #9
0
파일: Program.cs 프로젝트: jc4st3lls/DH
        private static void RestoreEncryptFileFrom(string aliasName, string fileName, string pubFileName, bool isBinary)
        {
            DHKeyPair _aliaskeys   = RestoreKeys(aliasName);
            PublicKey _publickeyto = RestorePublicKey(pubFileName);

            IDiffieHellman _dh      = new DiffieHellman();
            DHDerivedKey   _derived = _dh.GenerateDerivedKey(_aliaskeys, _publickeyto);

            Console.WriteLine($"Derived Key:\n {BitConverter.ToString(_derived.Value)}");

            string fileout = fileName.Replace(extfile, string.Empty);

            byte[]  IV     = System.Text.Encoding.UTF8.GetBytes(fileout);
            ICypher cypher = new AesCypher(_derived.Value, IV);

            byte[] read = ReadBinFile(fileName);

            string content = cypher.Decrypt(read);

            if (isBinary)
            {
                var bcontent = Convert.FromBase64String(content);
                WriteBinFile(fileout, bcontent);
            }
            else
            {
                WriteTextFile(fileout, content);
            }


            Console.WriteLine($"{fileout} decrypt file created.");
        }
        public static void Cifrado(string path, string root, int tamaño, int p, int q)
        {
            string rootPrivate;
            string keyPrivate;

            rootPrivate = root + @"\\Upload\\Asymmetric\\KeyPrivates.txt";
            string directorio;

            directorio = root + @"\\Upload\\";
            if (!Directory.Exists(directorio + "\\Asymmetric\\"))
            {
                DirectoryInfo di = Directory.CreateDirectory(directorio + "\\Asymmetric\\");
            }
            DiffieHellman dh    = new DiffieHellman(p, tamaño);
            RSA           rsa   = new RSA(p, q);
            string        texto = System.IO.File.ReadAllText(@path);

            rsa.ObtenerFI();
            rsa.ObtenerE();

            string txtcifrado = "Cipher: RSA" + Environment.NewLine + "Clave pública: " + "( " + rsa.ObtenerN().ToString() + " , " + rsa.ObtenerD().ToString() + " )"
                                + Environment.NewLine + " " + Environment.NewLine + "Cipher: Diffie-Hellman" + Environment.NewLine + "Clave pública: " +
                                " ( " + dh.SetAlice() + " )";

            keyPrivate = "Clave privada: " + "( " + rsa.ObtenerN().ToString() + " , " + rsa.ObtenerE().ToString() + " )";
            File.WriteAllText(@rootPrivate, keyPrivate);
            root = root + @"\\Upload\\Asymmetric\\KeyPublics.txt";
            using (StreamWriter outputFile = new StreamWriter(root))
            {
                foreach (char caracter in txtcifrado)
                {
                    outputFile.Write(caracter.ToString());
                }
            }
        }
예제 #11
0
    public void Private_key_randomly_generated()
    {
        var primeP      = new BigInteger(7919);
        var privateKeys = Enumerable.Range(0, 5).Select(_ => DiffieHellman.PrivateKey(primeP)).ToList();

        Assert.Equal(privateKeys.Distinct().Count(), privateKeys.Count);
    }
예제 #12
0
    public void Private_key_in_range()
    {
        var primeP      = new BigInteger(23);
        var privateKeys = Enumerable.Range(0, 10).Select(_ => DiffieHellman.PrivateKey(primeP)).ToList();

        Assert.That(privateKeys, Is.All.InRange(new BigInteger(1), primeP - new BigInteger(1)));
    }
예제 #13
0
        public void CreateNewSessionKey()
        {
            if (FinishedKeyExchange == false)
            {
                // The logic elsewhere is to call this method unless RemoteHasKey == true.
                // That needs to be cleaned up, because this is pointless.
                if (SentKeyExchange)
                {
                    //LogManager.Current.WriteToLog("CreateNewSessionKey() AGAIN for " + this.ToString() + "\n" + Environment.StackTrace);
                    return;
                }

                try {
                    LoggingService.LogInfo("Creating secure communication channel to {0}...", ToString());

                    SentKeyExchange = true;

                    var keyExchange = DiffieHellman.CreateKeyExchange();
                    var m           = Network.MessageBuilder.CreateNewSessionKeyMessage(this, keyExchange);
                    var c           = new AckMethod();
                    c.args    = new object[] { this };
                    c.Method += Network.NewSessionKeyReady;
                    Network.AckMethods.Add(m.MessageID, c);
                    Network.SendRoutedMessage(m);
                } catch (Exception ex) {
                    LoggingService.LogError("Failed to create key exchange! Hopefully we will retry...");
                    SentKeyExchange = false;
                    throw ex;
                }
            }
            else
            {
                LoggingService.LogWarning("Why are we trying to CreateNewSessionKey for {0} when FinishedKeyExchange=True?", ToString());
            }
        }
예제 #14
0
        private void OnDataReceived(object sender, DataReceivedEventArgs e)
        {
            Deserializer deserializer = new Deserializer(e.Buffer);

            while (!deserializer.EndOfStream)
            {
                byte header = deserializer.ReadByte();
                byte length = deserializer.ReadByte();

                switch (length)
                {
                case 0x42:
                    byte[] publicKey         = deserializer.ReadBytes(64);
                    byte[] sharedKey         = DiffieHellman.GenerateSharedKey(publicKey, Keys.PrivateKey, Keys.Prime);
                    byte[] randomBytes       = CryptoUtils.GetRandomBytes();
                    byte[] hashedRandomBytes = CryptoUtils.Hash(randomBytes);
                    byte[] xoredRandomBytes  = CryptoUtils.XOR(randomBytes, sharedKey);
                    this.EncryptionKey = hashedRandomBytes;
                    this.SendKey(xoredRandomBytes);
                    this.client.DataReceived -= OnDataReceived;
                    this.OnHandshakeDone();
                    break;

                default:
                    if (!this.HandlePacket(header, length, deserializer))
                    {
                        logger.Error("Unknown unencrypted packet, header: 0x{0:X2}, length: 0x{1:X2}", header, length);
                        this.client.Disconnect();
                        return;
                    }
                    break;
                }
            }
        }
예제 #15
0
    public void Private_key_is_random()
    {
        var p           = new BigInteger(7919);
        var privateKeys = Enumerable.Range(0, 10).Select(_ => DiffieHellman.PrivateKey(p)).ToArray();

        Assert.Equal(privateKeys.Distinct().Count(), privateKeys.Length);
    }
        public AssociateResponse(OpenIdRelyingParty relyingParty, ServiceEndpoint provider, IDictionary <string, string> args, DiffieHellman dh)
            : base(relyingParty, provider, args)
        {
            DH = dh;

            if (Args.ContainsKey(Protocol.openidnp.assoc_handle))
            {
                initializeAssociation();
            }
            else
            {
                // Attempt to recover from an unsupported assoc_type
                if (Protocol.Version.Major >= 2)
                {
                    if (Util.GetRequiredArg(Args, Protocol.openidnp.error_code) == Protocol.Args.ErrorCode.UnsupportedType)
                    {
                        string assoc_type   = Util.GetRequiredArg(Args, Protocol.openidnp.assoc_type);
                        string session_type = Util.GetRequiredArg(Args, Protocol.openidnp.session_type);
                        // If the suggested options are among those we support...
                        if (Array.IndexOf(Protocol.Args.SignatureAlgorithm.All, assoc_type) >= 0 &&
                            Array.IndexOf(Protocol.Args.SessionType.All, session_type) >= 0 &&
                            RelyingParty.Settings.IsAssociationInPermittedRange(Protocol, assoc_type))
                        {
                            SecondAttempt = AssociateRequest.Create(RelyingParty, Provider, assoc_type, session_type, false);
                        }
                    }
                }
            }
        }
예제 #17
0
        public string RecuperarMensajesSala(string guidResponse, string username)
        {
            try
            {
                DbConnection connection      = new DbConnection();
                List <Sala>  salasDeUsuarios = connection.BuscarVarios <Sala>("salas", Builders <Sala> .Filter.Eq("guid", guidResponse));
                var          filtro          = Builders <Usuario> .Filter.Eq("user", username);

                var  usuarioActual = connection.BuscarUno <Usuario>("users", filtro);
                Sala salaActual    = new Sala();
                foreach (var item in salasDeUsuarios)
                {
                    if (item.UsuarioA == usuarioActual.User)
                    {
                        salaActual = item;
                        break;
                    }
                }

                //Generar key DH para generar 10bitsSDES
                DiffieHellman PersonaA = new DiffieHellman(usuarioActual.NumeroPrivado)
                {
                    PublicoExterno = salaActual.ValorPublicoB
                };

                string cadenaLlaveSdes = Convert.ToString(PersonaA.GenerarKey(), 2).PadLeft(10, '0');
                Sdes   cipher          = new Sdes(cadenaLlaveSdes);

                List <Mensaje> mensajesEncriptados = connection.BuscarVarios <Mensaje>("mensajes",
                                                                                       Builders <Mensaje> .Filter.Eq("salaGuid", guidResponse));

                List <Mensaje> mensajesDesEncriptados = new List <Mensaje>();
                //Des encriptar los mensajes
                foreach (var item in mensajesEncriptados)
                {
                    string desEnc = "";
                    foreach (var caracter in item.Contenido)
                    {
                        byte letra = Convert.ToByte(caracter);
                        desEnc += Convert.ToChar(cipher.SDES_DeCipher(letra));
                    }
                    Mensaje mensajeDes = new Mensaje(guidResponse)
                    {
                        Contenido       = desEnc,
                        Guid            = item.Guid,
                        UsuarioEmisor   = item.UsuarioEmisor,
                        UsuarioReceptor = item.UsuarioReceptor
                    };
                    mensajesDesEncriptados.Add(mensajeDes);
                }

                var json = JsonConvert.SerializeObject(mensajesDesEncriptados);
                return(json);
            }
            catch
            {
                return("");
            }
        }
예제 #18
0
        public void Private_key_in_range()
        {
            var primeP      = new BigInteger(23);
            var privateKeys = Enumerable.Range(0, 100).Select(_ => DiffieHellman.RandomPrivateKey(primeP)).ToList();

            Assert.All(privateKeys,
                       privateKey => { Assert.InRange(privateKey, new BigInteger(2), primeP - new BigInteger(1)); });
        }
예제 #19
0
    public void Can_calculate_public_key_using_private_key()
    {
        var p          = new BigInteger(23);
        var g          = new BigInteger(5);
        var privateKey = new BigInteger(6);

        Assert.Equal(new BigInteger(8), DiffieHellman.PublicKey(p, g, privateKey));
    }
예제 #20
0
        public void DeffieHelmanNewTest()
        {
            DiffieHellman algorithm = new DiffieHellman();
            List <int>    key       = algorithm.GetKeys(541, 10, 50, 100);

            Assert.AreEqual(key[0], 449);
            Assert.AreEqual(key[1], 449);
        }
예제 #21
0
 public ChatClient()
 {
     diffieHellman   = new DiffieHellman();
     commonSecret    = new Dictionary <Guid, byte[]>();
     sendQueue       = new BlockingCollection <string>();
     onlineUsersIDs  = new List <Guid>();
     onlineUsernames = new Dictionary <Guid, string>();
 }
예제 #22
0
        public void DeffieHelmanTest1()
        {
            DiffieHellman algorithm = new DiffieHellman();
            List <int>    key       = algorithm.GetKeys(19, 2, 6, 13);

            Assert.AreEqual(key[0], 7);
            Assert.AreEqual(key[1], 7);
        }
예제 #23
0
        public void DeffieHelmanTest3()
        {
            DiffieHellman algorithm = new DiffieHellman();
            List <int>    key       = algorithm.GetKeys(353, 3, 97, 233);

            Assert.AreEqual(key[0], 160);
            Assert.AreEqual(key[1], 160);
        }
예제 #24
0
        private string PrepareDHResponseString(string request)
        {
            DHClient = new DiffieHellman(256).GenerateResponse(request);
            var response = DHClient.ToString();

            DHKey = DHClient.Key;
            return(response);
        }
예제 #25
0
    public void Can_calculate_secret_using_other_partys_public_key()
    {
        var p = new BigInteger(23);
        var theirPublicKey = new BigInteger(19);
        var myPrivateKey   = new BigInteger(6);

        Assert.Equal(new BigInteger(2), DiffieHellman.Secret(p, theirPublicKey, myPrivateKey));
    }
예제 #26
0
        public ActionResult SignUp()
        {
            //Post
            var userName = Request.Form["userName"].ToString();
            var password = Request.Form["password"].ToString();
            var levels   = Convert.ToInt32(Request.Form["levels"].ToString());
            //Get para verificar que no existe un Usuario con otro Nombre
            var found = false;
            var User  = new Users();
            var login = User.GetLogIn();

            foreach (LogInElements elements in login)
            {
                if ((elements.UserName == userName))
                {
                    found = true;
                    break;
                }
            }
            if (found)
            {
                registroValido = 2;
                return(RedirectToAction("Index"));
            }
            else
            {
                //método para cifrar la clave ZigZag
                LogInElements elemento      = new LogInElements();
                DiffieHellman diffieHellman = new DiffieHellman();
                DateTime      now           = DateTime.Now;
                var           ticks         = now.Ticks;
                var           ab            = (int)(ticks % 17);
                var           p             = 1021;
                var           g             = 11;
                var           a             = Convert.ToString(ab, 2);
                a = a.PadLeft(8, '0');
                //cifrar a en binario
                a = User.ZigZagEncryptionCipher(a, levels);
                //cifrar la contraseña del ususario
                var CipherPassword = User.ZigZagEncryptionCipher(password, levels);
                //generar A con diffie Hellman
                var A = diffieHellman.GenerarClaves(ab, p, g);
                //elemento a cifrar
                elemento.Password   = CipherPassword;
                elemento.UserName   = userName;
                elemento.A          = Convert.ToString(A);
                elemento.PrivateKey = a;
                using (var client = new HttpClient())
                {
                    client.BaseAddress = new Uri("http://localhost:58992/");
                    var postjob = client.PostAsync("api/LogIn", new StringContent(new JavaScriptSerializer().Serialize(elemento), Encoding.UTF8, "application/json"));
                    postjob.Wait();
                    registroValido = 1;
                }
                return(RedirectToAction("Index"));
            }
        }
예제 #27
0
파일: DH.cs 프로젝트: amon-ra/Dokan-SSHFS
 public byte[] getE()
 {
     if (e_array == null)
     {
         dh      = new DiffieHellmanManaged(p, g, 0);
         e_array = dh.CreateKeyExchange();
     }
     return(e_array);
 }
예제 #28
0
 public ChatServer()
 {
     ConnectedClients = new List <TcpClient>();
     diffieHellman    = new DiffieHellman();
     commonSecrets    = new Dictionary <TcpClient, byte[]>();
     ClientIDs        = new Dictionary <TcpClient, Guid>();
     IDClients        = new Dictionary <Guid, TcpClient>();
     Usernames        = new Dictionary <Guid, string>();
 }
예제 #29
0
        public byte[] Decrypt(byte[] chunk, PhantasmaKeys keys)
        {
            if (keys.Address != this.Source && keys.Address != this.Destination)
            {
                throw new ChainException("decryption public address does not match");
            }

            return(DiffieHellman.Decrypt(chunk, keys.PrivateKey));
        }
예제 #30
0
        public BigInteger POST(requestSharedKeyBindingModel model)
        {
            DiffieHellman DH  = new DiffieHellman();
            var           key = DH.getFinalKey(BigInteger.Parse(model.Key));

            UserManager.FindById(User.Identity.GetUserId()).SharedBarcodeSecret = key;
            db.SaveChanges();
            return(DH.GetMyPublic());
        }
예제 #31
0
        public HabboCrypto(BigInteger n, BigInteger e, BigInteger d)
        {
            this.DH = new DiffieHellman(200);

            this.RSA = new RSA(n, e, d, 0, 0, 0, 0, 0);

            this.RC4 = new RC4();

            this.Initialized = false;
        }
        public HabboEncryptionHandlerV1(RsaKeyHolder keys)
        {
            this.DiffieHellman = new DiffieHellman();

            this.Rsa = RsaKey.ParsePrivateKey(keys.N, keys.E, keys.D);

            this.Rc4 = new ARC4();

            this.Initialized = false;
        }
        private void ProtocolV4(Stream stream, CertificateStore clientCredentials, Certificate[] trustedRootCertificates, ISecureChannelSecurityManager manager, string preSharedKey, SecureChannelCryptoOptionFlags supportedOptions)
        {
            #region 1. hello handshake

            //send client hello
            SecureChannelPacket.Hello clientHello = new SecureChannelPacket.Hello(BinaryID.GenerateRandomID256(), supportedOptions);
            SecureChannelPacket.WritePacket(stream, clientHello);

            //read server hello
            SecureChannelPacket.Hello serverHello = (new SecureChannelPacket(stream)).GetHello();

            //read selected crypto option
            _selectedCryptoOption = supportedOptions & serverHello.CryptoOptions;

            if (_selectedCryptoOption == SecureChannelCryptoOptionFlags.None)
                throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert);

            #endregion

            #region 2. key exchange

            //read server key exchange data
            SecureChannelPacket.KeyExchange serverKeyExchange = (new SecureChannelPacket(stream)).GetKeyExchange();

            SymmetricEncryptionAlgorithm encAlgo;
            string hashAlgo;
            KeyAgreement keyAgreement;

            switch (_selectedCryptoOption)
            {
                case SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256:
                    encAlgo = SymmetricEncryptionAlgorithm.Rijndael;
                    hashAlgo = "SHA256";
                    keyAgreement = new DiffieHellman(DiffieHellmanGroupType.RFC3526, 2048, KeyAgreementKeyDerivationFunction.Hmac, KeyAgreementKeyDerivationHashAlgorithm.SHA256);
                    break;

                case SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256:
                    encAlgo = SymmetricEncryptionAlgorithm.Rijndael;
                    hashAlgo = "SHA256";
                    keyAgreement = new TechnitiumLibrary.Security.Cryptography.ECDiffieHellman(256, KeyAgreementKeyDerivationFunction.Hmac, KeyAgreementKeyDerivationHashAlgorithm.SHA256);
                    break;

                default:
                    throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert);
            }

            //send client key exchange data
            SecureChannelPacket.KeyExchange clientKeyExchange = new SecureChannelPacket.KeyExchange(keyAgreement.GetPublicKeyXML(), clientCredentials.PrivateKey, hashAlgo);
            SecureChannelPacket.WritePacket(stream, clientKeyExchange);

            //generate master key
            byte[] masterKey = GenerateMasterKey(clientHello, serverHello, _preSharedKey, keyAgreement, serverKeyExchange.PublicKeyXML);

            //verify master key using HMAC authentication
            {
                SecureChannelPacket.Authentication clientAuthentication = new SecureChannelPacket.Authentication(serverHello, masterKey);
                SecureChannelPacket.WritePacket(stream, clientAuthentication);

                SecureChannelPacket.Authentication serverAuthentication = (new SecureChannelPacket(stream)).GetAuthentication();
                if (!serverAuthentication.IsValid(clientHello, masterKey))
                    throw new SecureChannelException(SecureChannelCode.ProtocolAuthenticationFailed, _remotePeerEP, _remotePeerCert);
            }

            //enable channel encryption
            switch (encAlgo)
            {
                case SymmetricEncryptionAlgorithm.Rijndael:
                    //using MD5 for generating AES IV of 128bit block size
                    HashAlgorithm md5Hash = HashAlgorithm.Create("MD5");
                    byte[] eIV = md5Hash.ComputeHash(clientHello.Nonce.ID);
                    byte[] dIV = md5Hash.ComputeHash(serverHello.Nonce.ID);

                    //create encryption and decryption objects
                    SymmetricCryptoKey encryptionKey = new SymmetricCryptoKey(SymmetricEncryptionAlgorithm.Rijndael, masterKey, eIV, PaddingMode.None);
                    SymmetricCryptoKey decryptionKey = new SymmetricCryptoKey(SymmetricEncryptionAlgorithm.Rijndael, masterKey, dIV, PaddingMode.None);

                    //enable encryption
                    EnableEncryption(stream, encryptionKey, decryptionKey, new HMACSHA256(masterKey), new HMACSHA256(masterKey));
                    break;

                default:
                    throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert);
            }

            //channel encryption is ON!

            #endregion

            #region 3. exchange & verify certificates & signatures

            if (!_reNegotiating)
            {
                //send client certificate
                SecureChannelPacket.WritePacket(this, clientCredentials.Certificate);

                //read server certificate
                _remotePeerCert = (new SecureChannelPacket(this)).GetCertificate();

                //verify server certificate
                try
                {
                    _remotePeerCert.Verify(trustedRootCertificates);
                }
                catch (Exception ex)
                {
                    throw new SecureChannelException(SecureChannelCode.InvalidRemoteCertificate, _remotePeerEP, _remotePeerCert, "Invalid remote certificate.", ex);
                }
            }

            //verify key exchange signature
            switch (_selectedCryptoOption)
            {
                case SecureChannelCryptoOptionFlags.DHE2048_RSA_WITH_AES256_CBC_HMAC_SHA256:
                case SecureChannelCryptoOptionFlags.ECDHE256_RSA_WITH_AES256_CBC_HMAC_SHA256:
                    if (_remotePeerCert.PublicKeyEncryptionAlgorithm != AsymmetricEncryptionAlgorithm.RSA)
                        throw new SecureChannelException(SecureChannelCode.InvalidRemoteCertificateAlgorithm, _remotePeerEP, _remotePeerCert);

                    if (!serverKeyExchange.IsSignatureValid(_remotePeerCert, "SHA256"))
                        throw new SecureChannelException(SecureChannelCode.InvalidRemoteKeyExchangeSignature, _remotePeerEP, _remotePeerCert);

                    break;

                default:
                    throw new SecureChannelException(SecureChannelCode.NoMatchingCryptoAvailable, _remotePeerEP, _remotePeerCert);
            }

            if ((manager != null) && !manager.ProceedConnection(_remotePeerCert))
                throw new SecureChannelException(SecureChannelCode.SecurityManagerDeclinedAccess, _remotePeerEP, _remotePeerCert, "Security manager declined access.");

            #endregion
        }
예제 #34
0
 public static void Initialize(RsaKeyHolder keys)
 {
     Rsa = RsaKey.ParsePrivateKey(keys.N, keys.E, keys.D);
     DiffieHellman = new DiffieHellman();
 }