关于共享内存:
使用共享内存的时候, 如果想记录共享内存的相关信息, 可以
在共享内存的头部来记录信息, 比如设计一个结构体
1 2 3 4 5
| struct Head { int total; //最多可以存放多少个 int useNum; //当前可用的个数 }
|

1.秘钥协商的流程
- 在秘钥协商客户端生成一随机字符串 - rand1
- 客户端将rand1发送给秘钥协商服务器
- 服务器接收客户端发送的rand1, 在服务器端生成一另外一个随机字符串rand2
- 服务器将rand1和rand2进行混合运算生成一个新的字符串 - seckey1
- 服务器将生成的rand2发送给客户端
- 客户端接收数据, 客户端有rand1和rand2
- 可以将seckey1和seckey2作为秘钥
2.秘钥校验
- 当秘钥协商成功之后, 需要再次校验客户端和服务器生成的秘钥是否相同
3.秘钥注销
- 不再继续使用的秘钥需要注销
- 需要标记秘钥的状态:
- bool status
- status == 1: 可用
- status == 0: 不可用
4.秘钥查看
5.使用的数据结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| // 客户端给服务器发送数据的时候用到的数据结构 struct RequestMsg { //1 密钥协商 //2 密钥校验; // 3 密钥注销 int cmdType; // 报文类型 char clientId[12]; // 客户端编号 char authCode[65]; // 认证码 - openssl hmac char serverId[12]; // 服务器端编号 char r1[64]; // 客户端随机数 };
- cmdType: 客户端请求的类型, 服务器根据这个变量做不同的处理 - clientId: 客户端的编号, 是唯一的 - serverId: 服务器的编号, 是唯一的 - authCode: 消息认证码, 判定消息是否被篡改过 - (原始数据 + 秘钥) * 哈希运算 = 散列值 - r1: 客户端生成的随机字符串, 生成秘钥其中的一部分原材料
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| // 服务器给客户端回复的时候用的到结构 struct RespondMsg { int rv; // 返回值 char clientId[12]; // 客户端编号 char serverId[12]; // 服务器编号 char r2[64]; // 服务器端随机数 int seckeyid; // 对称密钥编号 keysn };
- rv: return value - > 服务器对客户端请求的处理结果 - 0: 正确 - -1: 错误 - clientId: 客户端的编号, 是唯一的 - serverId: 服务器的编号, 是唯一的 - r2: 服务器生成的随机字符串, 生成秘钥其中的一部分原材料 - seckeyid: 生成的新的秘钥之后, 需要编号, 该动作是有秘钥协商服务器完成的
|
- 写一个人机交互程序
1 2 3 4 5 6 7 8 9 10 11 12 13
| printf("0-退出, 1-协商, 2-校验, 3-注销\n"); while(1) { // 键盘捕捉 cin >> sel; switch(sel) { case 1: // 秘钥协商 break; } }
|
- 用户输入1, 进入秘钥协商
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| 创建一个 RequestMsg对象, 并初始化 将要发送的数据序列化 - 得到一个字符串 创建通信的套接字, 并且连接到秘钥协商服务器 发送序列化之后的字符串 阻塞等待接收服务器回发的数据 - > 字符串 服务器序列化之后得到的字符串 需要接接收的字符串解码, 数据还原得到RespondMsg对象 查看服务器处理结果 - > rv的值 // 服务器给客户端回复的时候用的到结构 struct RespondMsg { int rv; // 返回值 char clientId[12]; // 客户端编号 char serverId[12]; // 服务器编号 char r2[64]; // 服务器端随机数 int seckeyid; // 对称密钥编号 keysn }; - rv: return value - > 服务器对客户端请求的处理结果 - 0: 正确 - -1: 错误 - clientId: 客户端的编号, 是唯一的 - serverId: 服务器的编号, 是唯一的 - r2: 服务器生成的随机字符串, 生成秘钥其中的一部分原材料 - seckeyid: 生成的新的秘钥之后, 需要编号, 该动作是有秘钥协商服务器完成的 失败 - > 直接退出, 通过用户 成功 -> 继续 通过服务器发送过来的r2和自己 的r1组合 进行哈希运算 -> 散列值 -> 秘钥 将生成的秘钥写入共享内存 class NodeSHMInfo { public: int status; int seckeyID; char clientID[12]; char serverID[12]; char seckey[128]; };
|
NodeSHMInfo 类型的变量可以从配置文件或者是环境变量中获取;