예제 #1
0
        /// <summary>
        ///   Validates server acceptance message
        /// </summary>
        /// <remark>
        ///   Here the client verifies that the received message length is 80
        ///   bytes, then opens the encrypted box and verifies that the sent
        ///   message is server's signature to the derived shared secrets. With
        ///   this the handshake concludes.
        /// </remark>
        /// <exception cref="ArgumentException">
        ///   Thrown if the server's Accept <paramref name="msg"/> is not the
        ///   correct size or the signature is not valid.
        /// </exception>
        /// <param name="msg">
        ///   The received message, encrypted server's signature.
        /// </param>
        public void VerifyAccept(byte[] msg)
        {
            if (msg.Length != 80)
            {
                throw new ArgumentException("Incorrect message size");
            }

            var nonce = new byte[NONCE_SIZE];

            nonce.Initialize();

            // Concatenate the network key and derived secrets to obtain
            // the message key
            var key = CryptoHash.Sha256(
                Utils.Concat(_network_key, _shared_ab, _shared_aB, _shared_Ab)
                );

            var opened_msg = SecretBox.Open(msg, nonce, key);

            // Compute the message that it is supposed to be signed with the
            // server's long term key
            var hashed        = CryptoHash.Sha256(_shared_ab);
            var msg_to_verify = Utils.Concat(
                _network_key, detached_signature_A,
                _longterm_client_keypair.PublicKey, hashed
                );

            if (!PublicKeyAuth.VerifyDetached(opened_msg, msg_to_verify, _longterm_server_pk))
            {
                throw new ArgumentException("Invalid signature");
            }
        }
예제 #2
0
        public static void DecryptPacket(Socket socket, ServerState state, byte[] packet)
        {
            var messageId     = BitConverter.ToInt32(new byte[2].Concat(packet.Take(2)).Reverse().ToArray(), 0);
            var payloadLength = BitConverter.ToInt32(new byte[1].Concat(packet.Skip(2).Take(3)).Reverse().ToArray(), 0);
            var unknown       = BitConverter.ToInt32(new byte[2].Concat(packet.Skip(2).Skip(3).Take(2)).Reverse().ToArray(), 0);
            var cipherText    = packet.Skip(2).Skip(3).Skip(2).ToArray();

            byte[] plainText;

            if (messageId == 10100)
            {
                plainText = cipherText;
            }
            else if (messageId == 10101)
            {
                state.clientKey = cipherText.Take(32).ToArray();
                var nonce = GenericHash.Hash(state.clientKey.Concat(state.serverKey.PublicKey).ToArray(), null, 24);
                cipherText              = cipherText.Skip(32).ToArray();
                plainText               = PublicKeyBox.Open(cipherText, nonce, state.serverKey.PrivateKey, state.clientKey);
                state.sessionKey        = plainText.Take(24).ToArray();
                state.clientState.nonce = plainText.Skip(24).Take(24).ToArray();
                plainText               = plainText.Skip(24).Skip(24).ToArray();
            }
            else
            {
                state.clientState.nonce = Utilities.Increment(Utilities.Increment(state.clientState.nonce));
                plainText = SecretBox.Open(new byte[16].Concat(cipherText).ToArray(), state.clientState.nonce,
                                           state.sharedKey);
            }
            Console.WriteLine("[UCR]    {0}" + Environment.NewLine + "{1}", PacketInfos.GetPacketName(messageId),
                              Utilities.BinaryToHex(packet.Take(7).ToArray()) + Utilities.BinaryToHex(plainText));
            ClientCrypto.EncryptPacket(state.clientState.socket, state.clientState, messageId, unknown, plainText);
        }
예제 #3
0
 public void Decrypt()
 {
     try
     {
         if (this.m_vType == 10101)
         {
             byte[] array = this.m_vData;
             this.Client.CPublicKey = array.Take(32).ToArray <byte>();
             this.Client.CSharedKey = this.Client.CPublicKey;
             this.Client.CRNonce    = Client.GenerateSessionKey();
             byte[] nonce = GenericHash.Hash(this.Client.CPublicKey.Concat(Key.Crypto.PublicKey).ToArray <byte>(), null, 24);
             array = array.Skip(32).ToArray <byte>();
             byte[] source = PublicKeyBox.Open(array, nonce, Key.Crypto.PrivateKey, this.Client.CPublicKey);
             this.Client.CSessionKey = source.Take(24).ToArray <byte>();
             this.Client.CSNonce     = source.Skip(24).Take(24).ToArray <byte>();
             this.SetData(source.Skip(24).Skip(24).ToArray <byte>());
         }
         else
         {
             this.Client.CSNonce = Sodium.Utilities.Increment(Sodium.Utilities.Increment(this.Client.CSNonce));
             this.SetData(SecretBox.Open(new byte[16].Concat(this.m_vData).ToArray <byte>(), this.Client.CSNonce, this.Client.CSharedKey));
         }
     }
     catch (Exception)
     {
         this.Client.CState = 0;
     }
 }
