Exemplo n.º 1
0
        public void TestMd5()
        {
            var buff    = Encoding.UTF8.GetBytes(@"密码");
            var md5Sum  = MbedTLS.MD5(buff);
            var md5Hash = MD5.Create().ComputeHash(buff);

            Assert.IsTrue(md5Hash.SequenceEqual(md5Sum));
        }
Exemplo n.º 2
0
        protected override void initCipher(byte[] iv, bool isCipher)
        {
            base.initCipher(iv, isCipher);

            var cipherInfo = OpenSSL.GetCipherInfo(_innerLibName);

            if (cipherInfo == IntPtr.Zero)
            {
                throw new Exception("openssl: cipher not found");
            }
            var ctx = OpenSSL.EVP_CIPHER_CTX_new();

            if (ctx == IntPtr.Zero)
            {
                throw new Exception("fail to create ctx");
            }

            if (isCipher)
            {
                _encryptCtx = ctx;
            }
            else
            {
                _decryptCtx = ctx;
            }

            byte[] realKey;
            if (_method.StartsWith(@"rc4-md5"))
            {
                var temp = new byte[keyLen + ivLen];
                Array.Copy(_key, 0, temp, 0, keyLen);
                Array.Copy(iv, 0, temp, keyLen, ivLen);
                realKey = MbedTLS.MD5(temp);
            }
            else
            {
                realKey = _key;
            }

            var ret = OpenSSL.EVP_CipherInit_ex(ctx, cipherInfo, IntPtr.Zero, null, null, isCipher ? OpenSSL.OPENSSL_ENCRYPT : OpenSSL.OPENSSL_DECRYPT);

            if (ret != 1)
            {
                throw new Exception("openssl: fail to set key length");
            }
            ret = OpenSSL.EVP_CIPHER_CTX_set_key_length(ctx, keyLen);
            if (ret != 1)
            {
                throw new Exception("openssl: fail to set key length");
            }
            ret = OpenSSL.EVP_CipherInit_ex(ctx, IntPtr.Zero, IntPtr.Zero, realKey, _method == "rc4-md5" ? null : iv, isCipher ? OpenSSL.OPENSSL_ENCRYPT : OpenSSL.OPENSSL_DECRYPT);
            if (ret != 1)
            {
                throw new Exception("openssl: cannot set key and iv");
            }
            OpenSSL.EVP_CIPHER_CTX_set_padding(ctx, 0);
        }
Exemplo n.º 3
0
        protected override void initCipher(byte[] iv, bool isCipher)
        {
            base.initCipher(iv, isCipher);
            IntPtr ctx = Marshal.AllocHGlobal(MbedTLS.cipher_get_size_ex());

            if (isCipher)
            {
                _encryptCtx = ctx;
            }
            else
            {
                _decryptCtx = ctx;
            }
            byte[] realkey;
            if (_method.StartsWith("rc4-"))
            {
                byte[] temp = new byte[keyLen + ivLen];
                realkey = new byte[keyLen];
                Array.Copy(_key, 0, temp, 0, keyLen);
                Array.Copy(iv, 0, temp, keyLen, ivLen);
                realkey = MbedTLS.MD5(temp);
            }
            else
            {
                realkey = _key;
            }
            MbedTLS.cipher_init(ctx);
            if (MbedTLS.cipher_setup(ctx, MbedTLS.cipher_info_from_string(getInfo().name)) != 0)
            {
                throw new Exception("Cannot initialize mbed TLS cipher context");
            }

            /*
             * MbedTLS takes key length by bit
             * cipher_setkey() will set the correct key schedule
             * and operation
             *
             *  MBEDTLS_AES_{EN,DE}CRYPT
             *  == MBEDTLS_BLOWFISH_{EN,DE}CRYPT
             *  == MBEDTLS_CAMELLIA_{EN,DE}CRYPT
             *  == MBEDTLS_{EN,DE}CRYPT
             *
             */
            if (MbedTLS.cipher_setkey(ctx, realkey, keyLen * 8,
                                      isCipher ? MbedTLS.MBEDTLS_ENCRYPT : MbedTLS.MBEDTLS_DECRYPT) != 0)
            {
                throw new Exception("Cannot set mbed TLS cipher key");
            }
            if (MbedTLS.cipher_set_iv(ctx, iv, ivLen) != 0)
            {
                throw new Exception("Cannot set mbed TLS cipher IV");
            }
            if (MbedTLS.cipher_reset(ctx) != 0)
            {
                throw new Exception("Cannot finalize mbed TLS cipher context");
            }
        }
