Exemple #1
0
        public static ECDiffieHellmanPublicKey FromDerEncoded(byte[] keyBytes)
        {
            var clientPublicKeyBlob            = FixPublicKey(keyBytes.Skip(23).ToArray());
            ECDiffieHellmanPublicKey clientKey = ECDiffieHellmanCngPublicKey.FromByteArray(clientPublicKeyBlob, CngKeyBlobFormat.EccPublicBlob);

            return(clientKey);
        }
        private byte[] DiffieHellmanClient(Rijndael newRijndael)
        {
            ECDiffieHellmanCng ECDF = new ECDiffieHellmanCng();
            ECDF.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
            ECDF.HashAlgorithm = CngAlgorithm.Sha256;
            byte[] pubkey = ECDF.PublicKey.ToByteArray();

            string base64pubkey = Convert.ToBase64String(pubkey);

            Send(dataStream, base64pubkey); //pošlje javni ključ kot base64

            string serverPublicKey = Recieve(dataStream); //prejme njegov javni ključ

            //byte[] iv = Encoding.UTF32.GetBytes("sestnajst1234567");
            //Send(dataStream, Convert.ToBase64String(iv));
            newRijndael.GenerateIV();
            iv = Convert.ToBase64String(newRijndael.IV);
            MessageBox.Show("iv je: " + iv);
            Send(dataStream, iv);

            byte[] byteServerKey = Convert.FromBase64String(serverPublicKey);
            byte[] sharedKey = ECDF.DeriveKeyMaterial(ECDiffieHellmanCngPublicKey.FromByteArray(byteServerKey, CngKeyBlobFormat.EccPublicBlob));

            return sharedKey;
        }
Exemple #3
0
        public Task KeyExchangeAsync()
        {
            return(Task.Factory.StartNew(delegate
            {
                keyProvider = getNewKeyProvider();

                this.ClientConnection.WtlpClient.EncryptionIV = new AesCryptoServiceProvider().IV;

                var response = (string)ClientConnection.CallRemoteFunction(
                    ComponentNamesExtended.Authentication,
                    AuthenticationMethods.KeyExchange,
                    keyProvider.PublicKey.ToByteArray().ToStringBase64(),
                    this.ClientConnection.WtlpClient.EncryptionIV.ToStringBase64()
                    );


                ECDiffieHellmanPublicKey otherKey = ECDiffieHellmanCngPublicKey.FromByteArray(response.GetBytesBase64(), CngKeyBlobFormat.EccPublicBlob);

                this.ClientConnection.WtlpClient.EncryptionKey = keyProvider.DeriveKeyMaterial(otherKey);

                this.ClientConnection.TrustLevel = 2;
                this.ClientConnection.MyTrustLevel = 2;

                this.ClientConnection.WtlpClient.EncryptMessages = true;

                keyProvider = null;
            }));
        }
Exemple #4
0
        public static ECDiffieHellmanCngPublicKey FromTLSPublicKey(CngAlgorithm alg, byte[] tlsKey)
        {
            if (alg == CngAlgorithm.ECDiffieHellmanP256)
            {
                if (tlsKey.Length != 65)
                {
                    throw new ArgumentOutOfRangeException(nameof(tlsKey), $"Expecting 65 bytes, received {tlsKey.Length} bytes.");
                }

                var buffer = new byte[72];
                buffer.AsSpan().Write(BCRYPT_ECDH_PUBLIC_P256_MAGIC).Write(tlsKey.AsSpan().Slice(1));

                return((ECDiffieHellmanCngPublicKey)ECDiffieHellmanCngPublicKey.FromByteArray(buffer, CngKeyBlobFormat.EccPublicBlob));
            }

            if (alg == CngAlgorithm.ECDiffieHellmanP384)
            {
                if (tlsKey.Length != 97)
                {
                    throw new ArgumentOutOfRangeException(nameof(tlsKey), $"Expecting 97 bytes, received {tlsKey.Length} bytes.");
                }

                var buffer = new byte[104];
                buffer.AsSpan().Write(BCRYPT_ECDH_PUBLIC_P384_MAGIC).Write(tlsKey.AsSpan().Slice(1));

                return((ECDiffieHellmanCngPublicKey)ECDiffieHellmanCngPublicKey.FromByteArray(buffer, CngKeyBlobFormat.EccPublicBlob));
            }

            throw new NotImplementedException();
        }