예제 #4
0
        public void SecretBox7()
        {
            byte[] k = new byte[SecretBox.KeySize];
            byte[] n = new byte[SecretBox.NonceSize];

            RandomNumberGenerator random = new RNGCryptoServiceProvider();

            int mlen;

            for (mlen = 0; mlen < 1000; ++mlen)
            {
                byte[] m  = new byte[mlen + SecretBox.ZeroSize];
                byte[] c  = new byte[mlen + SecretBox.ZeroSize];
                byte[] m2 = new byte[mlen + SecretBox.ZeroSize];

                random.GetBytes(k);
                random.GetBytes(n);
                random.GetBytes(m);

                Array.Clear(m, 0, SecretBox.ZeroSize);

                SecretBox secretBox = new SecretBox(k);

                secretBox.Box(c, m, n);
                secretBox.Open(m2, c, n);

                int i;
                for (i = 0; i < mlen + SecretBox.ZeroSize; ++i)
                {
                    Assert.AreEqual(m2[i], m[i]);
                }
            }
        }
예제 #5
0
파일: KeyExchange.cs 프로젝트: xiao5gee/C3
        public static byte[] Decrypt(byte[] message, byte[] rxKey)
        {
            var nonce  = message.Take(crypto_secretbox_NONCEBYTES).ToArray();
            var cipher = message.Skip(crypto_secretbox_NONCEBYTES).ToArray();

            return(SecretBox.Open(cipher, nonce, rxKey));
        }
 public void OpenSecretBoxBadNonce()
 {
     SecretBox.Open(
         Utilities.HexToBinary("00000000000000000000000000000000b58d3c3e5ae78770b7db54e29e3885138a2f1ddb738f2309d9b38164"),
         Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVW"),
         Encoding.UTF8.GetBytes("12345678901234567890123456789012"));
 }
예제 #7
0
파일: Message.cs 프로젝트: mugmickey/UCR-1
 public void Decrypt()
 {
     try
     {
         if (m_vType == 10101)
         {
             byte[] cipherText = m_vData;
             Client.CPublicKey = cipherText.Take(32).ToArray();
             Client.CSharedKey = Client.CPublicKey;
             Client.CRNonce    = Client.GenerateSessionKey();
             byte[] nonce = GenericHash.Hash(Client.CPublicKey.Concat(Key.Crypto.PublicKey).ToArray(), null, 24);
             cipherText = cipherText.Skip(32).ToArray();
             var PlainText = PublicKeyBox.Open(cipherText, nonce, Key.Crypto.PrivateKey, Client.CPublicKey);
             Client.CSessionKey = PlainText.Take(24).ToArray();
             Client.CSNonce     = PlainText.Skip(24).Take(24).ToArray();
             SetData(PlainText.Skip(24).Skip(24).ToArray());
         }
         else
         {
             Client.CSNonce = Utilities.Increment(Utilities.Increment(Client.CSNonce));
             SetData(SecretBox.Open(new byte[16].Concat(m_vData).ToArray(), Client.CSNonce, Client.CSharedKey));
         }
     }
     catch (Exception ex)
     {
         Client.CState = 0;
         return;
     }
 }
