使用wireshark抓包,本地环回测试通信数据已经通过SM4国密算法加密

具体操作

  • 本实验采用 本地环回测试
  • 开启wireshark抓包工具,设定端口号 tcp.port == 5099 (5099为服务端对外开启服务的端口号),不可以使用ip.addr指定ip地址,因为本地环回测试,相关信息太多,使用端口抓包最为简单
  • 首先开启服务端,然后开启客户端,服务端开启之后输出 "Bind returned success",并输出客户端连接通信使用的端口号,然后客户端会使用socket通信传输经过SM4对称加密算法加密返回的密文
  • 密文存储格式是字符串,表示形式是十六进制;socket通信的时候会将这个字符串再次编码为十六进制,因此使用wireshark抓包数据之后 需要对拦截的数据进行解码 (十六进制 转 字符串)
  • hex转str - 在线工具
  • 客户端发送数据完毕之后,输出Client:sending data test,请按任意键退出
  • 服务端打印输出 客户端发送数据的数据 以及对应的长度等信息,输出 Connect closed,结束通信

服务端

 客户端

 wireshark抓包

  • 客户端 端口号 向 服务端 端口号 发送33字节数据

  •  点击 Data,查看下窗口,左边是数据的十六进制,右边是字符串

  •  将wireshark抓到的数据和server接收到的数据对比,数据一致
  • 表明客户端和发送端数据传输是经过SM4算法加密的

参考链接

服务端代码

// sdf_cpp_warpper.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
// server端

#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN


#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <iomanip>
#include <winsock2.h>
#include <Ws2tcpip.h>
#include <stdio.h>


#include "sdf_warpper.hpp"
#include "cstring"

#pragma comment(lib, "Ws2_32.lib")
#pragma comment(lib,"libhsm_core.lib")

#define DEFAULT_BUFLEN 1024
using namespace std;

typedef std::vector<unsigned char> bytes;
std::string BytesToStr(const bytes& in)
{
	bytes::const_iterator from = in.cbegin();
	bytes::const_iterator to = in.cend();
	std::ostringstream oss;
	for (; from != to; ++from)
		oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(*from);
	return oss.str();
}