Exemplo n.º 4
0
        public void DeriveSessionKey(byte[] salt, byte[] masterKey, byte[] sessionKey)
        {
            int ret = MbedTLS.hkdf(salt, saltLen, masterKey, keyLen, InfoBytes, InfoBytes.Length, sessionKey,
                                   keyLen);

            if (ret != 0)
            {
                throw new System.Exception("failed to generate session key");
            }
        }
Exemplo n.º 5
0
 public void TestMD5()
 {
     for (int len = 1; len < 64; len++)
     {
         System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();
         byte[] bytes = new byte[len];
         _random.NextBytes(bytes);
         string md5str  = Convert.ToBase64String(md5.ComputeHash(bytes));
         string md5str2 = Convert.ToBase64String(MbedTLS.MD5(bytes));
         Assert.IsTrue(md5str == md5str2);
     }
 }
Exemplo n.º 6
0
 protected override void cipherUpdate(bool isCipher, int length, byte[] buf, byte[] outbuf)
 {
     // C# could be multi-threaded
     if (_disposed)
     {
         throw new ObjectDisposedException(ToString());
     }
     if (MbedTLS.cipher_update(isCipher ? _encryptCtx : _decryptCtx, buf, length, outbuf, ref length) != 0)
     {
         throw new Exception("Cannot update mbed TLS cipher context");
     }
 }
Exemplo n.º 7
0
 protected override void cipherUpdate(bool isEncrypt, int length, byte[] buf, byte[] outbuf)
 {
     // C# could be multi-threaded
     if (_disposed)
     {
         throw new ObjectDisposedException(this.ToString());
     }
     if (MbedTLS.cipher_update(isEncrypt ? _encryptCtx : _decryptCtx,
                               buf, length, outbuf, ref length) != 0)
     {
         throw new CryptoErrorException();
     }
 }
Exemplo n.º 8
0
        // UDP: master key
        // TCP: session key
        private void CipherSetKey(bool isEncrypt, byte[] key)
        {
            IntPtr ctx = isEncrypt ? _encryptCtx : _decryptCtx;
            int    ret = MbedTLS.cipher_setkey(ctx, key, keyLen * 8, isEncrypt ? MbedTLS.MBEDTLS_ENCRYPT : MbedTLS.MBEDTLS_DECRYPT);

            if (ret != 0)
            {
                throw new System.Exception("failed to set key");
            }
            ret = MbedTLS.cipher_reset(ctx);
            if (ret != 0)
            {
                throw new System.Exception("failed to finish preparation");
            }
        }
Exemplo n.º 9
0
        public override byte[] ClientUdpPreEncrypt(byte[] plaindata, int datalength, out int outlength)
        {
            byte[] outdata = new byte[datalength + 1024];
            if (user_key == null)
            {
                user_id = new byte[4];
                int index_of_split = Server.param.IndexOf(':');
                if (index_of_split > 0)
                {
                    try
                    {
                        uint user = uint.Parse(Server.param.Substring(0, index_of_split));
                        user_key = System.Text.Encoding.UTF8.GetBytes(Server.param.Substring(index_of_split + 1));
                        BitConverter.GetBytes(user).CopyTo(user_id, 0);
                    }
                    catch (Exception ex)
                    {
                        Logging.Log(LogLevel.Warn, $"Faild to parse auth param, fallback to basic mode. {ex}");
                    }
                }
                if (user_key == null)
                {
                    random.NextBytes(user_id);
                    user_key = Server.key;
                }
            }
            byte[] auth_data = new byte[3];
            random.NextBytes(auth_data);

            byte[] md5data  = MbedTLS.ComputeHash(Server.key, auth_data, 0, auth_data.Length);
            int    rand_len = UdpGetRandLen(random_client, md5data);

            byte[] rand_data = new byte[rand_len];
            random.NextBytes(rand_data);
            outlength = datalength + rand_len + 8;
            encryptor = EncryptorFactory.GetEncryptor("rc4", Convert.ToBase64String(user_key) + Convert.ToBase64String(md5data, 0, 16));
            encryptor.Encrypt(plaindata, datalength, outdata, out datalength);
            rand_data.CopyTo(outdata, datalength);
            auth_data.CopyTo(outdata, outlength - 8);
            byte[] uid = new byte[4];
            for (int i = 0; i < 4; ++i)
            {
                uid[i] = (byte)(user_id[i] ^ md5data[i]);
            }
            uid.CopyTo(outdata, outlength - 5);
            md5data = MbedTLS.ComputeHash(user_key, outdata, 0, outlength - 1);
            return(outdata);
        }