예제 #8
0
        public static void DecryptPacket(ServerState state, byte[] packet)
        {
            using (var reader = new Reader(packet))
            {
                var ID = reader.ReadUInt16();
                reader.Seek(3, SeekOrigin.Current);
                var Version = reader.ReadUInt16();

                byte[] cipherText = reader.ReadAllBytes, plainText;

                var Name = Packet_Names.GetName(ID);

                switch (ID)
                {
                case 10100:
                {
                    plainText = cipherText;

                    break;
                }

                case 10101:
                {
                    state.ClientKey = cipherText.Take(32).ToArray();

                    var nonce = GenericHash.Hash(state.ClientKey.Concat(state.ServerKey.PublicKey).ToArray(), null,
                                                 24);

                    cipherText = cipherText.Skip(32).ToArray();

                    plainText = PublicKeyBox.Open(cipherText, nonce, state.ServerKey.PrivateKey, state.ClientKey);

                    state.SessionKey        = plainText.Take(24).ToArray();
                    state.ClientState.Nonce = plainText.Skip(24).Take(24).ToArray();

                    plainText = plainText.Skip(24).Skip(24).ToArray();

                    break;
                }

                default:
                {
                    state.ClientState.Nonce = Utilities.Increment(Utilities.Increment(state.ClientState.Nonce));

                    plainText = SecretBox.Open(new byte[16].Concat(cipherText).ToArray(), state.ClientState.Nonce,
                                               state.SharedKey);

                    break;
                }
                }

                ClientCrypto.EncryptPacket(state.ClientState, ID, Version, plainText);

                Console.WriteLine(
                    $"[{DateTime.Now.ToLongTimeString()}, CLIENT, {ID}] {Resources.Definition.Decode(new Reader(plainText), ID)}");

                Logger.Write(BitConverter.ToString(plainText).Replace("-", string.Empty), $"{ID}_{Name}",
                             LogType.PACKET);
            }
        }
예제 #9
0
        public async static Task <byte[]> ReadSecretMessage(Stream s, byte[] key, CancellationToken token = default)
        {
            var read = 0;

            byte[] header = new byte[4 + 24];
            while (read < header.Length)
            {
                read += await s.ReadAsync(header, read, header.Length - read, token);
            }

            var length = BitConverter.ToUInt32(header, 0);

            byte[] nonce = header.Skip(4).ToArray();

            if (length > MaxMessageLen)
            {
                throw new ArgumentOutOfRangeException($"Encrypted message specified a size of {length}, which is greater than the limit of {MaxMessageLen}");
            }

            byte[] ciphertext = new byte[length];
            read = 0;
            while (read < ciphertext.Length)
            {
                read += await s.ReadAsync(ciphertext, read, ciphertext.Length - read, token);
            }

            return(SecretBox.Open(ciphertext, nonce, key));
        }
예제 #10
0
 private static byte[] DecryptSecretSeed(byte[] seedBytes, byte[] keyHash)
 {
     byte[] nonceBytes  = new byte[24];
     byte[] cipherBytes = new byte[seedBytes.Length - nonceBytes.Length];
     Array.Copy(seedBytes, 0, nonceBytes, 0, nonceBytes.Length);
     Array.Copy(seedBytes, nonceBytes.Length, cipherBytes, 0, cipherBytes.Length);
     return(SecretBox.Open(cipherBytes, nonceBytes, keyHash));
 }
예제 #11
0
    static string SecretboxDecryptionFromBase64(string keyBase64, string ciphertextReceivedBase64)
    {
        String[] parts      = ciphertextReceivedBase64.Split(':');
        byte[]   nonce      = Base64Decoding(parts[0]);
        byte[]   ciphertext = Base64Decoding(parts[1]);
        var      decrypted  = SecretBox.Open(ciphertext, nonce, Base64Decoding(keyBase64));

        return(System.Text.Encoding.UTF8.GetString(decrypted, 0, decrypted.Length));
    }
예제 #12
0
        /// <summary>
        /// Decrypts the Data into a byte[]
        /// </summary>
        /// <param name="locked">locked Data to be decrypted</param>
        public byte[] UnlockBytes(ILocked locked)
        {
            if (locked == null)
            {
                throw new ArgumentNullException(nameof(locked));
            }

            return(SecretBox.Open(locked.Ciphertext, locked.Nonce.Bytes, key.Bytes));
        }
예제 #13
0
 public void OpenSecretBoxBadKey()
 {
     Assert.Throws <KeyOutOfRangeException>(() =>
     {
         SecretBox.Open(
             Utilities.HexToBinary("00000000000000000000000000000000b58d3c3e5ae78770b7db54e29e3885138a2f1ddb738f2309d9b38164"),
             Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVWX"),
             Encoding.UTF8.GetBytes("123456789012345678901234567890"));
     });
 }
예제 #14
0
        public void OpenSecretBox()
        {
            const string EXPECTED = "Adam Caudill";
            var          actual   = Encoding.UTF8.GetString(SecretBox.Open(
                                                                Utilities.HexToBinary("00000000000000000000000000000000b58d3c3e5ae78770b7db54e29e3885138a2f1ddb738f2309d9b38164"),
                                                                Encoding.UTF8.GetBytes("ABCDEFGHIJKLMNOPQRSTUVWX"),
                                                                Encoding.UTF8.GetBytes("12345678901234567890123456789012")));

            Assert.AreEqual(EXPECTED, actual);
        }