Exemple #5
0
        public override byte[] ProcessServerKeys(ProtocolVersion version, byte[] data)
        {
            // Only ECCurveType.named_curve is supported
            if (data[0] != 3)
            {
                throw new Exception("ECCurveType " + data[0] + " is not supported");
            }

            // Create our ECDiffieHellmanCng provider with correct curve
            UInt16 namedCurve = (UInt16)((data[1] << 8) + data[2]);

            _ecdhCng = new ECDiffieHellmanCng(NamedCurveToKeySize(namedCurve));

            // Extract the ECPoint data
            int keyLength = data[3];

            byte[] ecPoint = new byte[keyLength];
            Buffer.BlockCopy(data, 4, ecPoint, 0, keyLength);

            // Extract the signature
            byte[] signature = new byte[data.Length - 4 - keyLength];
            Buffer.BlockCopy(data, 4 + keyLength, signature, 0, data.Length - 4 - keyLength);

            // Create the public key from the ecPoint
            byte[] keyBlob = Point2Blob(ecPoint);
            _publicKey = ECDiffieHellmanCngPublicKey.FromByteArray(keyBlob, CngKeyBlobFormat.EccPublicBlob);

            return(signature);
        }
 /// <summary>
 ///
 /// The encryption format is a JSON-encoded EcEncryptedMessageAesCbcHmacSha256.
 /// </summary>
 /// <param name="value">The value to store encrypted.</param>
 /// <param name="ecPublicKeyAsByteArray">The public key used to encrypt the value.</param>
 public void Write(byte[] value, byte[] ecPublicKeyAsByteArray)
 {
     using (ECDiffieHellmanPublicKey ecPublicKey = ECDiffieHellmanCngPublicKey.FromByteArray(ecPublicKeyAsByteArray, CngKeyBlobFormat.EccPublicBlob))
     {
         Write(value, ecPublicKey);
     }
 }
Exemple #7
0
        public CallResult KeyExchange_server(string publicKey, string iv)
        {
            //Initialize a new key provides
            this.keyProvider = AuthenticationComponent.getNewKeyProvider();
            ECDiffieHellmanPublicKey otherKey = ECDiffieHellmanCngPublicKey.FromByteArray(publicKey.GetBytesBase64(), CngKeyBlobFormat.EccPublicBlob);

            //derive connection key from target's public key

            var key = keyProvider.DeriveKeyMaterial(otherKey);

            ClientConnection.WtlpClient.EncryptionKey = key;
            var initVector = iv.GetBytesBase64();

            ClientConnection.WtlpClient.EncryptionIV = iv.GetBytesBase64();

            //Increase Trust level (connection is now encrypted)

            this.ClientConnection.TrustLevel   = 2;
            this.ClientConnection.MyTrustLevel = 2;


            //Send back our own public key so target can derive connection key, too
            CallResult result = new ResponseResult(keyProvider.PublicKey.ToByteArray().ToStringBase64());

            //once the response has been sent, enable encryption for all following messages
            result.PostProcessingAction += delegate { this.ClientConnection.WtlpClient.EncryptMessages = true; };

            //Reset key provider
            keyProvider = null;

            return(result);
        }
Exemple #8
0
        /// <summary>
        /// Occurs when the client has been sucessfully authenticated by the loginserver.
        /// Called by UILoginDialog.cs.
        /// </summary>
        /// <param name="Client">The client that received the packet.</param>
        /// <param name="Packet">The packet that was received.</param>
        public static void OnLoginNotify(NetworkClient Client, ProcessedPacket Packet)
        {
            //Should this be stored for permanent access?
            byte[] ServerPublicKey = Packet.ReadBytes(Packet.ReadByte());
            byte[] EncryptedData   = Packet.ReadBytes(Packet.ReadByte());

            AESEncryptor Enc = (AESEncryptor)Client.ClientEncryptor;

            Enc.PublicKey          = ServerPublicKey;
            Client.ClientEncryptor = Enc;
            lock (NetworkFacade.Client)
                NetworkFacade.Client.ClientEncryptor = Enc;

            ECDiffieHellmanCng PrivateKey = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.PrivateKey;

            byte[] NOnce = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.NOnce;

            byte[] ChallengeResponse = StaticStaticDiffieHellman.Decrypt(PrivateKey,
                                                                         ECDiffieHellmanCngPublicKey.FromByteArray(ServerPublicKey, CngKeyBlobFormat.EccPublicBlob),
                                                                         NOnce, EncryptedData);

            MemoryStream StreamToEncrypt = new MemoryStream();
            BinaryWriter Writer          = new BinaryWriter(StreamToEncrypt);

            Writer.Write((byte)ChallengeResponse.Length);
            Writer.Write(ChallengeResponse, 0, ChallengeResponse.Length);

            Writer.Write(Client.ClientEncryptor.Username);
            Writer.Write((byte)PlayerAccount.Hash.Length);
            Writer.Write(PlayerAccount.Hash);
            Writer.Flush();

            //Encrypt data using key and IV from server, hoping that it'll be decrypted correctly at the other end...
            Client.SendEncrypted((byte)PacketType.CHALLENGE_RESPONSE, StreamToEncrypt.ToArray());
        }