void sm4_encrypt_decrypt_demo() {
	sdf_qax::SDF_warpper sdf_warpper("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");
	//char a[16] = { '1','0','0','0','0','2','4','5','6','7','2','1','3','4','5','6' };
	char a[]{ '0','0','0','0','0','0','0','0','0','0','0','0','0','0' };
	//char a[]{ 00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };

	//std::cout << "input_data: ";
	std::cout << "char类型数据: ";
/*	for (auto i : a) {
		std::cout << i << " ";
	}  */
	//std::cout << std::endl;			  
	bytes input(a, a + 15);
	for (auto i : input) {
		std::cout << i;
	}			 
	std::cout << std::endl;
	std::cout << "char类型数据 转十六进制 输出: ";
	std::cout << BytesToStr(input) << std::endl;		   


	char outbuffer[32]{ 0 };
	int out_buffer_true_length = 0;
	sdf_warpper.sm4_symmetry_encrypt((uint8_t *)sdf_warpper.getStaticKey(), a, sizeof(a) / sizeof(char), outbuffer, &out_buffer_true_length);
	std::cout << "cipher data with padding length: " << out_buffer_true_length << std::endl;

	char static_key[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
	bytes input_3(static_key, static_key + 15);
	std::cout << "static_key数据 转十六进制 输出: ";
	std::cout << BytesToStr(input_3) << std::endl;

/*	for (char i : outbuffer) {
		std::cout << i;
	}							   */
	bytes input_2(outbuffer, outbuffer + out_buffer_true_length);

	std::cout << "密文数据输出:";
	std::cout << BytesToStr(input_2) << std::endl;
	//std::cout << std::endl;
	std::cout << "true array length: " << strlen(outbuffer) << std::endl;
	char decrypt_result[32]{ 0 };
	int out_true_length = 0;
	sdf_warpper.sm4_symmetry_decrypt((uint8_t *)sdf_warpper.getStaticKey(), outbuffer, out_buffer_true_length, decrypt_result, &out_true_length);

	std::cout << "decrypt result data: ";
	for (int i = 0; i < strlen(decrypt_result); i++) {
		std::cout << decrypt_result[i];
	}
	std::cout << std::endl;
}

ECCCipher cipher;   //密文存储结构体

void sm2_encrypt_decrypt_demo() {
	sdf_qax::SDF_warpper sdf_warpper2("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");
	char a[]{ '3','4','5' };
	std::cout << "input_data: ";
	for (char i : a) {
		std::cout << i;
	}
	std::cout << std::endl;

	sdf_warpper2.sm2_internal_encrypt(1, a, 3, &cipher);
	char decrypt_result[256]{ 0 };
	int out_true_length = 0;
	sdf_warpper2.sm2_internal_decrypt(1, &cipher, reinterpret_cast<sdf_uint8_t *>(decrypt_result), &out_true_length, nullptr, 0);
	std::cout << "Data length after decryption: " << out_true_length << std::endl;
	std::cout << "Data after decryption: ";
	for (int i = 0; i < out_true_length; i++) {
		std::cout << decrypt_result[i];
	}
	std::cout << std::endl;
}

void main()
{
	//Initialze winsock
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		std::cout << "Can't Initialize winsock!Quiting!" << std::endl;;
		return;
	}

	//Creste a sockrt
	SOCKET sockSrv = socket(AF_INET, SOCK_STREAM, 0);
	if (sockSrv == INVALID_SOCKET) {
		wprintf(L"Can't create a socket with error %d\n", WSAGetLastError());
		WSACleanup();
		return;
	}

	//Bind the socket to an ip address and port
	int port = 5099;
	SOCKADDR_IN addrSrv;
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(port); //1024以上的端口号
	addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

	//Bind the socket
	int retVal = bind(sockSrv, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR));
	if (retVal == SOCKET_ERROR) {
		printf("Failed bind:%d\n", WSAGetLastError());
		closesocket(sockSrv);
		WSACleanup();
		return;
	}
	else {
		std::cout << "Bind returned success" << std::endl;
	}

	//Tell winsock the socket is for listening
	if (listen(sockSrv, SOMAXCONN) == SOCKET_ERROR) {
		printf("Listen failed:%d", WSAGetLastError());
		return;
	}

	//wait for a connection
	SOCKADDR_IN addrClient;
	int clientSize = sizeof(addrClient);
	SOCKET sockConn = accept(sockSrv, (SOCKADDR*)&addrClient, &clientSize);
	if (sockConn == SOCKET_ERROR) {
		wprintf(L"accept failed with error: %ld\n", WSAGetLastError());
		closesocket(sockSrv);
		WSACleanup();
		return;
	}

	char host[NI_MAXHOST];       //Client's remote name
	char service[NI_MAXSERV];    //Service (i.e. port)the client is connect on
	ZeroMemory(host, NI_MAXHOST);//Same as memset(host,0,NI_MAXHOST)
	ZeroMemory(service, NI_MAXSERV);

	if (getnameinfo((sockaddr*)&addrClient, sizeof(addrClient), host, NI_MAXHOST, service, NI_MAXSERV, 0) == 0) {
		std::cout << "connect on port " << service << std::endl;
	}
	else {
		inet_ntop(AF_INET, &addrClient.sin_addr, host, NI_MAXHOST);
		std::cout << host << " connect on port " << ntohs(addrClient.sin_port) << std::endl;
	}

	//while loop:accept and echo message back to client
	char recvbuf[DEFAULT_BUFLEN] = "";
	int recvbuflen = DEFAULT_BUFLEN;
	memset(recvbuf, 0, sizeof(recvbuf));
	char sendbuf[] = "Client: sending data test\n";
	retVal = send(sockConn, sendbuf, sizeof(sendbuf), 0);
	if (retVal == SOCKET_ERROR) {
		wprintf(L"send failed with error: %d\n", WSAGetLastError());
		closesocket(sockSrv);
		WSACleanup();
		return;
	}
	do {

		retVal = recv(sockConn, recvbuf, recvbuflen, 0);
		if (retVal > 0) {
			wprintf(L"Bytes received: %d\n", retVal);
			printf("%s\n", recvbuf);
		}
		else if (retVal == 0)
			wprintf(L"Connection closed\n");
		else
			wprintf(L"recv failed with error: %d\n", WSAGetLastError());

	} while (retVal > 0);


	closesocket(sockConn);
	//close socket
	closesocket(sockSrv);
	//close winsock
	WSACleanup();
	system("pause");
}


// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件

客户端代码

// sdf_cpp_warpper.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
// client端

#ifndef UNICODE
#define UNICODE
#endif

#define WIN32_LEAN_AND_MEAN


#include <iostream>
#include <stdio.h>
#include <string>
#include <sstream>
#include <vector>
#include <iomanip>
#include <winsock2.h>
#include <Ws2tcpip.h>


#include "sdf_warpper.hpp"
#include "cstring"

#pragma comment(lib,"libhsm_core.lib")
#pragma comment(lib, "Ws2_32.lib")
using namespace std;

typedef std::vector<unsigned char> bytes;
std::string BytesToStr(const bytes& in)
{
	bytes::const_iterator from = in.cbegin();
	bytes::const_iterator to = in.cend();
	std::ostringstream oss;
	for (; from != to; ++from)
		oss << std::hex << std::setw(2) << std::setfill('0') << static_cast<int>(*from);
	return oss.str();
}

void sm4_encrypt_decrypt_demo(char* outbuffer,int & out_buffer_true_length) {
	sdf_qax::SDF_warpper sdf_warpper("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");
	//char a[16] = { '1','0','0','0','0','2','4','5','6','7','2','1','3','4','5','6' };
	char a[]{ '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0' };
	//char a[]{ 00,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };

	//std::cout << "input_data: ";
	//std::cout << "char类型数据: ";
	/*	for (auto i : a) {
			std::cout << i << " ";
		}  */
		//std::cout << std::endl;			  
	bytes input(a, a + 15);
/*	for (auto i : input) {
		std::cout << i;
	}
	std::cout << std::endl;
	std::cout << "char类型数据 转十六进制 输出: ";
	std::cout << BytesToStr(input) << std::endl;		   */


	//char outbuffer[32]{ 0 };
	//int out_buffer_true_length = 0;
	sdf_warpper.sm4_symmetry_encrypt((uint8_t*)sdf_warpper.getStaticKey(), a, sizeof(a) / sizeof(char), outbuffer, &out_buffer_true_length);
//	std::cout << "cipher data with padding length: " << out_buffer_true_length << std::endl;

	char static_key[16] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 };
	bytes input_3(static_key, static_key + 15);
/*	std::cout << "static_key数据 转十六进制 输出: ";
	std::cout << BytesToStr(input_3) << std::endl;			 */

	/*	for (char i : outbuffer) {
			std::cout << i;
		}							   */
	bytes input_2(outbuffer, outbuffer + out_buffer_true_length);

	//std::cout << "密文数据输出:";
	//std::cout << BytesToStr(input_2) << std::endl;
	//std::cout << std::endl;
//	std::cout << "true array length: " << strlen(outbuffer) << std::endl;
	char decrypt_result[32]{ 0 };
	int out_true_length = 0;
	sdf_warpper.sm4_symmetry_decrypt((uint8_t*)sdf_warpper.getStaticKey(), outbuffer, out_buffer_true_length, decrypt_result, &out_true_length);

	//std::cout << "decrypt result data: ";
/*	for (int i = 0; i < strlen(decrypt_result); i++) {
		std::cout << decrypt_result[i];				    
	}							   */
	std::cout << std::endl;
}
ECCCipher cipher;   //密文存储结构体