예제 #15
0
        public string Decrypt(string cipher, byte[] key)
        {
            byte[] cipherBytes  = Utilities.HexToBinary(cipher);
            var    nonce        = cipherBytes.Take(24).ToArray();
            var    messageBytes = cipherBytes.Skip(24).ToArray();
            var    message      = Utilities.BinaryToHex(messageBytes);

            var secret        = SecretBox.Open(messageBytes, nonce, key);
            var secretMessage = Encoding.UTF8.GetString(secret);

            return(secretMessage);
        }
        public void SecretBoxOpenWithGeneratedDataTest()
        {
            var    key     = SecretBox.GenerateKey();
            var    nonce   = SecretBox.GenerateNonce();
            String message = "Hello, World!";

            byte[] plainText  = System.Text.Encoding.UTF8.GetBytes(message);
            byte[] cipherText = SecretBox.Create(plainText, nonce, key);
            byte[] decrypted  = SecretBox.Open(cipherText, nonce, key);

            Assert.AreEqual(plainText.ToString(), decrypted.ToString());
        }
예제 #17
0
        public static byte[] Decrypt(byte[] Payload, KeyPair keyPair)
        {
            ushort Id;
            int    Length;
            ushort Version;

            using (Reader reader = new Reader(Payload))
            {
                Id      = reader.ReadUInt16();
                Length  = reader.ReadInt24();
                Version = reader.ReadUInt16();
                Payload = Payload.Skip(2).Skip(3).Skip(2).ToArray();
            }
            if (!Form1.Config.UseRC4)
            {
                switch (Id)
                {
                case 20100:
                    decryptedPayload = Payload;
                    break;

                case 20103:
                    decryptedPayload = Payload;
                    break;

                case 20104:
                    ClientConfig.ServerNonce = GenericHash.Hash(ClientConfig.SNonce.Concat(keyPair.PublicKey).Concat(Keys.ServerKey).ToArray(), null, 24);
                    decryptedPayload         = PublicKeyBox.Open(Payload, ClientConfig.ServerNonce, keyPair.PrivateKey, Keys.ServerKey);
                    ClientConfig.RNonce      = decryptedPayload.Take(24).ToArray();
                    ClientConfig.SharedKey   = decryptedPayload.Skip(24).Take(32).ToArray();
                    decryptedPayload         = decryptedPayload.Skip(24).Skip(32).ToArray();
                    break;

                default:
                    ClientConfig.RNonce = Utilities.Increment(Utilities.Increment(ClientConfig.RNonce));
                    byte[] toDecrypt = new byte[16].Concat(Payload).ToArray();
                    decryptedPayload = SecretBox.Open(toDecrypt, ClientConfig.RNonce, ClientConfig.SharedKey);
                    Logger.Write(Encoding.UTF8.GetString(decryptedPayload), "Decrypted OHD");
                    break;
                }
            }
            else if (Form1.Config.UseRC4)
            {
                decryptedPayload = RC4.Decrypt(Payload);
            }
            else
            {
            }
            return(decryptedPayload);
        }
예제 #18
0
        /// <summary>
        ///   Checks for <paramref name="msg"/> length and validity, extracting
        ///   the client's long term public key upon success.
        /// </summary>
        /// <param name="msg">Client authenticate message</param>
        /// <exception cref="ArgumentException">
        ///   Thrown if the client Auth <paramref name="msg"/> fails to pass the
        ///   checks.
        /// </exception>
        public void AcceptAuth(byte[] msg)
        {
            if (msg.Length != 112)
            {
                throw new ArgumentException("Incorrect secretbox length");
            }

            // A nonce consisting of 24 zeros
            var nonce = new byte[NONCE_SIZE];

            nonce.Initialize();

            // Calculate the decryption key from the dervided keys
            var key = CryptoHash.Sha256(
                Utils.Concat(_network_key, _shared_ab, _shared_aB)
                );

            var opened_msg = SecretBox.Open(msg, nonce, key);

            if (opened_msg.Length != 96)
            {
                throw new ArgumentException("Invalid size of opened message");
            }

            // Extract the signature of the long term client's public key
            // signed with the derived secret
            var detached_signature = new byte[SIG_SIZE];

            Buffer.BlockCopy(opened_msg, 0, detached_signature, 0, SIG_SIZE);

            // Extract the long term client's public key
            var lt_cli_pk = new byte[PUB_KEY_SIZE];

            Buffer.BlockCopy(opened_msg, SIG_SIZE, lt_cli_pk, 0, PUB_KEY_SIZE);

            var shared_hashed = CryptoHash.Sha256(_shared_ab);
            // Concat network_key, server longterm pk and sha256 hashed shared_ab secret
            var to_verify = Utils.Concat(
                _network_key, _longterm_server_keypair.PublicKey, shared_hashed
                );

            if (!PublicKeyAuth.VerifyDetached(detached_signature, to_verify, lt_cli_pk))
            {
                throw new ArgumentException("Signature does not match");
            }

            detached_signature_A = detached_signature;
            _longterm_client_pk  = lt_cli_pk;
            this.DeriveAb();
        }