Exemple #9
0
        public byte[] SetSessionKey(byte[] clientPublicKey) //set session key
        {
            //CngKey k = CngKey.Import(clientPublicKey, CngKeyBlobFormat.EccPublicBlob); //firs argument public key from client
            byte[] SessionKey = owner.DeriveKeyMaterial(ECDiffieHellmanCngPublicKey.FromByteArray(clientPublicKey, CngKeyBlobFormat.EccPublicBlob));//firs argument public key from client

            return(SessionKey);
        }
        // private ECDiffieHellmanCng diffieHellman = null;

        public Aes DeriveKeyAndIv(byte[] privateKeyFrom, byte[] publicKeyTo, string prefix)
        {
            byte[] x = { 69, 67, 83, 49, 64, 0, 0, 0 };

            //Prefix above generated array to existing public key array
            privateKeyFrom = x.Concat(privateKeyFrom).ToArray();
            var privateKey = new ECDiffieHellmanCng(CngKey.Import(privateKeyFrom, new CngKeyBlobFormat("ECCPRIVATEBLOB")));

            privateKey.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
            privateKey.HashAlgorithm         = CngAlgorithm.Sha256;
            privateKey.SecretAppend          = StringToBytes(prefix);
            byte[] keyAndIv = privateKey.DeriveKeyMaterial(ECDiffieHellmanCngPublicKey.FromByteArray(publicKeyTo, new CngKeyBlobFormat("PUBLICBLOB")));
            byte[] key      = new byte[16];
            Array.Copy(keyAndIv, 0, key, 0, 16);
            byte[] iv = new byte[16];
            Array.Copy(keyAndIv, 16, iv, 0, 16);

            aes         = new AesManaged();
            aes.Key     = key;
            aes.IV      = iv;
            aes.Mode    = CipherMode.CBC;
            aes.Padding = PaddingMode.PKCS7;

            return(aes);
        }
Exemple #11
0
        public static ECDiffieHellmanPublicKey CreateEcDiffieHellmanPublicKey(string clientPubKeyString)
        {
            byte[] clientPublicKeyBlob = Base64Url.Decode(clientPubKeyString);
            clientPublicKeyBlob = FixPublicKey(clientPublicKeyBlob.Skip(23).ToArray());

            ECDiffieHellmanPublicKey clientKey = ECDiffieHellmanCngPublicKey.FromByteArray(clientPublicKeyBlob, CngKeyBlobFormat.EccPublicBlob);

            return(clientKey);
        }
Exemple #12
0
        public static ECDiffieHellmanPublicKey ImportEccPublicKeyFromCertificate(X509Certificate2 cert)
        {
            var keyType   = new byte[] { 0x45, 0x43, 0x4b, 0x33 };
            var keyLength = new byte[] { 0x30, 0x00, 0x00, 0x00 };
            var key       = cert.PublicKey.EncodedKeyValue.RawData.Skip(1);
            var keyImport = keyType.Concat(keyLength).Concat(key).ToArray();

            return(ECDiffieHellmanCngPublicKey.FromByteArray(keyImport, CngKeyBlobFormat.EccPublicBlob));
        }
Exemple #13
0
        public static ECDiffieHellmanPublicKey ImportKey(string Path)
        {
            ECDiffieHellmanPublicKey Key;

            using (BinaryReader Reader = new BinaryReader(File.Open(Path, FileMode.Open)))
            {
                Key = ECDiffieHellmanCngPublicKey.FromByteArray(Reader.ReadBytes(Reader.ReadByte()), CngKeyBlobFormat.EccPublicBlob);
                return(Key);
            }
        }
Exemple #14
0
        /// <summary>
        /// Decrypts the contents of the provided PacketStream instance.
        /// </summary>
        /// <param name="EncryptedPacket">An encrypted PacketStream instance.</param>
        /// <param name="DecryptionArgs">A DecryptionArgsContainer instance.</param>
        /// <returns>A MemoryStream instance with the decrypted data.</returns>
        public override MemoryStream DecryptPacket(PacketStream EncryptedPacket, DecryptionArgsContainer DecryptionArgs)
        {
            byte[] EncryptedData = new byte[EncryptedPacket.Length - (int)PacketHeaders.ENCRYPTED];
            EncryptedPacket.Read(EncryptedData, 0, EncryptedData.Length);

            byte[] DecryptedData = StaticStaticDiffieHellman.Decrypt(m_PrivateKey,
                                                                     ECDiffieHellmanCngPublicKey.FromByteArray(m_PublicKey, CngKeyBlobFormat.EccPublicBlob),
                                                                     m_NOnce, EncryptedData);

            return(new MemoryStream(DecryptedData));
        }
