在学习安全传输平台项目总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。
10-安全传输平台项目扩展-第02天(keymngserver重构-硬件扩展)
目录:
一、复习
1、C复习-C++复习
2、keymngclient主框架、业务流和基础组件
二、安全传输平台项目——keymngserver重构
1、C++类对象模型初探
2、服务器框架复习
3、服务器框架和编程思路
4、keymngserver设计与实现-hello和dbapi类
5、keymngserver设计与实现-keymngserverapp类
6、keymngserver设计与实现-keymngserverop类
7、keymngserver设计与实现-keymngserver集成keymngserverop
8、keymngserver设计与实现-keymngserver_init流程和run流程分析
9、keymngserver设计与实现-run实现
10、keymngserver设计与实现-exit实现和业务流调试
11、keymngserver设计与实现-面向抽象类编程、编码
12、keymngserver设计与实现-面向抽象类编程、测试
三、安全传输平台项目扩展——硬件扩展
1、设备扩展-管理功能了解
2、设备扩展-设备编程
3、设备扩展-设备工作原理
一、复习
1、C复习-C++复习
(1)指针做函数参数——间接赋值成立的三个条件
(2)多态理解——多态的现象、成立的三个条件、意义、C++编译器如何实现多态
(3)函数指针做函数参数——如何理解回调函数、好处
(4)面向抽象类编程——计算机的组成
(5)C++类对象之间的关系——依赖(张三开车)和关联(张三有车)
2、keymngclient主框架(主框架类(应用程序类))、业务流(业务流类)和基础组件(共享内存IPC类、共享内存OP类)
(1)移植日志类 keymnglog
(2)移植共享内存类(类型转换)keymng_shmop、myipc_shm
(3)应用程序框架类 keymngclient、keymngclientapp
(4)keymngclient.cpp 调用—— keymngclientapp.cpp 调用——keymngclientop.cpp
(5)按照密钥协商,完成密钥校验和密钥注销
二、安全传输平台项目——keymngserver重构-硬件扩展
1、C++类对象模型初探
》C++对象模型可以概括为以下2部分:
(1)语言中直接支持面向对象程序设计的部分,主要涉及如构造函数、析构函数、虚函数、继承(单继承、多继承、虚继承)、多态等等。
(2)对于各种支持的底层实现机制。
在c语言中,“数据”和“处理数据的操作(函数)”是分开来声明的,也就是说,语言本身并没有支持“数据和函数”之间的关联性。在c++中,通过抽象数据类型(abstract data type,ADT),在类中定义数据和函数,来实现数据和函数直接的绑定。
概括来说,在C++类中有两种成员数据:static、nonstatic;三种成员函数:static、nonstatic、virtual。
C++中的class从面向对象理论出发,将变量(属性)和函数(方法)集中定义在一起,用于描述现实世界中的类。从计算机的角度,程序依然由数据段和代码段构成。
C++编译器如何完成面向对象理论到计算机程序的转化?
换句话:C++编译器是如何管理类、对象、类和对象之间的关系
具体的说:具体对象调用类中的方法,那,c++编译器是如何区分,是那个具体的类,调用这个方法呢?
1)C++类对象中的成员变量和成员函数是分开存储的
成员变量:
普通成员变量:存储于对象中,与struct变量有相同的内存布局和字节对齐方式
静态成员变量:存储于全局数据区中
成员函数:存储于代码段中。
问题出来了:很多对象共用一块代码?代码是如何区分具体对象的呢?
换句话说:int getK() const { return k; },代码是如何区分,具体obj1、obj2、obj3对象的k值?
obj1.getK();
obj2.getK();
obj3.getK();
2)C++编译器对普通成员函数的内部处理
》总结:
(1)C++类对象中的成员变量和成员函数是分开存储的。C语言中的内存四区模型仍然有效!
(2)C++中类的普通成员函数都隐式包含一个指向当前对象的this指针。
(3)静态成员函数、成员变量属于类
静态成员函数与普通成员函数的区别
静态成员函数不包含指向具体对象的指针
普通成员函数包含一个指向具体对象的指针
类似于客户端keymngclient。
4、keymngserver设计与实现-hello和dbapi类
(1)更改keymngclient.cpp输入输出(先只输出hello)和头文件;
(2)修改makefile(采用g++;目标文件改为.cpp;链接不需要的.o注释掉,只保留keymngserver.o)
(3)make后 测试,执行>./keymngserver 只输出hello
(4)修改keymng_dbop.h,增加KeyMngDBOp类,然后把keymng_dbop.cpp中的函数和全局变量添加到KeyMngDBOp类中,做成员变量和成员函数(增加static关键字);修改头文件;KeyMngsvr_DBOp_upKeyStatus函数用不到,先注释掉。
(5)修改keymng_dbop.cpp,成员函数增加类的属性KeyMngDBOp::,日志函数KeyMng_Log和日志类成员函数KeyMngLevel增加LogHelper::
(6)修改makefile(增加链接的keymnglog.o keymng_dbop.o);
(7)make编译,然后执行>./keymngserver 测试
5、keymngserver设计与实现-keymngserverapp类
(1)拷贝keymngserver.cpp为keymngserverapp.cpp,拷贝keymngserver.cpp为keymngserverapp.h
(2)keymngserverapp.h删除除头文件其他部分,并注释掉socket相关的头文件,然后设计KeyMngServerApp类:
class KeyMngServerApp { public: KeyMngServerApp(); ~KeyMngServerApp(); public: int init(); int run(); int exit(); };
(3)keymngserverapp.cpp中注释掉socket相关的头文件,增加输入C++头文件,实现KeyMngServerApp类中的成员函数(内部实现待写,都先写return 0);
(4)修改makefile(增加链接的keymngserverapp.o);
(5)keymngserverapp.cpp增加头文件 #include "keymngserverapp.h",主函数更改声明;
(6)make编译,然后执行>./keymngserver;测试
(7)keymngserver.cpp中增加头文件 #include "keymngserverapp.h",增加api函数调用:
int main() { cout << "keymngserver hello...\n"; KeyMngServerApp keyMngServerApp; keyMngServerApp.init(); keyMngServerApp.run(); //====>run(&keyMngServerApp); keyMngServerApp.exit(); return 0; }
(8)make编译,然后执行>./keymngserver;测试
6、keymngserver设计与实现-keymngserverop类
(1)keymngserverop.h设计KeyMngServerOp类:
(2)keymngserverop.cpp中注释掉socket相关的头文件,成员函数增加类的属性KeyMngServerOp::,成员函数(内部实现待修改,都只留return 0,其他都注释掉);日志函数KeyMng_Log和日志类成员函数KeyMngLevel增加LogHelper::;共享内存函数KeyMng_ShmInit、KeyMng_ShmWrite、KeyMng_ShmRead增加KeyMng_ShmOp::;数据库函数KeyMngsvr_DBOp_GenKeyID、KeyMngsvr_DBOp_WriteSecKey增加KeyMngDBOp::
(3)修改makefile(增加链接的myipc_shm.o、keymng_shmop.o、keymngserverop.o);
(4)make编译,然后执行>./keymngserver;测试
7、keymngserver设计与实现-keymngserver集成keymngserverop
(1)keymngserverapp.h的KeyMngServerApp类中增加接口函数:
class KeyMngServerApp { public: KeyMngServerApp(); ~KeyMngServerApp(); public: int setServerOp(KeyMngServerOp *pKeyMngServerOp); int setInfo(MngServer_Info *pMngServerInfo); public: int init(); int run(); int exit(); private: KeyMngServerOp *m_pKeyMngServerOp; MngServer_Info *m_pMngServerInfo; };
(2)keymngserverapp.cpp中实现接口函数,(内部实现待写,都先写return 0);
(3)keymngserver.cpp中增加业务流类调用:
int main() { cout << "keymngserver hello...\n"; KeyMngServerApp keyMngServerApp; //定义业务流类 注入到app中 KeyMngServerOp keyMngServerOp; MngServer_Info mngServer_Info; keyMngServerApp.setServerOp(keyMngServerOp); keyMngServerApp.setInfo(&mngServer_Info); keyMngServerApp.init(); keyMngServerApp.run(); //====>run(&keyMngServerApp); keyMngServerApp.exit(); return 0; }
(4)make编译,然后执行>./keymngserver;测试
8、keymngserver设计与实现-keymngserver_init流程和run流程分析
keymngserver.cpp 调用—— keymngserver.cpp 调用——keymngserverop.cpp
(1)keymngserverapp.cpp实现init函数:
int KeyMngServerApp::init() { int ret = 0; //安装一个信号处理函数 signal(SIGUSR1, mysighandler_t); //告诉linux内核 当有人向我发送用户自定义信号1的时候 请你调用myfunc api函数 signal(SIGPIPE, SIG_IGN); //告诉linux内核 当有管道破裂时候 ,请你不要在发送SIGPIPE 让1.exe死掉 请你忽略 memset(m_pMngServerInfo, 0, sizeof(MngServer_Info)); //初始化服务器 全局变量 ret = m_pKeyMngServerOp->MngServer_InitInfo(m_pMngServerInfo); if (ret != 0) { printf("func MngServer_InitInfo() err:%d \n", ret); return ret; } //函数声明 //服务器端初始化 ret = sckServer_init(m_pMngServerInfo->serverport, &m_listenfd); //应该把listenfd 变成app类的属性 if (ret != 0) { printf("func sckServer_init() err:%d \n", ret); return ret; } return ret; }
(2)keymngserverapp.cpp中为signal函数设置回调函数,并设置全局变量g_EndTag,都是全局的:
int g_EndTag = 0 ; // void mysighandler_t(int arg) { printf("func mysighandler_t() begin arg:%d\n", arg); g_EndTag = 1; printf("func mysighandler_t() end\n"); return ; }
(3)keymngserverapp.cpp实现run函数:
int KeyMngServerApp::run() { int ret = 0; int connfd = 0; int mytime = 3; pthread_t pid; while (1) { if (g_EndTag == 1) { break; } ret = sckServer_accept(m_listenfd, mytime, &connfd); if (ret == Sck_ErrTimeOut) { printf("func sckServer_accept() 检测到内核中没有连接 \n "); continue; } //C++里面 使用业务类对象/连接/配置信息 //待实现!!! //pthread_create(&pid, NULL, mystart_routine, (void *)connfd); } return 0; }
(4)keymngserverapp.h增加:
class KeyMngServerApp {
... private: int m_listenfd ; };
(5)keymngserverapp.cpp中的run函数C++里面 使用业务类对象/连接/配置信息 待实现!!!
(6)keymngserver.cpp中把服务器进程变成守护进程,main()函数中增加INIT_DAEMON,main()函数前增加宏:
#define INIT_DAEMON \ { \ if(fork() >0) exit(0); \ setsid(); \ if(fork()>0) exit(0); \ }
9、keymngserver设计与实现-run实现
run函数是KeyMngServerApp类的成员,pthread_create(&pid, NULL, mystart_routine, (void *)connfd)如何获得类的相应参数呢?
分析:connfd是传给mystart_routine使用的,但是现在还需要传KeyMngServerApp类,所以需要把二者结合为一个结构体,放到最后一个参数,传给mystart_routine函数
(1)keymngserverapp.cpp中的run函数
//C++里面 使用业务类对象/连接/配置信息 ThreadInfo *pThreadInfo = new ThreadInfo; pThreadInfo->keyMngServerApp = this; //把app类的对象 传入到线程体中 pThreadInfo->connfd = connfd; pthread_create(&pid, NULL, mystart_routine, (void *)pThreadInfo);
(2)connfd和KeyMngServerApp类一起使用,keymngserverapp.cpp增加一个结构体ThreadInfo,然后把结构体首地址传给pthread_create的最后一个参数
struct ThreadInfo { KeyMngServerApp *keyMngServerApp; int connfd; };
(3)keymngserverapp.cpp中的mystart_routine函数中
ThreadInfo *tmpThreadInfo = reinterpret_cast(arg);
(4)问题来源:在全局函数mystart_routine中,想使用 KeyMngServerApp类的私有属性(m_pKeyMngServerOp);?如何使用?
想在一个函数外使用类的私有属性,方法:1)在类中写1个get函数;2)把私有属性改成public;3)在该类中把该函数声明为友元函数
用法3解决:在全局函数mystart_routine中,想使用 KeyMngServerApp类的私有属性(m_pKeyMngServerOp);可以把全局函数声明成 KeyMngServerApp类的好朋友
在keymngserverapp.h中KeyMngServerApp类增加:
class KeyMngServerApp { friend void *mystart_routine (void *arg); ... }
(5)keymngserverapp.cpp中的mystart_routine函数中
ThreadInfo *tmpThreadInfo = reinterpret_cast(arg); KeyMngServerAbsOp *pKeyMngServerOp = NULL; //方法1: 在提供一个get接口 //方法2: 把私有属性改成public //方法3: 在全局函数mystart_routine中,想使用 KeyMngServerApp类的私有属性(m_pKeyMngServerOp); //可以把全局函数声明成 KeyMngServerApp类的好朋友 pKeyMngServerOp = tmpThreadInfo->keyMngServerApp->m_pKeyMngServerOp; connfd = tmpThreadInfo->connfd;
(6)keymngserverapp.cpp中的mystart_routine函数中MngServer_Agree、MngServer_Check、MngServer_Revoke函数前增加pKeyMngServerOp->,参数m_pMngServerInfo前增加tmpThreadInfo->keyMngServerApp->
(7)由于keymngserverapp.cpp中run函数分配了内存,所以在mystart_routine函数最后加入:
delete tmpThreadInfo;
(8)make编译,然后执行>./keymngserver;测试
10、keymngserver设计与实现-exit实现和业务流调试
(1)keymngserverapp.cpp实现exit函数:
int KeyMngServerApp::exit() { sleep(2); //释放资源 sckClient_closeconn(m_listenfd); //服务器端环境释放 sckServer_destroy(); //释放数据库连接池 IC_DBApi_PoolFree(); printf("keymngserver优雅退出\n"); return 0; }
(2)keymngserverapp.cpp中增加头文件#include "icdbapi.h"
11、keymngserver设计与实现-面向抽象类编程、编码
需求说明:实现keymngServerApp应用程序类能可配置调用SecMngServerOp业务操作类
要求1:keymngServerApp系统可以通过配置文件,选择调用张三写SecMngServerOp业务操作类或者李四写的SecMngServerOp业务操作类
要求2:系统SecMngServerApp应用程序框架类和SecMngServerOp业务操作类类有效解耦合
设计一个抽象类,并实现; 达到效果
-----------------------------------------------------------------------------------------------------------------
(1)拷贝keymngserverop.h为keymngserverabsop.h,然后把类KeyMngServerOp改为类KeyMngServerAbsOp,并把成员函数改为纯虚函数
class KeyMngServerAbsOp { public: //初始化服务器 全局变量 virtual int MngServer_InitInfo(MngServer_Info *svrInfo) = 0; virtual int MngServer_Quit(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen) = 0; //服务端 密钥协商应答流程 virtual int MngServer_Agree(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen) = 0; //int keymngserver_agree(MngServer_Info *pmngServerInfo, MsgKey_Req *pMsgKeyReq , unsigned char **pMsgKey_ResData, int *iMsgKey_ResDataLen); virtual int MngServer_Check(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen) = 0; virtual int MngServer_Revoke(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen) = 0; virtual int MngServer_view(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen) = 0; };
(2)拷贝keymngserverop.cpp为keymngserverop_lisi.cpp,拷贝keymngserverop.h为keymngserverop_lisi.h,然后把 keymngserverop_lisi.h中(keymngserver 错误码) 错误码 拷贝到keymngserverabsop.h;
(3)把 keymngserverop_lisi.h中类名KeyMngServerOp更改为KeyMngServerOp_LiSi,继承于KeyMngServerAbsOp
// keymngserverop_lisi.h #pragma once #include "keymng_msg.h" #include "keymngserverabsop.h" class KeyMngServerOp_LiSi : public KeyMngServerAbsOp { public: //初始化服务器 全局变量 virtual int MngServer_InitInfo(MngServer_Info *svrInfo); //服务端 密钥协商应答流程 virtual int MngServer_Agree(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen); //int keymngserver_agree(MngServer_Info *pmngServerInfo, MsgKey_Req *pMsgKeyReq , unsigned char **pMsgKey_ResData, int *iMsgKey_ResDataLen); virtual int MngServer_Check(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen); virtual int MngServer_Revoke(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen); virtual int MngServer_view(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen); virtual int MngServer_Quit(MngServer_Info *svrInfo, MsgKey_Req *msgkeyReq, unsigned char **outData, int *datalen); };
(4)把 keymngserverop_lisi.cpp中把作用域的类名由KeyMngServerOp更改为KeyMngServerOp_LiSi,因为原来实现的函数只有三个,所以需要把其他的成员函数把桩打好,(内部实现待写,都先写return 0);
(5)把 keymngserverop_lisi.cpp、keymngserver.cpp中增加头文件#include "keymngserverop_lisi.h"
(6)把 keymngserver.cpp、keymngserverapp.h、keymngserverapp.cpp、keymngserverop_lisi.h、keymngserverop_lisi.cpp中把头文件keymngserverop.h更改为keymngserverabsop.h
(7)修改makefile(增加链接的keymngserverop_lisi.o,去掉keymngserverop.o);
(8)make编译,然后执行>./keymngserver;测试
(9)报错:keymngserverapp.h 30:KeyMngServerOp未声明?
解决:在keymngserverapp.h中把KeyMngServerApp类中KeyMngServerOp改为KeyMngServerAbsOp
报错:keymngserver.cpp 37:KeyMngServerOp在此作用域中尚未声明?
解决:keymngserver.cpp的main函数中KeyMngServerOp keyMngServerOp更改为:KeyMngServerAbsOp * keyMngServerOp = new KeyMngServerOp_LiSi; keyMngServerApp.setServerOp(&keyMngServerOp);更改为keyMngServerApp.setServerOp(keyMngServerOp);
报错:keymngserverapp.h 34:int KeyMngServerApp::setServerOp(KeyMngServerOp *pKeyMngServerOp)的原型不匹配类KeyMngServerApp?
解决:keymngserver.cpp的setServerOp函数中把KeyMngServerOp改为KeyMngServerAbsOp
移动走keymngserverop.h和keymngserverop.cpp
重新编译,
报错:keymng_dbop.h错误keymngserverop.h没有那个文件或目录
解决:在keymng_dbop.h中去掉头文件keymngserverop.h
报错:keymngserverapp.cpp 130:错误:KeyMngServerOp在此作用域尚未声明
解决:把KeyMngServerOp改为KeyMngServerAbsOp
(10)keymngserver.cpp中main函数最后增加 delete keyMngServerOp;
(11)keymngserverabsop.h增加KeyMngServerAbsOp类的构造和虚析构函数(public)
class KeyMngServerAbsOp { public: KeyMngServerAbsOp() { } virtual ~KeyMngServerAbsOp() { } .... };
12、keymngserver设计与实现-面向抽象类编程、测试
要求1:keymngServerApp系统可以通过配置文件,选择调用张三写SecMngServerOp业务操作类或者李四写的SecMngServerOp业务操作类
根据要求1,需要在keymngserver.cpp的main函数中根据条件判断,选择调用张三或王五的业务操作类:
if (1) { new wangwu王五 } else { new lisi李四 }
三、安全传输平台项目扩展——硬件扩展
1、设备扩展-管理功能了解
课程目标
》通过硬件接口完成数据的加解密
硬件设备的管理
对设备的管理
硬件接口的编程
初始化、加密、解密
对企业中常用硬件调用进行熟悉
SURE签名验证服务器
(1)安全行业 国家密码局
1)商用密码
2)军用密码
(2)密码设备
1)存储密钥
2)密码运算
(3)标准的密码算法
DES 3DES RAS
国内密码算法:在国际的ECC(椭圆曲线)--SM2xxx
密码设备配置管理系统功能说明
1)密码设备初始化时,会生成超级管理员、系统管理员、安全管理员、审计管理员
用不通的角色访问密码设备,做不同的操作
2)密码设备初始化完毕以后,通过安全协议登录密码设备:https://192.168.101.1/
3)通过IE浏览器可以登录密码设备,对密码设备进行配置管理,方便密码设备提供安全的密码运算服务
4)演示:通过超级管理员身份登录密码设备
5)演示:通过系统管理员身份登录密码设备
6)演示:通过安全管理员身份登录密码设备
7)演示:通过审计管理员身份登录密码设备
2、设备扩展-设备编程
设备api函数调用。
》测试:
#define _CRT_SECURE_NO_WARNINGS #include "stdio.h" #include "stdlib.h" #include "string.h" #include "BasicDefine.h" #include "BasicError.h" #include "SureCSPAPI.h" int main() { int result = 0, i = 0; ClientContext pContext = NULL; char * cfgFile = "SureCryptoCfg.xml" ; unsigned char plain_text[] = { 0x8b, 0xea, 0x0f, 0xc9, 0x3b, 0xf0, 0x17, 0xbd,0x36, 0x3b, 0x1f, 0x23, 0x58, 0xbc, 0xa1, 0xbf }; int plain_text_len = 16; unsigned char key[] = { 0x40, 0xbb, 0x12, 0xdd, 0x6a, 0x82, 0x73, 0x86,0x7f, 0x35, 0x29, 0xd3, 0x54, 0xb4, 0xa0, 0x26 }; int keyLength = 16; unsigned char cipher_text[1024] = { 0 }; int cipher_text_len = sizeof(cipher_text); unsigned char out_text[1024] = { 0 }; int out_text_len = sizeof (out_text); result = SVS_InitServerConnect(&pContext, cfgFile); //获取连接 if( result !=ERR_SUCCESS) { printf("InitServerConnect error = 0x%08x.\n",result); system("pause"); return result; } result = SVS_CipherAction(pContext, ALG_SYM_SM1_ECB, CIPHER_ENCRYPT, key, keyLength, NULL, 0, plain_text, plain_text_len, cipher_text, &cipher_text_len); for (i = 0; i < cipher_text_len; i++) { printf("%X%X ", (cipher_text[i] >> 4) & 0x0F, (cipher_text[i]) & 0x0F); } printf( "\n"); result = SVS_CipherAction(pContext, ALG_SYM_SM1_ECB , CIPHER_DECRYPT, key, keyLength, NULL, 0, cipher_text, cipher_text_len, out_text, &out_text_len); if (memcmp(out_text, plain_text, out_text_len) == 0) { printf("加密 和 解密的 一样 ok\n"); } else { printf("加密 和 解密的 不一样 err\n"); } // some code... result = SVS_FinalizeServerConnect(&pContext); //释放连接 printf("FinalizeServerConnect result = 0x%08x\n",result); system("pause"); return result; }
3、设备扩展-设备工作原理
》设备工作原理:
在学习安全传输平台项目总结了笔记,并分享出来。有问题请及时联系博主:Alliswell_WP,转载请注明出处。