예제 #19
0
        public void Decrypt()
        {
            var Message = Encoding.ASCII.GetBytes("Hello World");

            var Key = SodiumCore.GetRandomBytes(32);

            var Nonce = SodiumCore.GetRandomBytes(24);

            var CipherText = SecretBox.Create(Message, Nonce, Key);

            var PlainText = SecretBox.Open(CipherText, Nonce, Key);

            Assert.AreEqual(Encoding.ASCII.GetString(Message), Encoding.ASCII.GetString(PlainText));
        }
예제 #20
0
        /// <summary>
        /// MultiboxOpenBody
        /// </summary>
        /// <param name="cypherText"></param>
        /// <param name="length_and_key"></param>
        /// <returns></returns>
        public static byte[] MultiboxOpenBody(byte[] cypherText, byte[] length_and_key)
        {
            if (length_and_key == null)
            {
                return(null);
            }
            var key    = SubArray(length_and_key, 1, length_and_key.Length - 1);
            var length = length_and_key[0];
            var start  = 24 + 32;
            var size   = 32 + 1 + 16;
            var nonce  = SubArray(cypherText, 0, 24);

            return(SecretBox.Open(SubArray(cypherText, start + length * size, cypherText.Length - (start + length * size)), nonce, key));
        }
예제 #21
0
        public void SecretBox8()
        {
            byte[] k = new byte[SecretBox.KeySize];
            byte[] n = new byte[SecretBox.NonceSize];

            RandomNumberGenerator cryptoRandom = new RNGCryptoServiceProvider();
            Random random = new Random();

            int mlen;

            for (mlen = 0; mlen < 1000; ++mlen)
            {
                byte[] m  = new byte[mlen + SecretBox.ZeroSize];
                byte[] c  = new byte[mlen + SecretBox.ZeroSize];
                byte[] m2 = new byte[mlen + SecretBox.ZeroSize];

                cryptoRandom.GetBytes(k);
                cryptoRandom.GetBytes(n);
                cryptoRandom.GetBytes(m);
                Array.Clear(m, 0, SecretBox.ZeroSize);

                SecretBox secretBox = new SecretBox(k);

                secretBox.Box(c, m, n);

                int caught = 0;
                while (caught < 10)
                {
                    c[random.Next(0, mlen + SecretBox.ZeroSize)] = (byte)(random.Next() % 255);

                    try
                    {
                        secretBox.Open(m2, c, n);

                        int i;
                        for (i = 0; i < mlen + SecretBox.ZeroSize; ++i)
                        {
                            Assert.AreEqual(m2[i], m[i]);
                        }
                    }
                    catch (SecurityException ex)
                    {
                        caught++;
                    }
                }
            }
        }
        public void SecretBoxOpenTest()
        {
            var key   = "7IygDz/Hy8LC/wqXb6vsrpq7Vyn7mxCoh8nYOn5yVXc=";
            var nonce = "bUBIsnfvIv2Wo95SEkt4DIvBqZLGGBjV";

            byte[] message = System.Text.Encoding.UTF8.GetBytes("Hello, World!");

            String cipherText = "cZFTGV7SrPeSdX5Q6b30PBEm5Y2uby/W5BSrrfU=";

            byte[] cipherTextBytes = Convert.FromBase64String(cipherText);

            byte[] bitKey    = Convert.FromBase64String(key);
            byte[] bitNonce  = Convert.FromBase64String(nonce);
            byte[] plainText = SecretBox.Open(cipherTextBytes, bitNonce, bitKey);

            Assert.AreEqual(message.ToString(), plainText.ToString());
        }