Exemplo n.º 10
0
        public void PackData(byte[] data, int datalength, byte[] outdata, out int outlength)
        {
            int rand_len = GetRandLen(datalength);

            outlength  = rand_len + datalength + 2;
            outdata[0] = (byte)(datalength ^ last_client_hash[14]);
            outdata[1] = (byte)((datalength >> 8) ^ last_client_hash[15]);
            {
                byte[] rnd_data = new byte[rand_len];
                random.NextBytes(rnd_data);
                encryptor.Encrypt(data, datalength, data, out datalength);
                if (datalength > 0)
                {
                    if (rand_len > 0)
                    {
                        int start_pos = GetRandStartPos(rand_len, random_client);
                        Array.Copy(data, 0, outdata, 2 + start_pos, datalength);
                        Array.Copy(rnd_data, 0, outdata, 2, start_pos);
                        Array.Copy(rnd_data, start_pos, outdata, 2 + start_pos + datalength, rand_len - start_pos);
                    }
                    else
                    {
                        Array.Copy(data, 0, outdata, 2, datalength);
                    }
                }
                else
                {
                    rnd_data.CopyTo(outdata, 2);
                }
            }

            byte[] key = new byte[user_key.Length + 4];
            user_key.CopyTo(key, 0);
            BitConverter.GetBytes(pack_id).CopyTo(key, key.Length - 4);
            ++pack_id;

            byte[] md5data = MbedTLS.ComputeHash(key, outdata, 0, outlength);
            last_client_hash = md5data;
            Array.Copy(md5data, 0, outdata, outlength, 2);
            outlength += 2;
        }
Exemplo n.º 11
0
        public override byte[] ClientUdpPostDecrypt(byte[] plaindata, int datalength, out int outlength)
        {
            if (datalength <= 8)
            {
                outlength = 0;
                return(plaindata);
            }
            byte[] md5data = MbedTLS.ComputeHash(user_key, plaindata, 0, datalength - 1);
            if (md5data[0] != plaindata[datalength - 1])
            {
                outlength = 0;
                return(plaindata);
            }
            md5data = MbedTLS.ComputeHash(Server.key, plaindata, datalength - 8, 7);
            int rand_len = UdpGetRandLen(random_server, md5data);

            outlength = datalength - rand_len - 8;
            encryptor = EncryptorFactory.GetEncryptor("rc4", Convert.ToBase64String(user_key) + Convert.ToBase64String(md5data, 0, 16));
            encryptor.Decrypt(plaindata, outlength, plaindata, out outlength);
            return(plaindata);
        }
        public static void LegacyDeriveKey(byte[] password, byte[] key, int keylen)
        {
            byte[] result = new byte[password.Length + MD5_LEN];
            int    i      = 0;

            byte[] md5sum = null;
            while (i < keylen)
            {
                if (i == 0)
                {
                    md5sum = MbedTLS.MD5(password);
                }
                else
                {
                    Array.Copy(md5sum, 0, result, 0, MD5_LEN);
                    Array.Copy(password, 0, result, MD5_LEN, password.Length);
                    md5sum = MbedTLS.MD5(result);
                }
                Array.Copy(md5sum, 0, key, i, Math.Min(MD5_LEN, keylen - i));
                i += MD5_LEN;
            }
        }
        public static void LegacyDeriveKey(byte[] password, byte[] key)
        {
            byte[] result = new byte[password.Length + 16];
            int    i      = 0;

            byte[] md5sum = null;
            while (i < key.Length)
            {
                if (i == 0)
                {
                    md5sum = MbedTLS.MD5(password);
                }
                else
                {
                    md5sum.CopyTo(result, 0);
                    password.CopyTo(result, md5sum.Length);
                    md5sum = MbedTLS.MD5(result);
                }
                md5sum.CopyTo(key, i);
                i += md5sum.Length;
            }
        }
Exemplo n.º 14
0
        public static void bytesToKey(byte[] password, byte[] key)
        {
            var result = new byte[password.Length + 16];
            var i      = 0;

            byte[] md5Sum = null;
            while (i < key.Length)
            {
                if (i == 0)
                {
                    md5Sum = MbedTLS.MD5(password);
                }
                else
                {
                    Debug.Assert(md5Sum != null, $@"{nameof(md5Sum)} != null");
                    md5Sum.CopyTo(result, 0);
                    password.CopyTo(result, md5Sum.Length);
                    md5Sum = MbedTLS.MD5(result);
                }
                md5Sum.CopyTo(key, i);
                i += md5Sum.Length;
            }
        }