Exemple #15
0
        protected void InitializeCrypto(byte[] remoteKey, bool isAuthority)
        {
            ECDiffieHellmanPublicKey publicKey = ECDiffieHellmanCngPublicKey.FromByteArray(remoteKey, CngKeyBlobFormat.EccPublicBlob);

            byte[] keyMaterial = _ecdh.DeriveKeyMaterial(publicKey);

            byte[] salt = new byte[_clientNonce.Length + _serverNonce.Length];
            Buffer.BlockCopy(_serverNonce, 0, salt, 0, _serverNonce.Length);
            Buffer.BlockCopy(_clientNonce, 0, salt, _serverNonce.Length, _clientNonce.Length);

            Rfc5869DeriveBytes kdf = new Rfc5869DeriveBytes(HMACAlgorithmName.HMACSHA256, keyMaterial, salt);

            byte[] cryptoBlock = kdf.GetBytes((AES_IV_SIZE + AES_KEY_SIZE + MAC_KEY_SIZE) * 2);

            byte[] serverAesIv  = new byte[AES_IV_SIZE];
            byte[] serverAesKey = new byte[AES_KEY_SIZE];
            byte[] serverMacKey = new byte[MAC_KEY_SIZE];
            byte[] clientAesIv  = new byte[AES_IV_SIZE];
            byte[] clientAesKey = new byte[AES_KEY_SIZE];
            byte[] clientMacKey = new byte[MAC_KEY_SIZE];

            int offset = 0;

            offset += BlockCopy(cryptoBlock, offset, serverAesIv, 0, serverAesIv.Length);
            offset += BlockCopy(cryptoBlock, offset, serverAesKey, 0, serverAesKey.Length);
            offset += BlockCopy(cryptoBlock, offset, serverMacKey, 0, serverMacKey.Length);
            offset += BlockCopy(cryptoBlock, offset, clientAesIv, 0, clientAesIv.Length);
            offset += BlockCopy(cryptoBlock, offset, clientAesKey, 0, clientAesKey.Length);
            offset += BlockCopy(cryptoBlock, offset, clientMacKey, 0, clientMacKey.Length);

            _signer     = new HMACSHA256();
            _signer.Key = isAuthority ? serverMacKey : clientMacKey;

            _verifier     = new HMACSHA256();
            _verifier.Key = isAuthority ? clientMacKey : serverMacKey;

            AesCounterModeProvider provider1 = new AesCounterModeProvider();

            provider1.IV  = isAuthority ? serverAesIv : clientAesIv;
            provider1.Key = isAuthority ? serverAesKey : clientAesKey;

            AesCounterModeProvider provider2 = new AesCounterModeProvider();

            provider2.IV  = isAuthority ? clientAesIv : serverAesIv;
            provider2.Key = isAuthority ? clientAesKey : serverAesKey;

            _encryptor = provider1.CreateEncryptor();
            _decryptor = provider2.CreateDecryptor();

            _secure = true;
        }
Exemple #16
0
        public override void ProcessClientKeys(ProtocolVersion version, ProtocolVersion clientVersion, CertificatePrivateKey privateKey, byte[] data)
        {
            if (data[0] != data.Length - 1)
            {
                throw new Exception("Incorrect ECPoint length");
            }

            // Exctract the ECPoint
            byte[] ecPoint = new byte[data.Length - 1];
            Buffer.BlockCopy(data, 1, ecPoint, 0, ecPoint.Length);

            // Create key blob and public key
            byte[] keyBlob = Point2Blob(ecPoint);
            _publicKey = ECDiffieHellmanCngPublicKey.FromByteArray(keyBlob, CngKeyBlobFormat.EccPublicBlob);
        }
Exemple #17
0
 /// <summary>
 /// Derives an 256bit key using ECDH-P521 and SHA256 that can be used for cryptographic operations.
 /// </summary>
 /// <param name="privateKey">My private key.</param>
 /// <param name="publicKey">Counterpart public key.</param>
 /// <returns></returns>
 public static byte[] DeriveKey(byte[] privateKey, byte[] publicKey)
 {
     byte[] final;
     using (CngKey key = CngKey.Import(privateKey, CngKeyBlobFormat.EccPrivateBlob))
         using (ECDiffieHellmanCng ecdh = new ECDiffieHellmanCng(key))
         {
             ecdh.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
             ecdh.HashAlgorithm         = CngAlgorithm.Sha256;
             using (ECDiffieHellmanPublicKey pub = ECDiffieHellmanCngPublicKey.FromByteArray(publicKey, CngKeyBlobFormat.EccPublicBlob))
             {
                 final = ecdh.DeriveKeyMaterial(pub);
             }
         }
     return(final);
 }
Exemple #18
0
        /// <summary>
        /// A client requested login.
        /// </summary>
        /// <param name="Client">NetworkClient instance.</param>
        /// <param name="Packet">ProcessedPacket instance.</param>
        public static void InitialClientConnect(NetworkClient Client, ProcessedPacket Packet)
        {
            Console.WriteLine("Server receives data - test 1");

            PacketStream EncryptedPacket = new PacketStream(0x02, 0);

            EncryptedPacket.WriteHeader();

            ClientPublicKey = Packet.ReadBytes((Packet.ReadByte()));

            AESEncryptor Enc = (AESEncryptor)Client.ClientEncryptor;

            Enc.NOnce              = Packet.ReadBytes((Packet.ReadByte()));
            Enc.PublicKey          = ClientPublicKey;
            Enc.PrivateKey         = ServerPrivateKey;
            Client.ClientEncryptor = Enc;

            //THIS IS IMPORTANT - public key must be derived from private!
            ServerPublicKey = ServerPrivateKey.PublicKey.ToByteArray();

            ChallengeResponse = new byte[16];
            m_Random.GetNonZeroBytes(ChallengeResponse);

            MemoryStream StreamToEncrypt = new MemoryStream();
            BinaryWriter Writer          = new BinaryWriter(StreamToEncrypt);

            Writer.Write(ChallengeResponse, 0, ChallengeResponse.Length);
            Writer.Flush();

            byte[] EncryptedData = StaticStaticDiffieHellman.Encrypt(ServerPrivateKey,
                                                                     ECDiffieHellmanCngPublicKey.FromByteArray(ClientPublicKey, CngKeyBlobFormat.EccPublicBlob), Enc.NOnce,
                                                                     StreamToEncrypt.ToArray());

            EncryptedPacket.WriteUInt16((ushort)(PacketHeaders.UNENCRYPTED +
                                                 (1 + ServerPublicKey.Length) +
                                                 (1 + EncryptedData.Length)));

            EncryptedPacket.WriteByte((byte)ServerPublicKey.Length);
            EncryptedPacket.WriteBytes(ServerPublicKey);
            EncryptedPacket.WriteByte((byte)EncryptedData.Length);
            EncryptedPacket.WriteBytes(EncryptedData);

            Client.Send(EncryptedPacket.ToArray());

            NetworkFacade.Listener.UpdateClient(Client);

            Console.WriteLine("Test 1: passed!");
        }