예제 #23
0
        public static byte[] Decrypt(byte[] encrypted)
        {
            byte[] decrypted;
            ushort id;
            int    length;
            ushort version;

            using (var reader = new Reader(encrypted))
            {
                id      = reader.ReadUInt16();
                length  = reader.ReadInt24();
                version = reader.ReadUInt16();
            }
            encrypted = encrypted.Skip(2).Skip(3).Skip(2).ToArray();
            switch (id)
            {
            case 10100:
                decrypted = encrypted;
                break;

            case 10101:
                ServerConfig.clientPublicKey = encrypted.Take(32).ToArray();
                encrypted = encrypted.Skip(32).ToArray();
                ServerConfig.clientSharedKey = ServerConfig.clientPublicKey;
                ServerConfig.clientRNonce    = Utils.GenerateRandomBytes(24);
                byte[] nonce = GenericHash.Hash(ServerConfig.clientPublicKey.Concat(Keys.ServerKey).ToArray(), null, 24);
                decrypted = PublicKeyBox.Open(encrypted, nonce, ServerConfig.privateKey, ServerConfig.clientPublicKey);
                ServerConfig.clientSessionKey = decrypted.Take(24).ToArray();
                ServerConfig.clientSNonce     = decrypted.Skip(24).Take(24).ToArray();
                ServerConfig.clientSNonce     = ServerConfig.clientSNonce;
                decrypted = decrypted.Skip(24).Skip(24).ToArray();
                Console.WriteLine(BitConverter.ToString(ServerConfig.clientSNonce).Replace("-", ""));
                Console.WriteLine(BitConverter.ToString(ServerConfig.clientSessionKey).Replace("-", ""));
                Console.WriteLine(BitConverter.ToString(nonce).Replace("-", ""));
                Console.WriteLine(BitConverter.ToString(ServerConfig.clientPublicKey).Replace("-", ""));
                break;

            default:
                ServerConfig.clientSNonce = Utilities.Increment(Utilities.Increment(ServerConfig.clientSNonce));
                decrypted = SecretBox.Open(new byte[16].Concat(encrypted).ToArray(), ServerConfig.clientSNonce, ServerConfig.clientSharedKey);
                break;
            }
            return(decrypted);
        }
예제 #24
0
        public static void DecryptPacket(Socket socket, ServerState state, byte[] packet)
        {
            int messageId     = BitConverter.ToInt32(new byte[2].Concat(packet.Take(2)).Reverse().ToArray(), 0);
            int payloadLength = BitConverter.ToInt32(new byte[1].Concat(packet.Skip(2).Take(3)).Reverse().ToArray(), 0);
            int unknown       = BitConverter.ToInt32(new byte[2].Concat(packet.Skip(2).Skip(3).Take(2)).Reverse().ToArray(), 0);

            byte[] cipherText = packet.Skip(2).Skip(3).Skip(2).ToArray();
            byte[] plainText;

            if (messageId == 10100)
            {
                plainText = cipherText;
            }
            else if (messageId == 10101)
            {
                state.clientKey = cipherText.Take(32).ToArray();
                byte[] nonce = GenericHash.Hash(state.clientKey.Concat(state.serverKey.PublicKey).ToArray(), null, 24);
                cipherText              = cipherText.Skip(32).ToArray();
                plainText               = PublicKeyBox.Open(cipherText, nonce, state.serverKey.PrivateKey, state.clientKey);
                state.sessionKey        = plainText.Take(24).ToArray();
                state.clientState.nonce = plainText.Skip(24).Take(24).ToArray();
                plainText               = plainText.Skip(24).Skip(24).ToArray();
            }
            else
            {
                state.clientState.nonce = Utilities.Increment(Utilities.Increment(state.clientState.nonce));
                plainText = SecretBox.Open(new byte[16].Concat(cipherText).ToArray(), state.clientState.nonce, state.sharedKey);
            }

            try
            {
                JObject decoded = state.decoder.decode(messageId, 0, plainText);
                var     msg     = new Message(messageId, "[C > S] " + decoded["name"], plainText, unknown, state, decoded["fields"].ToString());
                MainWindow.Context.AddMessageToQueueLog(msg);
            }
            catch (Exception)
            {
                var msg = new Message(messageId, "[C > S] " + "Undefined", plainText, unknown, state, "");
                MainWindow.Context.AddMessageToQueueLog(msg);
            }


            ClientCrypto.EncryptPacket(state.clientState.socket, state.clientState, messageId, unknown, plainText);
        }
