diff --git a/mes/客户端代码(C#).md b/mes/客户端代码(C#).md
new file mode 100644
index 0000000..e60d0e1
--- /dev/null
+++ b/mes/客户端代码(C#).md
@@ -0,0 +1,124 @@
+
+Client3.cs
+
+```
+using System;
+using System.IO;
+using System.Net;
+using System.Security.Cryptography;
+using System.Text;
+
+/// 请求体签名客户端。
+public sealed class Client3
+{
+
+ /// 服务器源。
+ /// http://api.group.mes/open/
+ public string Source { get; private set; }
+
+ /// 令牌。
+ public string Token { get; private set; }
+
+ /// 密钥。
+ public string Secret { get; private set; }
+
+ /// 构造函数,创建客户端实例。
+ public Client3(string source, string token, string secret)
+ {
+ if (string.IsNullOrEmpty(source)) throw new ArgumentException("未指定服务器源。");
+ if (string.IsNullOrEmpty(token)) throw new ArgumentException("未指定令牌。");
+ if (string.IsNullOrEmpty(secret)) throw new ArgumentException("未指定密钥。");
+
+ Source = source;
+ Token = token;
+ Secret = secret;
+ }
+
+ /// 发送 POST 请求。
+ /// 要调用的方法。
+ /// 请求体 JSON 字符串。
+ /// HTTP 响应体
+ ///
+ ///
+ public string Post(string func, string json)
+ {
+ // 请求体
+ var body = Encoding.UTF8.GetBytes(json ?? "");
+
+ // 计算签名
+ var stamp = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds).ToString();
+ var sha256 = Sha256(body);
+ var sample = Secret + "\n" + stamp + "\n" + sha256;
+ var signature = Sha256(Encoding.UTF8.GetBytes(sample));
+
+ // 发起 HTTP 请求
+ var url = Source + func;
+ var request = (HttpWebRequest)WebRequest.Create(url);
+ request.Method = "POST";
+ request.ContentType = "application/json";
+ request.ContentLength = body.Length;
+ request.Headers.Add("Token", Token);
+ request.Headers.Add("Stamp", stamp);
+ request.Headers.Add("Signature", signature);
+ request.GetRequestStream().Write(body, 0, body.Length);
+ var response = request.GetResponse() as HttpWebResponse;
+ using (var memory = new MemoryStream())
+ {
+ var stream = response.GetResponseStream();
+ var buffer = new byte[4096];
+ while (true)
+ {
+ var count = stream.Read(buffer, 0, buffer.Length);
+ if (count < 1) break;
+ memory.Write(buffer, 0, count);
+ }
+ return Encoding.UTF8.GetString(memory.ToArray());
+ }
+ }
+
+ /// 计算 SHA256,获取哈希的小写十六进制。
+ ///
+ static string Sha256(byte[] bytes)
+ {
+ using (var provider = new SHA256CryptoServiceProvider())
+ {
+ var hash = provider.ComputeHash(bytes);
+ provider.Clear();
+
+ const string hex = "0123456789abcdef";
+ var chars = new char[hash.Length * 2];
+ for (var i = 0; i < hash.Length; i++)
+ {
+ var b = bytes[i];
+ var offset = i * 2;
+ chars[offset] = hex[b / 16];
+ chars[offset + 1] = hex[b % 16];
+ }
+ return new string(chars);
+ }
+ }
+
+}
+```
+
+Program.cs
+
+```
+using System;
+
+class Program
+{
+
+ static void Main(string[] args)
+ {
+ // 准备客户端
+ var client3 = new Client3("http://127.0.0.1:8033/open/", "token3", "secret3");
+
+ // 发起接口请求
+ var response = client3.Post("checked", "");
+ Console.WriteLine(response);
+ }
+
+}
+
+```
diff --git a/mes/获取认证信息(测试).md b/mes/获取认证信息(测试).md
new file mode 100644
index 0000000..a07d8b3
--- /dev/null
+++ b/mes/获取认证信息(测试).md
@@ -0,0 +1,72 @@
+### 获取认证信息(Checked)
+
+此接口用于初期对接时验证认证方式时测试用,没有生产用途。
+
+此接口需要认证,详情请查看《认证方式》。
+
+---
+
+### 基本信息
+
+方法:POST
+URL: http://localhost:8033/open/checked
+
+---
+
+### 请求
+
+请求参数
+
+| 参数名 | 类型 | 必填 | 说明 |
+| :-- | :-- | :-- | :-- |
+| strict | bool | 否 | 要求接口必须通过认证,在认证失败时抛出错误信息。默认值:是 |
+
+示例 1:要求必须认证
+
+```
+{
+ "data": {
+ strict: true
+ }
+}
+```
+
+---
+
+### 响应
+
+响应字段
+
+| 字段 | 类型 | 说明 |
+| :-- | :-- | :-- |
+| clock | string | 当前服务器时钟。 |
+| checked | bool | 认证成功。 |
+| app | object | 注册的应用。 |
+| app.name | string | 应用的名称。 |
+
+认证成功时,响应如下:
+
+```
+{
+ "clock": "2023-06-25 20:00:00.000",
+ "status": "ok",
+ "data": {
+ "clock": "2023-06-25 20:00:00.000",
+ "checked": true,
+ "app": {
+ "name": "Demo3"
+ }
+ }
+}
+```
+
+服务端和客户端的系统时钟必须准确,若某一端的时钟偏差较大,则会出现以下响应:
+
+```
+{
+ "clock": "2023-06-25 20:00:00.000",
+ "status": "exception",
+ "message": "时间戳相差【2000】秒,超出了允许的范围,请检查系统时钟。",
+ "data": {}
+}
+```
diff --git a/mes/认证方式.md b/mes/认证方式.md
new file mode 100644
index 0000000..8aa3006
--- /dev/null
+++ b/mes/认证方式.md
@@ -0,0 +1,122 @@
+### 认证方式
+
+除了少部分的查询接口以外,大部分开放接口都需要认证,认证失败时候无法获取内容。
+
+目前已启用的认证方式有:
+- 基本认证
+- 请求体签名认证
+
+---
+
+### 基本认证
+
+基本认证使用固定的明文在网络中传输认证信息,存在被劫持的风险,因此不建议使用。
+
+基本认证仅需使用一个 `token` 参数,加入 HTTP 头部即可,以下为 HTTP 请求示例:
+
+```
+POST /open/checked HTTP/1.1
+Host: 127.0.0.1
+Content-Type: application/json
+Content-Length: 30
+Token: token1
+
+{ "data": { "strict": true } }
+```
+
+认证成功时响应内容由接口控制;认证失败时会得到以下响应体:
+
+```
+{
+ "status": "exception",
+ "message": "令牌不存在。",
+ "data": {}
+}
+```
+
+---
+
+### 请求体签名认证
+
+使用请求体签名认证方式时,所有请求必须是 POST 方法,应用注册后可取到两个值:
+- token:请求令牌,此值为固定值,需明文传输
+- secret:哈希盐,此值用于计算哈希时加盐
+
+HTTP 请求中与认证有关的字段有 3 个:
+- token:请求令牌,此参数为固定值
+- stamp:当前 UTC 毫秒时间戳
+- signature:签名,此参数为动态值
+
+#### 签名步骤
+
+根据当前时钟生成 UTC 时毫秒间戳,获取字符串:
+
+```
+// JavaScript 生成时间戳
+var stamp = String(Number(new Date()));
+
+// C# 生成时间戳
+var stamp = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds).ToString();
+```
+
+获取请求体的字符串:
+
+```
+{ "data": { "strict": true } }
+```
+
+使用 UTF-8 对请求体的文本进行编码,获取到 30 个字节,这与 HTTP 请求头中的 `Content-Length: 30` 一致,计算 SHA256,获取小写的十六进制:
+
+```
+// sha256
+bd1f3e0163a759712739476ef49425ea93753fe690f5edd589c0e43bd0d1f653
+```
+
+将请求体哈希、时间戳和 secret 使用换行符拼接成一个字符串:
+
+```
+var secret = "secret3";
+var stamp = "1687723200000";
+var sha256 = "bd1f3e0163a759712739476ef49425ea93753fe690f5edd589c0e43bd0d1f653";
+var sample = secret + "\n" + stamp + "\n" + sha256;
+```
+
+拼接后,得到待签名字符串:
+
+```
+secret3
+1687723200000
+bd1f3e0163a759712739476ef49425ea93753fe690f5edd589c0e43bd0d1f653
+```
+
+对待签名字符串进行 UTF-8 编码后,计算 SHA256,即为签名:
+
+```
+64235f1ae5900039b5e5c370aebbe8081b8b24b08b2bc3806a9a359304fc1e3b
+```
+
+#### 请求示例
+
+将令牌(Token)、时间戳(Stamp)和签名(Signature)加入 HTTP 请求头中,即可发起请求。
+
+```
+POST /open/checked HTTP/1.1
+Host: 127.0.0.1
+Content-Type: application/json
+Content-Length: 30
+Token: token3
+Stamp: 1687723200000
+Signature: 64235f1ae5900039b5e5c370aebbe8081b8b24b08b2bc3806a9a359304fc1e3b
+
+{ "data": { "strict": true } }
+```
+
+认证成功时响应内容由接口控制;认证失败时会得到以下响应体:
+
+```
+{
+ "status": "exception",
+ "message": "令牌不存在。",
+ "data": {}
+}
+```