Exemplo n.º 15
0
        public override void InitCipher(byte[] salt, bool isEncrypt, bool isUdp)
        {
            base.InitCipher(salt, isEncrypt, isUdp);
            IntPtr ctx = Marshal.AllocHGlobal(MbedTLS.cipher_get_size_ex());

            if (isEncrypt)
            {
                _encryptCtx = ctx;
            }
            else
            {
                _decryptCtx = ctx;
            }
            MbedTLS.cipher_init(ctx);
            if (MbedTLS.cipher_setup(ctx, MbedTLS.cipher_info_from_string(_innerLibName)) != 0)
            {
                throw new System.Exception("Cannot initialize mbed TLS cipher context");
            }

            DeriveSessionKey(isEncrypt ? _encryptSalt : _decryptSalt,
                             _Masterkey, _sessionKey);
            CipherSetKey(isEncrypt, _sessionKey);
        }
Exemplo n.º 16
0
        public override void cipherEncrypt(byte[] plaintext, uint plen, byte[] ciphertext, ref uint clen)
        {
            // buf: all plaintext
            // outbuf: ciphertext + tag
            int ret;

            byte[] tagbuf = new byte[tagLen];
            uint   olen   = 0;

            switch (_cipher)
            {
            case CIPHER_AES:
                ret = MbedTLS.cipher_auth_encrypt(_encryptCtx,
                                                  /* nonce */
                                                  _encNonce, (uint)nonceLen,
                                                  /* AD */
                                                  IntPtr.Zero, 0,
                                                  /* plain */
                                                  plaintext, plen,
                                                  /* cipher */
                                                  ciphertext, ref olen,
                                                  tagbuf, (uint)tagLen);
                if (ret != 0)
                {
                    throw new CryptoErrorException(String.Format("ret is {0}", ret));
                }
                Debug.Assert(olen == plen);
                // attach tag to ciphertext
                Array.Copy(tagbuf, 0, ciphertext, (int)plen, tagLen);
                clen = olen + (uint)tagLen;
                break;

            default:
                throw new System.Exception("not implemented");
            }
        }
Exemplo n.º 17
0
 private static string GetHash(string content)
 {
     return(Uri.EscapeUriString(BitConverter.ToString(MbedTLS.MD5(Encoding.ASCII.GetBytes(content))).Replace("-", "")));
 }
Exemplo n.º 18
0
        public void PackAuthData(byte[] data, int datalength, byte[] outdata, out int outlength)
        {
            const int authhead_len = 4 + 8 + 4 + 16 + 4;

            byte[]           encrypt  = new byte[24];
            AuthDataAesChain authData = Server.data as AuthDataAesChain;

            lock (authData)
            {
                if (authData.connectionID > 0xFF000000)
                {
                    authData.clientID = null;
                }
                if (authData.clientID == null)
                {
                    authData.clientID = new byte[4];
                    g_random.GetBytes(authData.clientID);
                    authData.connectionID = (UInt32)BitConverter.ToInt32(authData.clientID, 0) % 0xFFFFFD;
                }
                authData.connectionID += 1;
                Array.Copy(authData.clientID, 0, encrypt, 4, 4);
                Array.Copy(BitConverter.GetBytes(authData.connectionID), 0, encrypt, 8, 4);
            }

            outlength = authhead_len;
            byte[] encrypt_data = new byte[32];
            byte[] key          = new byte[Server.iv.Length + Server.key.Length];
            Server.iv.CopyTo(key, 0);
            Server.key.CopyTo(key, Server.iv.Length);

            UInt64 utc_time_second = (UInt64)Math.Floor(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1, 0, 0, 0)).TotalSeconds);
            UInt32 utc_time        = (UInt32)(utc_time_second);

            Array.Copy(BitConverter.GetBytes(utc_time), 0, encrypt, 0, 4);

            encrypt[12] = (byte)(Server.overhead);
            encrypt[13] = (byte)(Server.overhead >> 8);

            // first 12 bytes
            {
                byte[] rnd = new byte[4];
                random.NextBytes(rnd);
                rnd.CopyTo(outdata, 0);
                byte[] md5data = MbedTLS.ComputeHash(key, rnd, 0, rnd.Length);
                last_client_hash = md5data;
                Array.Copy(md5data, 0, outdata, rnd.Length, 8);
            }
            // uid & 16 bytes auth data
            {
                byte[] uid            = new byte[4];
                int    index_of_split = Server.param.IndexOf(':');
                if (index_of_split > 0)
                {
                    try
                    {
                        uint user = uint.Parse(Server.param.Substring(0, index_of_split));
                        user_key = System.Text.Encoding.UTF8.GetBytes(Server.param.Substring(index_of_split + 1));
                        BitConverter.GetBytes(user).CopyTo(uid, 0);
                    }
                    catch (Exception ex)
                    {
                        Logging.Log(LogLevel.Warn, $"Faild to parse auth param, fallback to basic mode. {ex}");
                    }
                }
                if (user_key == null)
                {
                    random.NextBytes(uid);
                    user_key = Server.key;
                }
                for (int i = 0; i < 4; ++i)
                {
                    uid[i] ^= last_client_hash[8 + i];
                }

                byte[] encrypt_key = user_key;

                IEncryptor encryptor = EncryptorFactory.GetEncryptor("aes-128-cbc", Convert.ToBase64String(encrypt_key) + SALT);

                encryptor.SetIV(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 });
                encryptor.Encrypt(encrypt, 16, encrypt_data, out int enc_outlen);
                encryptor.Dispose();
                Array.Copy(encrypt_data, 16, encrypt, 4, 16);
                uid.CopyTo(encrypt, 0);
            }
            // final HMAC
            {
                byte[] md5data = MbedTLS.ComputeHash(user_key, encrypt, 0, 20);
                last_server_hash = md5data;
                Array.Copy(md5data, 0, encrypt, 20, 4);
            }
            encrypt.CopyTo(outdata, 12);
            encryptor = EncryptorFactory.GetEncryptor("rc4", Convert.ToBase64String(user_key) + Convert.ToBase64String(last_client_hash, 0, 16));

            // combine first chunk
            {
                byte[] pack_outdata = new byte[outdata.Length];
                PackData(data, datalength, pack_outdata, out int pack_outlength);
                Array.Copy(pack_outdata, 0, outdata, outlength, pack_outlength);
                outlength += pack_outlength;
            }
        }