예제 #25
0
        public byte[] RecoverPrivateKey(string argon2mode, string walletPassword)
        {
            try
            {
                byte[] salt = Hex.Decode(Crypto.KdfParams.Salt);

                Argon2 arg = Utils.Crypto.GetArgon2FromType(argon2mode, walletPassword);
                //mpiva get from wallet not from config
                arg.DegreeOfParallelism = Crypto.KdfParams.Parallelism; //_config.Parallelism;
                arg.Iterations          = Crypto.KdfParams.OpsLimit;    //_config.OpsLimit;
                arg.MemorySize          = Crypto.KdfParams.MemLimitKib; //_config.MemLimitKIB;
                arg.Salt = salt;
                byte[] rawHash = arg.GetBytes(32);
                // extract nonce
                byte[] nonce = Hex.Decode(Crypto.CipherParams.Nonce);

                // extract cipertext
                byte[] ciphertext = Hex.Decode(Crypto.CipherText);

                // recover private key
                byte[] decrypted = null;
                try
                {
                    decrypted = SecretBox.Open(ciphertext, nonce, rawHash);
                }
                // ReSharper disable once EmptyGeneralCatchClause
                catch
                {
                }

                if (decrypted == null)
                {
                    throw new AException("Error recovering privateKey: wrong password.");
                }
                return(decrypted);
            }
            catch (Exception e)
            {
                throw new AException("Error recovering privateKey: wrong password.", e);
            }
        }
예제 #26
0
        /// <summary>
        ///   Asynchronously reads a message from the stream.
        /// </summary>
        /// <returns>An array with the decrypted message</returns>
        /// <param name="msg">A stream with incoming messages</param>
        public async Task <byte[]> Unbox(Stream msg)
        {
            var enc_header = new byte[HEAD_LEN];
            await msg.ReadAsync(enc_header, 0, HEAD_LEN);

            var header     = SecretBox.Open(enc_header, nonce, key);
            var length_buf = header.Take(2).ToArray();

            if (BitConverter.IsLittleEndian)
            {
                Array.Reverse(length_buf);
            }
            var length = BitConverter.ToUInt16(length_buf, 0);

            var boxed_body = new byte[length];
            await msg.ReadAsync(boxed_body, 0, length);

            var to_unbox = Utils.Concat(header.Skip(2).ToArray(), boxed_body);

            return(SecretBox.Open(to_unbox, nonce, key));
        }
        public static void DecryptPacket(Socket socket, ServerState state, byte[] packet)
        {
            int messageId     = BitConverter.ToInt32(new byte[2].Concat(packet.Take(2)).Reverse().ToArray(), 0);
            int payloadLength = BitConverter.ToInt32(new byte[1].Concat(packet.Skip(2).Take(3)).Reverse().ToArray(), 0);
            int unknown       = BitConverter.ToInt32(new byte[2].Concat(packet.Skip(2).Skip(3).Take(2)).Reverse().ToArray(), 0);

            byte[] cipherText = packet.Skip(2).Skip(3).Skip(2).ToArray();
            byte[] plainText;

            if (messageId == 10100)
            {
                plainText = cipherText;
            }
            else if (messageId == 10101)
            {
                state.clientKey = cipherText.Take(32).ToArray();
                byte[] nonce = GenericHash.Hash(state.clientKey.Concat(state.serverKey.PublicKey).ToArray(), null, 24);
                cipherText              = cipherText.Skip(32).ToArray();
                plainText               = PublicKeyBox.Open(cipherText, nonce, state.serverKey.PrivateKey, state.clientKey);
                state.sessionKey        = plainText.Take(24).ToArray();
                state.clientState.nonce = plainText.Skip(24).Take(24).ToArray();
                plainText               = plainText.Skip(24).Skip(24).ToArray();
            }
            else
            {
                state.clientState.nonce = Utilities.Increment(Utilities.Increment(state.clientState.nonce));
                plainText = SecretBox.Open(new byte[16].Concat(cipherText).ToArray(), state.clientState.nonce, state.sharedKey);
            }
            try
            {
                JObject decoded = state.decoder.decode(messageId, unknown, plainText);
                Console.WriteLine("{0}: {1}", decoded["name"], decoded["fields"]);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine("{0} {1}", messageId, Utilities.BinaryToHex(BitConverter.GetBytes(messageId).Reverse().Skip(2).Concat(BitConverter.GetBytes(plainText.Length).Reverse().Skip(1)).Concat(BitConverter.GetBytes(unknown).Reverse().Skip(2)).Concat(plainText).ToArray()));
            }
            ClientCrypto.EncryptPacket(state.clientState.socket, state.clientState, messageId, unknown, plainText);
        }