Exemple #19
0
        public byte[] GetDerivedKey(byte[] Material, byte[] Signature, byte[] PublicKey)
        {
            using (DSACryptoServiceProvider verifyDSA = new DSACryptoServiceProvider())
            {
                verifyDSA.ImportCspBlob(PublicKey);
                if (!verifyDSA.VerifyData(Material, Signature))
                {
                    Logger.Instance.LogError("Odebrano pakiet negocjacyjny z niepoprawnym podpisem. Klucz nie został uzgodniony!");
                    return(null);
                }
            }

            return(DiffieHellman.DeriveKeyMaterial(
                       ECDiffieHellmanCngPublicKey.FromByteArray(
                           Material,
                           CngKeyBlobFormat.EccPublicBlob
                           )
                       ));
        }
Exemple #20
0
        protected void DeriveSecretKey(string otherPartyPublicKey)
        {
            byte[] bytes = dh.DeriveKeyMaterial(ECDiffieHellmanCngPublicKey.FromByteArray(Convert.FromBase64String(otherPartyPublicKey), CngKeyBlobFormat.EccPublicBlob));

            aes = new AesManaged();

            aes.KeySize = 128;
            aes.Padding = PaddingMode.PKCS7;
            aes.Mode    = CipherMode.CBC;

            byte[] IV  = new byte[16];
            byte[] Key = new byte[16];

            Array.Copy(bytes, IV, 16);
            Array.Copy(bytes, 16, Key, 0, 16);

            aes.IV  = IV;
            aes.Key = Key;
        }
        private byte[] DiffieHellmanServer()
        {
            ECDiffieHellmanCng ECDF = new ECDiffieHellmanCng();
            ECDF.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
            ECDF.HashAlgorithm = CngAlgorithm.Sha256;
            byte[] pubkey = ECDF.PublicKey.ToByteArray();

            //byte[] data = Encoding.UTF8.GetBytes(Recieve(dataStream));
            string clientPublicKey = Recieve(dataStream); // Prejme base64 ključ

            Send(dataStream, Convert.ToBase64String(pubkey)); //pošlje base64 ključ

            iv = Recieve(dataStream);

            byte[] byteClientKey = Convert.FromBase64String(clientPublicKey);
            byte[] sharedKey = ECDF.DeriveKeyMaterial(ECDiffieHellmanCngPublicKey.FromByteArray(byteClientKey, CngKeyBlobFormat.EccPublicBlob));

            return sharedKey;
        }
Exemple #22
0
        protected string Encrypt(string blob, string externalKey)
        {
            var self = new ECDiffieHellmanCng();

            self.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
            self.HashAlgorithm         = CngAlgorithm.Sha256;

            publicKey = Convert.ToBase64String(self.PublicKey.ToByteArray());

            var externalKeyBytes = Convert.FromBase64String(externalKey);

            var externalKeyObject = ECDiffieHellmanCngPublicKey.FromByteArray(externalKeyBytes,
                                                                              CngKeyBlobFormat.GenericPublicBlob);

            var sharedSecret = self.DeriveKeyMaterial(externalKeyObject);

            var aes = new AesManaged();

            aes.Key = sharedSecret;
            aes.GenerateIV();

            var transform = aes.CreateEncryptor();

            using (var memoryStream = new MemoryStream())
            {
                var cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);

                var data = Encoding.ASCII.GetBytes(blob);

                cryptoStream.Write(data, 0, data.Length);
                cryptoStream.Close();

                var encryptedData = memoryStream.ToArray();

                blob = Convert.ToBase64String(encryptedData);

                self.Dispose();
                aes.Dispose();

                return(AddEncryptionHeaders(blob));
            }
        }
        public static ECDiffieHellmanPublicKey ParseECDiffieHellmanPublicKey256FromPublicKey(PublicKey publicKey)
        {
            if (publicKey.EncodedKeyValue.RawData.Length != 65)
            {
                throw new InvalidOperationException("KeyData length is invalid.");
            }

            byte[] FinalBuffer = new byte[72];

            using (MemoryStream Stream = new MemoryStream(FinalBuffer))
            {
                using BinaryWriter Writer = new BinaryWriter(Stream);

                Writer.Write(s_Win32_ECDH_Public_256_MagicNumber);
                Writer.Write(s_Win32_ECDH_Public_256_Length);
                Writer.Write(publicKey.EncodedKeyValue.RawData, 1, publicKey.EncodedKeyValue.RawData.Length - 1);
            }

            return(ECDiffieHellmanCngPublicKey.FromByteArray(FinalBuffer, CngKeyBlobFormat.EccPublicBlob));
        }