Exemplo n.º 19
0
        public override byte[] ClientPostDecrypt(byte[] plaindata, int datalength, out int outlength)
        {
            byte[] outdata = new byte[recv_buf_len + datalength];
            Array.Copy(plaindata, 0, recv_buf, recv_buf_len, datalength);
            recv_buf_len += datalength;
            outlength     = 0;
            byte[] key = new byte[user_key.Length + 4];
            user_key.CopyTo(key, 0);
            while (recv_buf_len > 4)
            {
                BitConverter.GetBytes(recv_id).CopyTo(key, key.Length - 4);

                int data_len = ((recv_buf[1] ^ last_server_hash[15]) << 8) + (recv_buf[0] ^ last_server_hash[14]);
                int rand_len = GetRandLen(data_len, random_server, last_server_hash);
                int len      = rand_len + data_len;
                if (len >= 4096)
                {
                    throw new ObfsException("ClientPostDecrypt data error");
                }
                if (len + 4 > recv_buf_len)
                {
                    break;
                }

                byte[] md5data = MbedTLS.ComputeHash(key, recv_buf, 0, len + 2);
                if (md5data[0] != recv_buf[len + 2] || md5data[1] != recv_buf[len + 3])
                {
                    throw new ObfsException("ClientPostDecrypt data uncorrect checksum");
                }

                int pos;
                if (data_len > 0 && rand_len > 0)
                {
                    pos = 2 + GetRandStartPos(rand_len, random_server);
                }
                else
                {
                    pos = 2;
                }
                int outlen = data_len;
                Util.Utils.SetArrayMinSize2(ref outdata, outlength + outlen);
                byte[] data = new byte[outlen];
                Array.Copy(recv_buf, pos, data, 0, outlen);
                encryptor.Decrypt(data, outlen, data, out outlen);
                last_server_hash = md5data;
                if (recv_id == 1)
                {
                    Server.tcp_mss = data[0] | (data[1] << 8);
                    pos            = 2;
                    outlen        -= 2;
                }
                else
                {
                    pos = 0;
                }
                Array.Copy(data, pos, outdata, outlength, outlen);
                outlength    += outlen;
                recv_buf_len -= len + 4;
                Array.Copy(recv_buf, len + 4, recv_buf, 0, recv_buf_len);
                ++recv_id;
            }
            return(outdata);
        }
Exemplo n.º 20
0
 private static string GetHash(string content)
 {
     return(HttpServerUtility.UrlTokenEncode(MbedTLS.MD5(Encoding.ASCII.GetBytes(content))));
 }