예제 #28
0
        public void LoadPrivateKey(SecureString password, bool save = true, string path = null)
        {
            if (string.IsNullOrEmpty(path))
            {
                path = (Environment.OSVersion.Platform == PlatformID.Unix) ?
                       Environment.GetEnvironmentVariable("HOME") :
                       Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");
                path += "/.cryptchat/" + Base32.ToBase32String(GenericHash.Hash(Encoding.ASCII.GetBytes(Username), null, 16)) + "/.pem";
            }

            if (!File.Exists(path))
            {
                Console.WriteLine("Generating keypair");
                using (KeyPair kp = Security.Boxes.Asymmetric.GenerateKeyPair())
                {
                    Console.WriteLine("Store PrivateKey as mem-locked Base64 string");
                    PrivateKey = Convert.ToBase64String(kp.PrivateKey);
                    Console.WriteLine("Store PublicKey as Base64 string");
                    PublicKey = Convert.ToBase64String(kp.PublicKey);
                    if (save)
                    {
                        SavePrivateKey(password);
                    }
                }
            }

            else
            {
                var cipher_file = File.ReadAllBytes(path);
                PrivateKey = Convert.ToBase64String(SecretBox.Open(cipher_file,
                                                                   GenericHash.Hash(Encoding.ASCII.GetBytes(Id), null, 24),
                                                                   GenericHash.Hash(Encoding.ASCII.GetBytes(password), null, 32)));
                using (var kpair = PublicKeyBox.GenerateKeyPair(Convert.FromBase64String(PrivateKey.ToString())))
                {
                    PublicKey = Convert.ToBase64String(kpair.PublicKey);
                }
            }
        }
예제 #29
0
파일: Boxes.cs 프로젝트: zevaryx/cryptchat
        public static string Decrypt(string crypt, string secretKey, string nonce)
        {
            byte[] secret_bytes;
            byte[] nonce_bytes;
            byte[] crypt_bytes;

            if (Utils.IsBase64(nonce))
            {
                nonce_bytes = Convert.FromBase64String(nonce);
            }
            else
            {
                throw new ArgumentException($"{nameof(nonce)} must be a Base64-encoded string");
            }

            if (Utils.IsBase64(crypt))
            {
                crypt_bytes = Convert.FromBase64String(crypt);
            }
            else
            {
                throw new ArgumentException($"{nameof(crypt)} must be a Base64-encoded string");
            }

            if (!Utils.IsBase64(secretKey))
            {
                secret_bytes = Encoding.ASCII.GetBytes(secretKey);
            }
            else
            {
                secret_bytes = Convert.FromBase64String(secretKey);
            }

            var plaintext = SecretBox.Open(crypt_bytes, nonce_bytes, secret_bytes);

            return(Encoding.UTF8.GetString(plaintext));
        }
예제 #30
0
        /// <summary>
        /// MultiboxOpenKey
        /// </summary>
        /// <param name="cypherText"></param>
        /// <param name="secretKey"></param>
        /// <param name="maxRecipients"></param>
        /// <returns>return null if secretKey is not valid</returns>
        public static byte[] MultiboxOpenKey(byte[] cypherText, byte[] secretKey, int maxRecipients = DEFAULT_MAX)
        {
            if (maxRecipients < 1 || maxRecipients > 255)
            {
                throw new ArgumentOutOfRangeException("max recipients must be between 1 and 255.");
            }

            var nonce      = SubArray(cypherText, 0, 24);
            var onetime_pk = SubArray(cypherText, 24, 32);
            var my_key     = ScalarMult.Mult(secretKey, onetime_pk);
            var start      = 24 + 32;
            var size       = 32 + 1 + 16;

            for (var i = 0; i <= maxRecipients; i++)
            {
                var s = start + size * i;

                if (s + size > (cypherText.Length - 16))
                {
                    return(null);
                }

                try
                {
                    var length_and_key = SecretBox.Open(SubArray(cypherText, s, size), nonce, my_key);

                    if (length_and_key != null)
                    {
                        return(length_and_key);
                    }
                }
                catch (System.Security.Cryptography.CryptographicException) { }
                catch (Exception ex) { System.Diagnostics.Trace.WriteLine(ex.Message); }
            }

            return(null);
        }