void sm2_encrypt_decrypt_demo() {
	sdf_qax::SDF_warpper sdf_warpper2("{\"device_type\": \"rpc\",\"device_socket\": \"172.22.14.231:5000\"}");	char a[]{ '3','4','5' };
	std::cout << "input_data: ";
	for (char i : a) {
		std::cout << i;
	}
	std::cout << std::endl;

	sdf_warpper2.sm2_internal_encrypt(1, a, 3, &cipher);
	char decrypt_result[256]{ 0 };
	int out_true_length = 0;
	sdf_warpper2.sm2_internal_decrypt(1, &cipher, reinterpret_cast<sdf_uint8_t *>(decrypt_result), &out_true_length, nullptr, 0);
	std::cout << "Data length after decryption: " << out_true_length << std::endl;
	std::cout << "Data after decryption: ";
	for (int i = 0; i < out_true_length; i++) {
		std::cout << decrypt_result[i];
	}
	std::cout << std::endl;
}

void main() {
	//Initialze winsock
	WSADATA wsaData;
	if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
	{
		std::cout << "Can't Initialize winsock!Quiting!" << std::endl;;
		return;
	}

	//Creste a sockrt
	SOCKET sockClient = socket(AF_INET, SOCK_STREAM, 0);
	if (sockClient == INVALID_SOCKET) {
		wprintf(L"Can't create a socket with error %d\n", WSAGetLastError());
		WSACleanup();
		return;
	}

	//Bind the socket to an ip address and port
	int port = 5099;
	SOCKADDR_IN addrSrv;
	addrSrv.sin_family = AF_INET;
	addrSrv.sin_port = htons(5099);
	//addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
	inet_pton(AF_INET, "127.0.0.1", &addrSrv.sin_addr.S_un.S_addr);

	char buff[1024];
	memset(buff, 0, sizeof(buff));
	//向服务器发出连接请求
	if (connect(sockClient, (struct  sockaddr*) & addrSrv, sizeof(addrSrv)) == INVALID_SOCKET) {
		printf("Connect failed:%d", WSAGetLastError());
		return;
	}
	else
	{
		//接收数据
		recv(sockClient, buff, sizeof(buff), 0);
		printf("%s\n", buff);
	}

	//发送数据
	//const char* buffSend = "hello, this is a Client....";
	//send(sockClient, buffSend, strlen(buffSend) + 1, 0);

//	char sendbuf[BUFSIZ];
//	ZeroMemory(sendbuf, BUFSIZ);
/*	strcpy_s(sendbuf, str.c_str());
	if (send(sockClient, sendbuf, strlen(sendbuf) + 1, 0) == SOCKET_ERROR) {
		wprintf(L"send failed with error: %d\n", WSAGetLastError());
		closesocket(sockClient);
		WSACleanup();
		break;
	}
 */
	char outbuffer[32]{ 0 };
	int out_buffer_true_length = 0;
	sm4_encrypt_decrypt_demo(outbuffer,out_buffer_true_length);
	bytes input_2(outbuffer, outbuffer + out_buffer_true_length);

	//std::cout << "密文数据输出:";
	//std::cout << BytesToStr(input_2) << std::endl;

	//printf("%d", strlen(buffSend) + 1);
	std::string return_value(BytesToStr(input_2));
	//std::cout << return_value << std::endl;

	char sendbuf[BUFSIZ];
	ZeroMemory(sendbuf, BUFSIZ);
	strcpy_s(sendbuf, return_value.c_str());
	if (send(sockClient, sendbuf, strlen(sendbuf) + 1, 0) == SOCKET_ERROR) {
		wprintf(L"send failed with error: %d\n", WSAGetLastError());
		closesocket(sockClient);
		WSACleanup();
		exit(-1);
	}



	//关闭套接字
	closesocket(sockClient);
	WSACleanup();
	system("pause");

}


// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值