Exemple #24
0
        /// <summary>
        /// Constructs an encrypted packet.
        /// </summary>
        /// <param name="PacketID">The ID of the packet.</param>
        /// <param name="PacketData">The data to encrypt.</param>
        /// <returns>A byte array containing the ID, length of the encrypted data and the encrypted data.</returns>
        public override byte[] FinalizePacket(byte PacketID, byte[] PacketData)
        {
            MemoryStream PacketStream = new MemoryStream();
            BinaryWriter PacketWriter = new BinaryWriter(PacketStream);

            PacketWriter.Write(PacketID);

            byte[] EncryptedData = StaticStaticDiffieHellman.Encrypt(m_PrivateKey,
                                                                     ECDiffieHellmanCngPublicKey.FromByteArray(m_PublicKey, CngKeyBlobFormat.EccPublicBlob),
                                                                     m_NOnce, PacketData);

            //The length of the encrypted data can be longer or smaller than the original length,
            //so write the length of the encrypted data.
            PacketWriter.Write((uint)(PacketHeaders.ENCRYPTED + EncryptedData.Length));
            //Also write the length of the unencrypted data.
            PacketWriter.Write(PacketData.Length);
            PacketWriter.Flush();

            PacketWriter.Write(EncryptedData);
            PacketWriter.Flush();

            return(PacketStream.ToArray());
        }
Exemple #25
0
        /// <summary>
        /// Initial response from server to client.
        /// </summary>
        /// <param name="Client">A NetworkClient instance.</param>
        /// <param name="Packet">A ProcessedPacket instance.</param>
        public static void HandleServerChallenge(NetworkClient Client, ProcessedPacket Packet)
        {
            Console.WriteLine("Client receives encrypted data - test 2");

            ServerPublicKey = Packet.ReadBytes(Packet.ReadByte());
            byte[] EncryptedData = Packet.ReadBytes(Packet.ReadByte());

            AESEncryptor Enc = (AESEncryptor)Client.ClientEncryptor;

            Enc.PublicKey          = ServerPublicKey;
            Client.ClientEncryptor = Enc;
            NetworkFacade.Client.ClientEncryptor = Enc;

            ECDiffieHellmanCng PrivateKey = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.PrivateKey;

            byte[] NOnce = Client.ClientEncryptor.GetDecryptionArgsContainer().AESDecryptArgs.NOnce;

            byte[] ChallengeResponse = StaticStaticDiffieHellman.Decrypt(PrivateKey,
                                                                         ECDiffieHellmanCngPublicKey.FromByteArray(ServerPublicKey, CngKeyBlobFormat.EccPublicBlob),
                                                                         NOnce, EncryptedData);

            MemoryStream StreamToEncrypt = new MemoryStream();
            BinaryWriter Writer          = new BinaryWriter(StreamToEncrypt);

            Writer.Write((byte)ChallengeResponse.Length);
            Writer.Write(ChallengeResponse, 0, ChallengeResponse.Length);

            Writer.Write(Client.ClientEncryptor.Username);
            Writer.Write((byte)PasswordHash.Length);
            Writer.Write(PasswordHash);
            Writer.Flush();

            Client.SendEncrypted(0x03, StreamToEncrypt.ToArray());

            Console.WriteLine("Test 2: passed!");
        }
Exemple #26
0
        public List <byte> CreateCKE()
        {
            if (this.kxType == "RSA")
            {
                List <byte> protocolVersion = new List <byte> ();
                List <byte> preMasterSecret = new List <byte>();

                byte[] random;
                Random rnd;

                protocolVersion.Add(this.majorVersion);
                protocolVersion.Add(this.minorVersion);

                random = new byte[46];
                rnd    = new Random();
                rnd.NextBytes(random);

                preMasterSecret.AddRange(protocolVersion.ToArray());
                preMasterSecret.AddRange(random);

                this.pre_master_secret_list = preMasterSecret;
                this.pre_master_secret      = preMasterSecret.ToArray();

                int certLen = this.common.ReadAtLoc(this.sCert_hs, 7, 3);

                byte[] sCert = new byte[certLen];
                Array.Copy(this.sCert_hs, 10, sCert, 0, certLen);

                String b64Cert = Convert.ToBase64String(sCert);

                System.IO.File.WriteAllText(@"server_cert.pem", b64Cert);
                X509Certificate2 cert      = new X509Certificate2(sCert);
                byte[]           publicKey = cert.PublicKey.EncodedKeyValue.RawData;
                String           b64PubKey = Convert.ToBase64String(publicKey);

                RSACryptoServiceProvider rsaProvider = (RSACryptoServiceProvider)cert.PublicKey.Key;

                byte[] encPMKey     = rsaProvider.Encrypt(this.pre_master_secret, RSAEncryptionPadding.Pkcs1);
                byte[] encPMKey_len = BitConverter.GetBytes((short)encPMKey.Length);
                Array.Reverse(encPMKey_len);

                this.ckeMessage = new List <byte>();
                this.ckeMessage.AddRange(encPMKey_len);
                this.ckeMessage.AddRange(encPMKey);

                return(this.ckeMessage);
            }
            else if (this.kxType == "ECDHE")
            {
                int skeLen = this.sKeyExch_hs[7];
                skeLen = skeLen - 1;

                byte[] sPubKey = new byte[skeLen];
                Buffer.BlockCopy(this.sKeyExch_hs, 9, sPubKey, 0, skeLen);

                this.ecdhCngClient = new ECDiffieHellmanCng(256);

                this.client_pub_key = this.ecdhCngClient.PublicKey;

                this.client_pub_key_bytes = this.ecdhCngClient.PublicKey.ToByteArray();

                byte[] i = { 0x04 };

                this.client_pub_key_bytes = this.client_pub_key_bytes.Skip(8).ToArray();

                this.client_pub_key_bytes = i.Concat(this.client_pub_key_bytes).ToArray();

                byte[] x = { 0x45, 0x43, 0x4B, 0x31, 0x20, 0, 0, 0 };

                sPubKey = x.Concat(sPubKey).ToArray();

                ECDiffieHellmanPublicKey serverKey = ECDiffieHellmanCngPublicKey.FromByteArray(sPubKey, CngKeyBlobFormat.EccPublicBlob);

                this.server_pub_key = serverKey;

                byte[] symmKey = this.ecdhCngClient.DeriveKeyMaterial(serverKey);

                this.pre_master_secret = sPubKey;

                this.pre_master_secret_list = new List <byte>(this.pre_master_secret);

                byte client_pub_key_len = (byte)this.client_pub_key_bytes.Length;

                this.ckeMessage = new List <byte>();
                this.ckeMessage.Add(client_pub_key_len);
                this.ckeMessage.AddRange(this.client_pub_key_bytes);

                return(this.ckeMessage);
            }
            List <byte> result1 = new List <byte>();

            return(result1);
        }
Exemple #27
0
        public async Task ECAsymmetricSigningAndEncryption()
        {
            var bob         = new ECDsaCng(521);
            var bobPublic   = CngKey.Import(bob.Key.Export(CngKeyBlobFormat.EccPublicBlob), CngKeyBlobFormat.EccPublicBlob);
            var alice       = new ECDsaCng(521);
            var alicePublic = CngKey.Import(alice.Key.Export(CngKeyBlobFormat.EccPublicBlob), CngKeyBlobFormat.EccPublicBlob);

            // Bob formulates request.
            var bobRequest = new MemoryStream();
            var bobDH      = ECDiffieHellman.Create();
            {
                byte[] bobPublicDH = bobDH.PublicKey.ToByteArray();
                byte[] bobSignedDH = bob.SignData(bobPublicDH);
                await bobRequest.WriteSizeAndBufferAsync(bobPublicDH, CancellationToken.None);

                await bobRequest.WriteSizeAndBufferAsync(bobSignedDH, CancellationToken.None);

                bobRequest.Position = 0;
            }

            // Alice reads request.
            var aliceResponse = new MemoryStream();

            byte[] aliceKeyMaterial;
            var    aliceDH = new ECDiffieHellmanCng();

            {
                byte[] bobPublicDH = await bobRequest.ReadSizeAndBufferAsync(CancellationToken.None);

                byte[] bobSignedDH = await bobRequest.ReadSizeAndBufferAsync(CancellationToken.None);

                var bobDsa = new ECDsaCng(bobPublic);
                Assert.IsTrue(bobDsa.VerifyData(bobPublicDH, bobSignedDH));
                var bobDHPK = ECDiffieHellmanCngPublicKey.FromByteArray(bobPublicDH, CngKeyBlobFormat.EccPublicBlob);
                aliceKeyMaterial = aliceDH.DeriveKeyMaterial(bobDHPK);

                await aliceResponse.WriteSizeAndBufferAsync(aliceDH.PublicKey.ToByteArray(), CancellationToken.None);

                await aliceResponse.WriteSizeAndBufferAsync(alice.SignData(aliceDH.PublicKey.ToByteArray()), CancellationToken.None);

                // Alice also adds a secret message.
                using (var aes = SymmetricAlgorithm.Create())
                {
                    using (var encryptor = aes.CreateEncryptor(aliceKeyMaterial, new byte[aes.BlockSize / 8]))
                    {
                        var cipherText = new MemoryStream();
                        using (var cryptoStream = new CryptoStream(cipherText, encryptor, CryptoStreamMode.Write))
                        {
                            cryptoStream.Write(new byte[] { 0x1, 0x3, 0x2 }, 0, 3);
                            cryptoStream.FlushFinalBlock();
                            cipherText.Position = 0;
                            await aliceResponse.WriteSizeAndStreamAsync(cipherText, CancellationToken.None);
                        }
                    }
                }

                aliceResponse.Position = 0;
            }

            // Bob reads response
            byte[] bobKeyMaterial;
            {
                byte[] alicePublicDH = await aliceResponse.ReadSizeAndBufferAsync(CancellationToken.None);

                byte[] aliceSignedDH = await aliceResponse.ReadSizeAndBufferAsync(CancellationToken.None);

                var aliceDsa = new ECDsaCng(alicePublic);
                Assert.IsTrue(aliceDsa.VerifyData(alicePublicDH, aliceSignedDH));
                var aliceDHPK = ECDiffieHellmanCngPublicKey.FromByteArray(alicePublicDH, CngKeyBlobFormat.EccPublicBlob);
                bobKeyMaterial = bobDH.DeriveKeyMaterial(aliceDHPK);

                // And Bob reads Alice's secret message.
                using (var aes = SymmetricAlgorithm.Create())
                {
                    using (var decryptor = aes.CreateDecryptor(aliceKeyMaterial, new byte[aes.BlockSize / 8]))
                    {
                        var plaintext = new MemoryStream();
                        var substream = await aliceResponse.ReadSizeAndStreamAsync(CancellationToken.None);

                        using (var cryptoStream = new CryptoStream(substream, decryptor, CryptoStreamMode.Read))
                        {
                            await cryptoStream.CopyToAsync(plaintext);

                            plaintext.Position = 0;
                            byte[] secretMessage = new byte[1024];
                            int    readBytes     = plaintext.Read(secretMessage, 0, secretMessage.Length);
                        }
                    }
                }
            }

            CollectionAssert.AreEqual(aliceKeyMaterial, bobKeyMaterial);
        }
Exemple #28
0
 protected override byte[] ComputeKey(byte[] otherPartyPublicKey)
 {
     return(((ECDiffieHellmanCng)_ecdh).DeriveKeyMaterial(ECDiffieHellmanCngPublicKey.FromByteArray(otherPartyPublicKey, CngKeyBlobFormat.EccPublicBlob)));
 }
Exemple #29
0
 private static ECDiffieHellmanPublicKey GetEcdhKey(byte[] publicKey)
 {
     //see: https://stackoverflow.com/a/22239489/1075882
     return(ECDiffieHellmanCngPublicKey.FromByteArray(publicKey, CngKeyBlobFormat.EccPublicBlob));
 }
Exemple #30
0
        bool IKeyManagementDriver.DeriveKey(int session, int alg, IntPtr pParam, int paramLen, int hBaseKey, out int hKey)
        {
            hKey = -1;

            try
            {
                SessionData ctx = ((SessionDriver)this.Hal.Session).GetSessionCtx(session);
                KeyData     kd  = ctx.ObjectCtx.GetObject(hBaseKey).Data as KeyData;

                if (kd == null)
                {
                    return(false);
                }

                switch ((AlgorithmType)alg)
                {
                case AlgorithmType.ECDH1_DERIVE:

                    ECDH_Params ecdh = new ECDH_Params(pParam, paramLen);

                    ECDiffieHellmanCng ec = kd.KeyCsp as ECDiffieHellmanCng;

                    ECDiffieHellmanCng cng = new ECDiffieHellmanCng(ec.Key);

                    byte[] pubData = new byte[ecdh.PublicData.Length + 8];

                    pubData[0] = (byte)'E';
                    pubData[1] = (byte)'C';
                    pubData[2] = (byte)'K';
                    switch (ec.KeySize)
                    {
                    case 521:
                        pubData[3] = (byte)'5';
                        pubData[4] = (byte)((521 + 7) / 8);
                        break;

                    case 384:
                        pubData[3] = (byte)'3';
                        pubData[4] = (byte)((384 + 7) / 8);
                        break;

                    case 256:
                        pubData[3] = (byte)'1';
                        pubData[4] = (byte)((256 + 7) / 8);
                        break;
                    }
                    pubData[5] = 0;
                    pubData[6] = 0;
                    pubData[7] = 0;

                    Array.Copy(ecdh.PublicData, 0, pubData, 8, ecdh.PublicData.Length);

                    //CngKey otherPublicKey = CngKey.Import(pubData, CngKeyBlobFormat.EccPublicBlob);

                    ECDiffieHellmanPublicKey otherPublicKey = ECDiffieHellmanCngPublicKey.FromByteArray(pubData, CngKeyBlobFormat.EccPublicBlob);


                    //byte[] otherKeyData = otherPublicKey.Export(CngKeyBlobFormat.EccPublicBlob);

                    //Debug.Print(otherKeyData[0].ToString());

                    switch (ecdh.kdf)
                    {
                    case AlgorithmType.NULL_KEY_DERIVATION:
                        cng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
                        cng.HashAlgorithm         = CngAlgorithm.Sha1;
                        break;

                    case AlgorithmType.SHA1_KEY_DERIVATION:
                        cng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
                        cng.HashAlgorithm         = CngAlgorithm.Sha1;
                        break;

                    case AlgorithmType.SHA256_KEY_DERIVATION:
                        cng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
                        cng.HashAlgorithm         = CngAlgorithm.Sha256;
                        break;

                    case AlgorithmType.SHA512_KEY_DERIVATION:
                        cng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
                        cng.HashAlgorithm         = CngAlgorithm.Sha512;
                        break;

                    case AlgorithmType.MD5_KEY_DERIVATION:
                        cng.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
                        cng.HashAlgorithm         = CngAlgorithm.MD5;
                        break;

                    case AlgorithmType.SHA224_HMAC:
                    case AlgorithmType.TLS_MASTER_KEY_DERIVE_DH:
                    default:
                        return(false);
                    }
                    cng.SecretPrepend = null;
                    cng.SecretAppend  = null;

                    byte[] keyData = cng.DeriveKeyMaterial(otherPublicKey);

                    SecretKey key = new SecretKey(keyData.Length * 8, keyData);

                    hKey = ctx.ObjectCtx.AddObject(CryptokiObjectType.Key, new KeyData(keyData, key));

                    break;

                default:
                    return(false);
                }
            }
            catch
            {
                return(false);
            }

            return(true);
        }