Pārlūkot izejas kodu

#IQBX #comment libfilecryption 编译成功

80374374 2 gadi atpakaļ
vecāks
revīzija
25c4f5cb2e

+ 47 - 0
Other/win/libfilecryption/CMakeLists.txt

@@ -0,0 +1,47 @@
+set(MODULE_NAME "libfilecryption")
+set(MODULE_PREFIX "LIB_FILECRYPTION")
+
+set(${MODULE_PREFIX}_SRCS
+	fileanalysis.cpp
+	fileanalysis.h
+	filecryption.cpp
+	filecryption.h
+	rvcfileheader.cpp
+	rvcfileheader.h
+    asf.cpp
+    asf.h
+    ${ThirdPartyHeadRoot}/CJson/cJSON.c
+)
+
+add_library(${MODULE_NAME} SHARED ${${MODULE_PREFIX}_SRCS})
+
+# 依赖openssl
+target_include_directories(${MODULE_NAME} PRIVATE
+	${CONAN_INCLUDE_DIRS_LIBKYSM}
+    ${ThirdPartyHeadRoot}/CJson
+    )
+
+target_compile_definitions(${MODULE_NAME} PUBLIC "LIBFILECRYPTION_EXPORTS")
+
+# 添加需要依赖的其他共享库(包括系统库)
+target_link_directories(${MODULE_NAME} PRIVATE
+    ${CONAN_LIB_DIRS_LIBKYSM}
+)
+set(${MODULE_PREFIX}_LIBS ${CONAN_PKG_LIBS_LIBKYSM})
+target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
+
+if(MSVC)
+	install(TARGETS ${MODULE_NAME} 
+    RUNTIME DESTINATION "${RVC_RUNTIME_PATH}" COMPONENT libraries
+    ARCHIVE DESTINATION "${RVC_LIBRARY_PATH}" COMPONENT develops EXCLUDE_FROM_ALL
+    LIBRARY DESTINATION "${RVC_LIBRARY_PATH}" COMPONENT libraries
+    )
+else(MSVC)
+install(TARGETS ${MODULE_NAME} 
+    RUNTIME DESTINATION "${RVC_RUNTIME_PATH}"
+    ARCHIVE DESTINATION "${RVC_LIBRARY_PATH}"
+    LIBRARY DESTINATION "${RVC_RUNTIME_PATH}"
+    COMPONENT libraries)
+endif(MSVC)
+
+set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "other/")

+ 40 - 0
Other/win/libfilecryption/asf.cpp

@@ -0,0 +1,40 @@
+#include "stdafx.h"
+#include "asf.h"
+
+uint64_t get_asf_headsize(void* pbuffer, int ilen)
+{
+	uint64_t uret = 0;
+	if (ASF_HEADER_SIZE_LEN != ilen || NULL == pbuffer){
+		return uret;
+	}
+	
+	uint32_t ulowbit = 0;
+	uint32_t uhighbit = 0;
+
+	memcpy(&ulowbit, pbuffer, sizeof(uint32_t));
+	memcpy(&uhighbit, (char*)pbuffer + sizeof(uint32_t), sizeof(uint32_t));
+
+	return (ulowbit + (uhighbit << 32));
+}
+
+
+int construct_asf_headsize(char* pbuffer, int ilen, uint64_t usize)
+{
+	int iret = -1;
+	if (ASF_HEADER_SIZE_LEN > ilen || NULL == pbuffer){
+		return iret;
+	}
+
+	uint32_t uhighbits = (usize >> 32);
+	uint32_t ulowbits = usize;
+	if (uhighbits > 0){
+		ulowbits = usize - (uhighbits<<32);
+	}
+
+	memcpy(pbuffer, &ulowbits, sizeof(uint32_t));
+	memcpy(pbuffer+sizeof(uint32_t), &uhighbits, sizeof(uint32_t));
+
+	iret = 0;
+
+	return iret;
+}

+ 15 - 0
Other/win/libfilecryption/asf.h

@@ -0,0 +1,15 @@
+#pragma once
+#include <stdint.h>
+
+#ifndef ASF_HEADER_GUID_LEN
+#define ASF_HEADER_GUID_LEN 16
+#endif
+
+#ifndef ASF_HEADER_SIZE_LEN
+#define ASF_HEADER_SIZE_LEN 8
+#endif
+
+static const char ASF_Header_GUID[ASF_HEADER_GUID_LEN]={0x30,0x26,0xB2,0x75,0x8E,0x66,0xCF,0x11,0xA6,0xD9,0x00,0xAA,0x00,0x62,0xCE,0x6C};
+
+uint64_t get_asf_headsize(void* pbuffer, int ilen);
+int construct_asf_headsize(char* pbuffer, int ilen, uint64_t usize);

+ 271 - 0
Other/win/libfilecryption/fileanalysis.cpp

@@ -0,0 +1,271 @@
+#include "stdafx.h"
+#include "stdlib.h"
+#include "fileanalysis.h"
+#include "CMBSMDLL.h"
+#include <string.h>
+#include "rvcfileheader.h"
+#include "cJSON.h"
+
+static unsigned char seedkey[] = "Q&@09#5*AZWSsdff";
+
+int get_srcfile_name(char* pname, size_t ulen, const char* pfilename)
+{
+	int iret = -1;
+
+	if (NULL == pfilename){
+		return iret;
+	}
+
+	const char* pindex = strrchr(pfilename, '\\');
+	const char* pend = strrchr(pfilename, '.');
+	if (pindex&&pend){
+		size_t udatalen = pend - pindex - 1;
+		if (ulen >= udatalen){
+			memcpy(pname, pindex+1, udatalen);
+			iret = 0;
+		}
+	}
+
+	return iret;
+}
+
+
+int get_srcfile_format(char* pformat, size_t ulen, const char* pfilename)
+{
+	int iret = -1;
+	if (NULL == pfilename){
+		return iret;
+	}
+
+	const char* pindex = strstr(pfilename, ".");
+	if (pindex){
+		size_t udatalen = strlen(pindex);
+		if (ulen >= udatalen){
+			memcpy(pformat, pindex+1, udatalen);
+			iret = 0;
+		}
+	}
+
+	return iret;
+}
+
+
+int get_srcfile_hash(char* phash, size_t ulen, const char* pfilename)
+{
+	int iret = -1;
+	BYTE hash[RVC_FILE_HASH_LEN] = { 0 };
+	if(0 == CMBSM3FileDigest((char*)pfilename, hash)){
+		if (RVC_FILE_HASH_LEN <= ulen){
+			memcpy(phash, hash, RVC_FILE_HASH_LEN);
+			iret = 0;
+		}
+	}
+
+	return iret;
+}
+
+
+unsigned long get_srcfile_size(const char* pfilename)
+{
+	unsigned long usize = 0;
+	if (NULL == pfilename){
+		return usize;
+	}
+
+	FILE* pFile = fopen(pfilename, "rb");
+	if (pFile){
+		fseek(pFile, 0, SEEK_END);
+		usize = ftell(pFile);
+		fclose(pFile);
+	}
+
+	return usize;
+}
+
+
+static int bin2str(unsigned char* x, int xlen, char* str, int str_size)
+{
+	static const char* hex2char = "0123456789ABCDEF";
+	int i, k = 0;
+	if (str_size <= xlen * 2)
+		return -1;
+	for (i = 0; i < xlen; ++i) {
+		int h = x[i] >> 4;
+		int l = x[i] & 0xf;
+		str[k++] = hex2char[h];
+		str[k++] = hex2char[l];
+	}
+	str[k] = 0;
+	return k;
+}
+
+
+int get_encrytion_filename(char* strbuffer, size_t ulen, bool bencname, const char* strprefix, size_t uprefixlen, const char* pfilename)
+{
+	int iret = -1;
+
+	const char* pIndex = strrchr(pfilename, '\\');
+	if (pIndex){
+		pIndex++;
+		strncpy_s(strbuffer, ulen, pfilename, pIndex - pfilename);
+		if (false == bencname){
+			strncat_s(strbuffer, ulen - (pIndex - pfilename), strprefix, uprefixlen);
+			strcat_s(strbuffer, ulen - (pIndex - pfilename) - uprefixlen, pIndex);
+		} 
+		else{
+			unsigned char strSM[RVC_FILE_HASH_LEN] = {0};
+			CMBSM3Digest((unsigned char*)pIndex, strlen(pIndex+1), strSM);
+			char strHash[MAX_PATH] = {0};
+			bin2str(strSM, RVC_FILE_HASH_LEN, strHash, MAX_PATH);
+			strncat_s(strbuffer, ulen - (pIndex - pfilename), strHash, strlen(strHash));
+		}
+		iret = 0;
+	}
+
+	return iret;
+}
+
+
+int get_decrytion_filename(char* strbuffer, size_t ulen, const char* strprefix, size_t uprefixlen, const char* pfilename)
+{
+	int iret = -1;
+
+	const char* pIndex = strrchr(pfilename, '\\');
+	if (pIndex){
+		pIndex++;
+		strncpy_s(strbuffer, ulen, pfilename, pIndex - pfilename);
+		strncat_s(strbuffer, ulen - (pIndex - pfilename), strprefix, uprefixlen);
+		strcat_s(strbuffer, ulen - (pIndex - pfilename) - uprefixlen, pIndex);
+		iret = 0;
+	}
+
+	return iret;
+}
+
+
+int SM4EncECBMode(unsigned char key[16], unsigned char *input, int length, unsigned char *output, int *output_len)
+{
+	return CMBSM4EncryptWithECB(key, input, length, output, output_len);
+}
+
+
+int SM4DecECBMode(unsigned char key[16], unsigned char *input, int length, unsigned char *output, int *output_len)
+{
+	return CMBSM4DecryptWithECB(key, input, length, output, output_len);
+}
+
+
+int GenerateSM4Key(unsigned char* pkey, size_t ukeysize, unsigned char* phash, size_t uhashlen, size_t ufilesize)
+{
+	int iret = -1;
+
+	if (SM4ENC_BLOCK_SIZE > ukeysize || NULL == pkey){
+		return iret;
+	}
+
+	if (NULL == phash || RVC_FILE_HASH_LEN != uhashlen || 0 == ufilesize){
+		memcpy(pkey, seedkey, SM4ENC_BLOCK_SIZE);
+		iret = 0;
+		return iret;
+	}
+
+	char strHash[MAX_PATH] = {0};
+	bin2str(phash, RVC_FILE_HASH_LEN, strHash, MAX_PATH);
+
+	unsigned char outputdata[MAX_PATH] = {0};
+	int ioutputlen = MAX_PATH;
+
+	CMBSM4EncryptWithECB(seedkey, (unsigned char*)strHash, strlen(strHash), outputdata, &ioutputlen);
+
+	int icount = ioutputlen/SM4ENC_BLOCK_SIZE;
+	if (icount > 0){
+		unsigned char *pindex = pkey;
+		int i = ufilesize % icount;
+		for (; i < ioutputlen; i += icount){
+			*pindex++ = outputdata[i];
+		}
+	} 
+	else{
+		memcpy(pkey, seedkey, SM4ENC_BLOCK_SIZE);
+	}
+
+	iret = 0;
+
+	return iret;
+}
+
+
+int get_file_json_infos_from_rvc_header(char** pstrjson, size_t* ujsonlen, char* pheader, size_t udatalen)
+{
+	int iret = -1;
+	rvc_fileheader_t t_param = {0};
+	if (0 != get_rvc_file_header_info(&t_param, pheader, udatalen, NULL)){
+		return iret;
+	}
+
+	char strHash[MAX_PATH] = {0};
+	bin2str(t_param.strhash, RVC_FILE_HASH_LEN, strHash, MAX_PATH);
+
+	cJSON* root = cJSON_CreateObject();
+	cJSON_AddItemToObject(root, "Hash",cJSON_CreateString(strHash));
+	cJSON_AddItemToObject(root, "FileName",cJSON_CreateString(t_param.strsrcfilename));
+	cJSON_AddItemToObject(root, "FileFormat",cJSON_CreateString(t_param.strsrcfileformat));
+	cJSON_AddItemToObject(root, "FileSize",cJSON_CreateNumber(t_param.usrcfilelen));
+
+	char *pret = cJSON_PrintUnformatted(root);
+	if (pret){
+		size_t ulen = strlen(pret);
+		*pstrjson = (char*)malloc(ulen+1);
+		memset(*pstrjson, 0, ulen+1);
+		memcpy(*pstrjson, pret, ulen);
+		*ujsonlen = ulen;
+		iret = 0;
+		free(pret);
+	}
+	return iret;
+}
+
+
+int get_file_json_infos_from_file(char** pstrjson, size_t* ujsonlen, const char* pfilename, FILE* pFile)
+{
+	int iret = -1;
+	if (NULL == pFile || NULL == pfilename){
+		return iret;
+	}
+
+	char strname[MAX_PATH] = {0};
+	get_srcfile_name(strname, MAX_PATH, pfilename);
+
+	char strformat[MAX_PATH] = {0};
+	get_srcfile_format(strformat, MAX_PATH, pfilename);
+
+	unsigned char strhash[RVC_FILE_HASH_LEN] = {0};
+	get_srcfile_hash((char*)strhash, RVC_FILE_HASH_LEN, pfilename);
+
+	char strValue[MAX_PATH] = {0};
+	bin2str(strhash, RVC_FILE_HASH_LEN, strValue, MAX_PATH);
+
+	size_t usize = 0;
+	if (pFile){
+		fseek(pFile, 0, SEEK_END);
+		usize = ftell(pFile);
+	}
+
+	cJSON* root = cJSON_CreateObject();
+	cJSON_AddItemToObject(root, "Hash",cJSON_CreateString(strValue));
+	cJSON_AddItemToObject(root, "FileName",cJSON_CreateString(strname));
+	cJSON_AddItemToObject(root, "FileFormat",cJSON_CreateString(strformat));
+	cJSON_AddItemToObject(root, "FileSize",cJSON_CreateNumber(usize));
+
+	char *pret = cJSON_PrintUnformatted(root);
+	if (pret){
+		size_t ulen = strlen(pret);
+		*pstrjson = (char*)malloc(ulen+1);
+		memset(*pstrjson, 0, ulen+1);
+		memcpy(*pstrjson, pret, ulen);
+		*ujsonlen = ulen;
+		iret = 0;
+		free(pret);
+	}
+	return iret;
+}

+ 23 - 0
Other/win/libfilecryption/fileanalysis.h

@@ -0,0 +1,23 @@
+#pragma once
+
+#include <stdio.h>
+
+#ifndef HEADER_OBJECT_GUID_LEN
+#define HEADER_OBJECT_GUID_LEN 16
+#endif
+
+#ifndef SM4ENC_BLOCK_SIZE
+#define SM4ENC_BLOCK_SIZE 16
+#endif
+
+int get_srcfile_name(char* pname, size_t ulen, const char* pfilename);
+int get_srcfile_format(char* pformat, size_t ulen, const char* pfilename);
+int get_srcfile_hash(char* phash, size_t ulen, const char* pfilename);
+unsigned long get_srcfile_size(const char* pfilename);
+int get_encrytion_filename(char* strbuffer, size_t ulen, bool bencname, const char* strprefix, size_t uprefixlen, const char* pfilename);
+int get_decrytion_filename(char* strbuffer, size_t ulen, const char* strprefix, size_t uprefixlen, const char* pfilename);
+int SM4EncECBMode(unsigned char key[16], unsigned char *input, int length, unsigned char *output, int *output_len);
+int SM4DecECBMode(unsigned char key[16], unsigned char *input, int length, unsigned char *output, int *output_len);
+int GenerateSM4Key(unsigned char* pkey, size_t ukeysize, unsigned char* phash, size_t uhashlen, size_t ufilesize);
+int get_file_json_infos_from_rvc_header(char** pstrjson, size_t* ujsonlen, char* pheader, size_t udatalen);
+int get_file_json_infos_from_file(char** pstrjson, size_t* ujsonlen, const char* pfilename, FILE* pFile);

+ 343 - 0
Other/win/libfilecryption/filecryption.cpp

@@ -0,0 +1,343 @@
+#include "stdafx.h"
+#include "filecryption.h"
+#include "fileanalysis.h"
+#include "rvcfileheader.h"
+#include "asf.h"
+
+#include <iostream>
+using namespace std;
+
+#include <stdio.h>
+
+#ifndef RVC_MAX_HEADER_LEN
+#define RVC_MAX_HEADER_LEN 512
+#endif
+
+#ifndef RVC_FILE_INT_LEN
+#define RVC_FILE_INT_LEN 4
+#endif
+
+#ifndef RVC_READ_BUFFER_SIZE
+#define RVC_READ_BUFFER_SIZE 1024
+#endif
+
+
+#ifndef safe_free
+#define safe_free(x) if (x){ free(x); x = NULL;}
+#endif
+
+int encryption_file(char* poutfile, size_t uoutlen, const char* pfilename, const filecryption_callback_t* pcallback, eRvcCryptionVersion eversion)
+{
+	int iret = -1;
+
+	if (NULL == pfilename){
+		return iret;
+	}
+
+	char pbuffer[RVC_MAX_HEADER_LEN] = {0};
+	size_t uheaderlen = RVC_MAX_HEADER_LEN;
+	int ilen = constrcut_rvc_file_header(pbuffer, &uheaderlen, pfilename, pcallback, eversion);
+	if (0 != ilen){
+		return iret;
+	}
+
+	unsigned char strkey[SM4ENC_BLOCK_SIZE] = {0};
+	size_t uindex = (RVC_FILE_HEADER_FLAG_LEN + sizeof(size_t));
+	if (get_key_from_header_info(strkey, SM4ENC_BLOCK_SIZE, pbuffer + uindex, uheaderlen - uindex, pcallback)){
+		return iret;
+	}
+
+	if (get_encrytion_filename(poutfile, uoutlen, false, RVC_FILEENC_STR, strlen(RVC_FILEENC_STR), pfilename)){
+		return iret;
+	}
+
+	FILE* pSrcFile = fopen(pfilename, "rb");
+	if (NULL == pSrcFile){
+		return iret;
+	}
+
+	FILE* pDestFile = fopen(poutfile, "wb");
+	if (NULL == pDestFile){
+		fclose(pSrcFile);
+		return iret;
+	}
+	
+	//1. 新增自定义文件头
+	fwrite(pbuffer, 1, uheaderlen, pDestFile);
+
+	//获取加密前文件头GUID
+	char strGuid[HEADER_OBJECT_GUID_LEN] = {0};
+	fread(strGuid, 1, HEADER_OBJECT_GUID_LEN, pSrcFile);
+	if (0 != memcmp(strGuid, ASF_Header_GUID, HEADER_OBJECT_GUID_LEN)){
+		safe_log(pcallback, "%s", "math guid failed, current format is not surpport!");
+		fclose(pSrcFile);
+		fclose(pDestFile);
+		return iret;
+	}
+
+	//2. 拷贝原文件头guid
+	fwrite(strGuid, 1, HEADER_OBJECT_GUID_LEN, pDestFile);
+
+	char strheadsize[ASF_HEADER_SIZE_LEN] = {0};
+	fread(strheadsize, 1, ASF_HEADER_SIZE_LEN, pSrcFile);
+	uint64_t uheadlen = get_asf_headsize(strheadsize, ASF_HEADER_SIZE_LEN);
+
+	uint64_t uheadobjlen = uheadlen - HEADER_OBJECT_GUID_LEN - ASF_HEADER_SIZE_LEN;
+	unsigned char* pobjdata = (unsigned char*)malloc(uheadobjlen);
+	fread(pobjdata, 1, uheadobjlen, pSrcFile);
+
+	int iencdatalen = uheadobjlen + SM4ENC_BLOCK_SIZE;
+	unsigned char* pobjdataenc = (unsigned char*)malloc(iencdatalen);
+	SM4EncECBMode(strkey, pobjdata, uheadobjlen, pobjdataenc, &iencdatalen);
+
+	char strdatalen[ASF_HEADER_SIZE_LEN] = {0};
+	construct_asf_headsize(strdatalen, ASF_HEADER_SIZE_LEN, iencdatalen + HEADER_OBJECT_GUID_LEN + ASF_HEADER_SIZE_LEN);
+	//3. 填充加密后文件头长度
+	fwrite(strdatalen, 1, ASF_HEADER_SIZE_LEN, pDestFile);
+
+	//4. 填充加密后文件头内容
+	fwrite(pobjdataenc, 1, iencdatalen, pDestFile);
+
+	char *data_buffer=(char *)malloc(RVC_READ_BUFFER_SIZE);
+	size_t udatalen = 0;
+	while(udatalen = fread(data_buffer, 1, RVC_READ_BUFFER_SIZE, pSrcFile)){
+		fwrite(data_buffer, 1, udatalen, pDestFile);	
+	}
+
+	fclose(pSrcFile);
+	fclose(pDestFile);
+
+	safe_free(pobjdata);
+	safe_free(pobjdataenc);
+	safe_free(data_buffer);
+
+	iret = 0;
+
+	return iret;
+}
+
+
+int decryption_file(char* poutfile, size_t uoutlen, const char* pfilename, const filecryption_callback_t* pcallback, eRvcCryptionVersion eversion)
+{
+	int iret = -1;
+
+	if (NULL == pfilename || eversion >= sizeof(cryption_ver_flag_table)/sizeof(char*) || eversion < 0){
+		safe_log(pcallback,"%s","invalid encryption version param.");
+		return iret;
+	}
+
+	FILE* pSrcFile = fopen(pfilename, "rb");
+	if (NULL == pSrcFile){
+		safe_log(pcallback,"open file %s failed!",pfilename);
+		return iret;
+	}
+
+	char strrvcflag[RVC_FILE_HEADER_FLAG_LEN] = {0};
+	fread(strrvcflag,1, RVC_FILE_HEADER_FLAG_LEN, pSrcFile);
+	if (0 != memcmp(strrvcflag, rvc_header, RVC_FILE_HEADER_FLAG_LEN)){
+		safe_log(pcallback,"file %s is not encryption!",pfilename);
+		fclose(pSrcFile);
+		iret = 0;
+		return iret;
+	}
+
+	int irvcheadlen = 0;
+	fread(&irvcheadlen, 1, sizeof(int), pSrcFile);
+	char* prvcbuffer = (char*)malloc(irvcheadlen);
+	memset(prvcbuffer, 0, irvcheadlen);
+	fread(prvcbuffer, 1, irvcheadlen - RVC_FILE_HEADER_FLAG_LEN - sizeof(int), pSrcFile);
+
+	if (0 != memcmp(prvcbuffer+sizeof(size_t), cryption_ver_flag_table[eversion], RVC_CRYPTION_VER_FLAG_LEN)){
+		if (0 == memcmp(prvcbuffer+sizeof(size_t), cryption_ver_flag_table[eversion], RVC_CRYPTION_VER_FLAG_LEN-1)){
+			safe_log(pcallback,"file %s encryption and decryption version is not matched!",pfilename);
+		} 
+		fclose(pSrcFile);
+		return iret;
+	}
+	
+	unsigned char strkey[SM4ENC_BLOCK_SIZE] = {0};
+	if (get_key_from_header_info(strkey, SM4ENC_BLOCK_SIZE, prvcbuffer, irvcheadlen - RVC_FILE_HEADER_FLAG_LEN - sizeof(int), pcallback)){
+		return iret;
+	}
+
+	if (get_decrytion_filename(poutfile, uoutlen, RVC_FILEDEC_STR, strlen(RVC_FILEDEC_STR), pfilename)){
+		return iret;
+	}
+
+	FILE* pDestFile = fopen(poutfile, "wb");
+	if (NULL == pDestFile){
+		return iret;
+	}
+
+	char strasfheader[ASF_HEADER_GUID_LEN] = {0};
+	if (ASF_HEADER_GUID_LEN == fread(strasfheader, 1, ASF_HEADER_GUID_LEN, pSrcFile)){
+		fwrite(strasfheader, 1, ASF_HEADER_GUID_LEN, pDestFile);
+	}
+
+	char strheadlen[ASF_HEADER_SIZE_LEN] = {0};
+	fread(strheadlen, 1, ASF_HEADER_SIZE_LEN, pSrcFile);
+	uint64_t uheadlen = get_asf_headsize(strheadlen, ASF_HEADER_SIZE_LEN);
+	unsigned char* pheaddata = (unsigned char*)malloc(uheadlen);
+	unsigned char* pdecheaddata = (unsigned char*)malloc(uheadlen);
+	int ioutlen = uheadlen;
+
+	fread(pheaddata, 1, uheadlen - ASF_HEADER_GUID_LEN - ASF_HEADER_SIZE_LEN, pSrcFile);
+	SM4DecECBMode(strkey, pheaddata, uheadlen - ASF_HEADER_GUID_LEN - ASF_HEADER_SIZE_LEN, pdecheaddata, &ioutlen);
+	construct_asf_headsize(strheadlen,ASF_HEADER_SIZE_LEN,ioutlen + ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN);
+	fwrite(strheadlen, 1, ASF_HEADER_SIZE_LEN, pDestFile);
+	fwrite(pdecheaddata, 1, ioutlen, pDestFile);
+
+	char *data_buffer=(char *)malloc(RVC_READ_BUFFER_SIZE);
+	size_t udatalen = 0;
+	while(udatalen = fread(data_buffer, 1, RVC_READ_BUFFER_SIZE, pSrcFile)){
+		fwrite(data_buffer, 1, udatalen, pDestFile);	
+	}
+
+	fclose(pSrcFile);
+	fclose(pDestFile);
+
+	safe_free(data_buffer);
+	safe_free(pdecheaddata);
+	safe_free(pheaddata);
+
+	return iret;
+}
+
+
+bool is_file_encrypted(const char* pfilename, const filecryption_callback_t* pcallback)
+{
+	bool bret = false;
+	if (NULL == pfilename){
+		return bret;
+	}
+
+	FILE* pSrcFile = fopen(pfilename, "rb");
+	if (NULL == pSrcFile){
+		safe_log(pcallback,"open file %s failed!",pfilename);
+		return bret;
+	}
+
+	char strrvcheader[RVC_FILE_HEADER_FLAG_LEN] = {0};
+	if (RVC_FILE_HEADER_FLAG_LEN == fread(strrvcheader, 1, RVC_FILE_HEADER_FLAG_LEN, pSrcFile)){
+		if (0 == strnicmp(strrvcheader, rvc_header, RVC_FILE_HEADER_FLAG_LEN)){
+			bret = true;
+		} 
+		else{
+			safe_log(pcallback,"file %s is not encryption!",pfilename);
+		}
+	}
+	fclose(pSrcFile);
+
+	return bret;
+}
+
+
+/*
+文件解密功能;
+	输入:文件路径
+	输出:文件明文头数据,文件明文头长度,加解密前后文件偏移量,自定义头文件头信息
+*/
+int rvc_file_decrypt(unsigned char** pdechead, size_t* udecheadlen, int* ioffset, char** pstrjson, size_t* ujsonlen, const char* pfilename, const filecryption_callback_t* pcallback, eRvcCryptionVersion eversion)
+{
+	int iret = -1;
+	if (NULL == pfilename || eversion >= sizeof(cryption_ver_flag_table)/sizeof(char*) || eversion < 0){
+		safe_log(pcallback,"%s","invalid cryption version param.");
+		return iret;
+	}
+
+	FILE* pSrcFile = fopen(pfilename, "rb");
+	if (NULL == pSrcFile){
+		safe_log(pcallback,"open file %s failed!",pfilename);
+		return iret;
+	}
+
+	unsigned char strkey[SM4ENC_BLOCK_SIZE] = {0};
+	int irvcheadlen = 0;
+
+	char strrvcflag[RVC_FILE_HEADER_FLAG_LEN] = {0};
+	fread(strrvcflag,1, RVC_FILE_HEADER_FLAG_LEN, pSrcFile);
+	if (0 != memcmp(strrvcflag, rvc_header, RVC_FILE_HEADER_FLAG_LEN)){
+		//safe_log(pcallback,"file %s is not encrypted!",pfilename);
+		*pdechead = NULL;
+		*udecheadlen = 0;
+		*ioffset = 0;
+		fclose(pSrcFile);
+		iret = 0;
+		return iret;
+	}
+	else{
+		//safe_log(pcallback,"file %s is encrypted!",pfilename);
+		fread(&irvcheadlen, 1, sizeof(int), pSrcFile);
+		char* prvcbuffer = (char*)malloc(irvcheadlen);
+		memset(prvcbuffer, 0, irvcheadlen);
+		fread(prvcbuffer, 1, irvcheadlen - RVC_FILE_HEADER_FLAG_LEN - sizeof(int), pSrcFile);
+
+		if (0 != memcmp(prvcbuffer+sizeof(size_t), cryption_ver_flag_table[eversion], RVC_CRYPTION_VER_FLAG_LEN)){
+			if (0 == memcmp(prvcbuffer+sizeof(size_t), cryption_ver_flag_table[eversion], RVC_CRYPTION_VER_FLAG_LEN-1)){
+				safe_log(pcallback,"file %s encryption and decrption version is not matched!",pfilename);
+			} 
+			safe_free(prvcbuffer);
+			fclose(pSrcFile);
+			return iret;
+		}
+
+		if (get_key_from_header_info(strkey, SM4ENC_BLOCK_SIZE, prvcbuffer, irvcheadlen - RVC_FILE_HEADER_FLAG_LEN - sizeof(int), pcallback)){
+			safe_free(prvcbuffer);
+			fclose(pSrcFile);
+			return iret;
+		}
+
+		int ijson = get_file_json_infos_from_rvc_header(pstrjson, ujsonlen, prvcbuffer, irvcheadlen - RVC_FILE_HEADER_FLAG_LEN - sizeof(int));
+		if (0 == ijson){
+			safe_log(pcallback,"get_file_json_infos_from_rvc_header success!");
+		}
+		safe_free(prvcbuffer);
+	}
+
+	char strasfheader[ASF_HEADER_GUID_LEN] = {0};
+	if (ASF_HEADER_GUID_LEN == fread(strasfheader, 1, ASF_HEADER_GUID_LEN, pSrcFile)){
+		if (0 != memcmp(strasfheader, ASF_Header_GUID, ASF_HEADER_GUID_LEN)){
+			safe_log(pcallback,"file %s is current not surrport format!",pfilename);
+			fclose(pSrcFile);
+			return iret;
+		}
+	}
+	else{
+		fclose(pSrcFile);
+		return iret;
+	}
+
+	char strheadlen[ASF_HEADER_SIZE_LEN] = {0};
+	fread(strheadlen, 1, ASF_HEADER_SIZE_LEN, pSrcFile);
+	uint64_t uheadlen = get_asf_headsize(strheadlen, ASF_HEADER_SIZE_LEN);
+	unsigned char* pheaddata = (unsigned char*)malloc(uheadlen);
+
+	fread(pheaddata+ ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN, 1, uheadlen - ASF_HEADER_GUID_LEN - ASF_HEADER_SIZE_LEN, pSrcFile);
+	unsigned char* pdecheaddata = (unsigned char*)malloc(uheadlen);
+	int ioutlen = uheadlen - ASF_HEADER_GUID_LEN - ASF_HEADER_SIZE_LEN ;
+	SM4DecECBMode(strkey, pheaddata + ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN, uheadlen - ASF_HEADER_GUID_LEN - ASF_HEADER_SIZE_LEN, pdecheaddata + ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN, &ioutlen);
+	construct_asf_headsize(strheadlen,ASF_HEADER_SIZE_LEN,ioutlen + ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN);
+	memcpy(pdecheaddata, strasfheader, ASF_HEADER_GUID_LEN);
+	memcpy(pdecheaddata + ASF_HEADER_GUID_LEN, strheadlen, ASF_HEADER_SIZE_LEN);
+	*pdechead = pdecheaddata;
+	*udecheadlen = ioutlen + ASF_HEADER_GUID_LEN + ASF_HEADER_SIZE_LEN;
+	*ioffset = (irvcheadlen + uheadlen - (*udecheadlen));
+	safe_free(pheaddata);
+	
+	fclose(pSrcFile);
+	iret = 0;
+	return iret;
+}
+
+
+int rvc_free_data(void** pdechead)
+{
+	int iret = -1;
+
+	safe_free(*pdechead);
+
+	iret = 0;
+
+	return iret;
+}
+

+ 50 - 0
Other/win/libfilecryption/filecryption.h

@@ -0,0 +1,50 @@
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#ifdef LIBFILECRYPTION_EXPORTS
+#define FILECRYPTION_API(type)	_declspec(dllexport) type 
+#else
+#define FILECRYPTION_API(type)	_declspec(dllimport) type
+#endif
+
+#ifndef RVC_FILEENC_STR
+#define RVC_FILEENC_STR "enc_"
+#endif
+
+#ifndef RVC_FILEDEC_STR
+#define RVC_FILEDEC_STR "dec_"
+#endif
+
+//加密算法版本
+enum eRvcCryptionVersion{
+	eVerA,
+	eVerB,
+	eVerC,
+	eVerD
+};
+
+
+typedef struct filecryption_callback_s  {
+	void (*oncryptionexception)(void *user_data);
+	void (*oncryptionfinished)(void *user_data);
+	void (*dbg)(const char* fmt, ...);
+}filecryption_callback_t;
+
+
+#ifndef safe_log
+#define safe_log(x, strformat, ...) if (x && x->dbg){ x->dbg(strformat, ##__VA_ARGS__);}
+#endif
+
+
+FILECRYPTION_API(int) encryption_file(char* poutfile, size_t uoutlen, const char* pfilename, const filecryption_callback_t* pcallback, eRvcCryptionVersion eversion);
+FILECRYPTION_API(int) decryption_file(char* poutfile, size_t uoutlen, const char* pfilename, const filecryption_callback_t* pcallback = NULL, eRvcCryptionVersion eversion = eVerA);
+FILECRYPTION_API(bool) is_file_encrypted(const char* pfilename, const filecryption_callback_t* pcallback);
+FILECRYPTION_API(int) rvc_file_decrypt(unsigned char** pdechead, size_t* udecheadlen, int* ioffset, char** pstrjson, size_t* ujsonlen,const char* pfilename, const filecryption_callback_t* pcallback = NULL, eRvcCryptionVersion eversion = eVerA);
+FILECRYPTION_API(int) rvc_free_data(void** pdechead);
+#ifdef __cplusplus
+} // extern "C" {
+#endif

+ 153 - 0
Other/win/libfilecryption/rvcfileheader.cpp

@@ -0,0 +1,153 @@
+#include "stdafx.h"
+#include "rvcfileheader.h"
+#include "fileanalysis.h"
+#include <string.h>
+
+
+int constrcut_rvc_file_header(char* pbuffer, size_t* ulen, const char* pfilename, const filecryption_callback_t* pcallback, eRvcCryptionVersion eversion)
+{
+	int iret = -1;
+
+	//1. 自定义文件头标识16位
+	size_t udatalen = strlen(rvc_header);
+	memcpy(pbuffer, rvc_header, udatalen);
+	//2. 自定义文件头长度4位
+	udatalen += sizeof(size_t);
+	//3. 文件加密版本标识
+	const char* strheader = cryption_ver_flag_table[0];
+	if (eversion < sizeof(cryption_ver_flag_table)/sizeof(char*) && eversion >= 0){
+		strheader = cryption_ver_flag_table[eversion];
+	}
+	if (0 == fill_tag_buffer(pbuffer + udatalen, *ulen - udatalen, strheader, strlen(strheader))){
+		udatalen += (strlen(strheader) + sizeof(size_t));
+	}
+
+	//4. 源文件hash值
+	char strhash[RVC_FILE_HASH_LEN] = {0};
+	if (get_srcfile_hash(strhash, RVC_FILE_HASH_LEN, pfilename)){
+		safe_log(pcallback,"%s","get file hash failed!");
+		return iret;
+	}
+	if (0 == fill_tag_buffer(pbuffer + udatalen, *ulen - udatalen, strhash, RVC_FILE_HASH_LEN)){
+		udatalen += (RVC_FILE_HASH_LEN + sizeof(size_t));
+	}
+
+	//5. 源文件文件大小
+	unsigned long usize = get_srcfile_size(pfilename);
+	memcpy(pbuffer+udatalen, &usize, sizeof(unsigned long));
+	udatalen += sizeof(unsigned long);
+	safe_log(pcallback,"src file size is %d.",usize)
+	//6. 源文件文件名
+	char strname[MAX_PATH] = {0};
+	get_srcfile_name(strname, MAX_PATH, pfilename);
+	if (0 == fill_tag_buffer(pbuffer + udatalen, *ulen - udatalen, strname, strlen(strname))){
+		udatalen += (strlen(strname) + sizeof(size_t));
+	}
+	//7. 真实文件格式,后缀名
+	char strformat[MAX_PATH] = {0};
+	get_srcfile_format(strformat, MAX_PATH, pfilename);
+	if (0 == fill_tag_buffer(pbuffer + udatalen, *ulen - udatalen, strformat, strlen(strformat))){
+		udatalen += (strlen(strformat) + sizeof(size_t));
+	}
+	safe_log(pcallback,"file name is %s, and file format is %s.",strname, strformat);
+	*ulen = udatalen;
+	memcpy(pbuffer+RVC_FILE_HEADER_FLAG_LEN, &udatalen, sizeof(size_t));
+	iret = 0;
+	return iret;
+}
+
+
+int get_rvc_file_header_info(rvc_fileheader_t* pdata, char* pheadbuffer, size_t ulen, const filecryption_callback_t* pcallback)
+{
+	int iret = -1;
+	if (NULL == pheadbuffer){
+		return iret;
+	}
+	//3. 文件加密版本标识
+	size_t uindex = 0;
+	if (0 == get_tag_value_from_buffer(pdata->strcryptver, RVC_CRYPTION_VER_FLAG_LEN, pheadbuffer+uindex, ulen - uindex)){
+		uindex += (RVC_CRYPTION_VER_FLAG_LEN + sizeof(size_t));
+	}
+	else{
+		return iret;
+	}
+	//4. 源文件hash值
+	if (0 == get_tag_value_from_buffer((char*)pdata->strhash, RVC_FILE_HASH_LEN, pheadbuffer+uindex, ulen - uindex)){
+		uindex += (RVC_FILE_HASH_LEN + sizeof(size_t));
+	}
+	else{
+		return iret;
+	}
+	//5. 源文件文件大小
+	memcpy(&pdata->usrcfilelen, pheadbuffer+uindex, sizeof(unsigned long));
+	uindex += sizeof(unsigned long);
+	//6. 源文件文件名
+	if (0 == get_tag_value_from_buffer((char*)pdata->strsrcfilename, MAX_PATH, pheadbuffer+uindex, ulen - uindex)){
+		uindex += (strlen(pdata->strsrcfilename) + sizeof(size_t));
+	}
+	else{
+		return iret;
+	}
+	//7. 真实文件格式,后缀名
+	if (0 == get_tag_value_from_buffer((char*)pdata->strsrcfileformat, MAX_PATH, pheadbuffer+uindex, ulen - uindex)){
+		iret = 0;
+	}
+
+	return iret;
+}
+
+
+int fill_tag_buffer(char* pbuffer, size_t ubuffersize, const char* pdata, size_t udatalen)
+{
+	int iret = -1;
+	if (NULL == pdata || NULL == pbuffer){
+		return iret;
+	}
+
+	if (ubuffersize > udatalen + sizeof(size_t)){
+		memcpy(pbuffer, &udatalen, sizeof(size_t));
+		memcpy(pbuffer + sizeof(size_t), pdata, udatalen);
+		iret = 0;
+	}
+
+	return iret;
+}
+
+
+int get_tag_value_from_buffer(char* pbuffer, size_t ubuffersize, const char* pdata, size_t udatalen)
+{
+	int iret = -1;
+	if (NULL == pdata || NULL == pbuffer || udatalen < sizeof(size_t)){
+		return iret;
+	}
+
+	int idatalen = 0;
+	memcpy(&idatalen, pdata, sizeof(int));
+
+	if (udatalen >= idatalen + sizeof(size_t) && ubuffersize >= idatalen){
+		memcpy(pbuffer, pdata + sizeof(size_t), idatalen);
+		iret = 0;
+	}
+
+	return iret;
+}
+
+
+int get_key_from_header_info(unsigned char* pkey, size_t ukeysize, char* pheader, size_t udatalen, const filecryption_callback_t* pcallback)
+{
+	int iret = -1;
+
+	rvc_fileheader_t t_param = {0};
+	if (0 != get_rvc_file_header_info(&t_param, pheader, udatalen, pcallback)){
+		safe_log(pcallback, "%s", "get rvc file header infos failed!");
+		return iret;
+	}
+
+	unsigned char strkey[SM4ENC_BLOCK_SIZE] = {0};
+	if (0 == GenerateSM4Key(strkey, SM4ENC_BLOCK_SIZE, t_param.strhash, RVC_FILE_HASH_LEN, t_param.usrcfilelen)){
+		//safe_log(pcallback, "%s", "Generate SM4Key success!");
+		iret = 0;
+	}
+
+	return iret;
+}

+ 54 - 0
Other/win/libfilecryption/rvcfileheader.h

@@ -0,0 +1,54 @@
+#pragma once
+#include <stdio.h>
+#include "filecryption.h"
+
+#ifndef RVC_FILE_HEADER_FLAG_LEN
+#define RVC_FILE_HEADER_FLAG_LEN	16
+#endif
+
+#ifndef RVC_FILE_HASH_LEN
+#define RVC_FILE_HASH_LEN 32
+#endif
+
+#ifndef RVC_CRYPTION_VER_FLAG_LEN
+#define RVC_CRYPTION_VER_FLAG_LEN		8
+#endif
+
+
+// {5565B9BA-2953-4F19-B05A-0F179287DB2D}
+static const char rvc_header[] = {0x55, 0x65, 0xb9, 0xba, 0x29, 0x53, 0x4f, 0x19, 0xb0, 0x5a, 0x0f, 0x17, 0x92, 0x87, 0xdb, 0x2d, 0x0};
+
+static const char* cryption_ver_flag_table[] = {
+	"rvcfilea",
+	"rvcfileb",
+	"rvcfilec",
+	"rvcfiled"
+};
+
+/*添加的自定义文件头信息
+1. 自定义文件头标识16位
+2. 自定义文件头长度4位
+3. 文件加密版本标识
+4. 源文件hash值
+5. 源文件文件大小
+6. 源文件文件名
+7. 真实文件格式,后缀名
+*/
+
+
+typedef struct rvc_fileheader_s{
+	unsigned char strhead[RVC_FILE_HEADER_FLAG_LEN];
+	size_t uheadlen;
+	char strcryptver[RVC_CRYPTION_VER_FLAG_LEN];
+	unsigned char strhash[RVC_FILE_HASH_LEN];
+	unsigned long usrcfilelen;
+	char strsrcfilename[MAX_PATH];
+	char strsrcfileformat[MAX_PATH];
+}rvc_fileheader_t;
+
+int constrcut_rvc_file_header(char* pbuffer, size_t* ulen, const char* pfilename, const filecryption_callback_t* pcallback, eRvcCryptionVersion eversion);
+// pheadbuffer从自定义的文件头的字段3,文件加密版本标识初开始
+int get_rvc_file_header_info(rvc_fileheader_t* pdata, char* pheadbuffer, size_t ulen, const filecryption_callback_t* pcallback);
+int fill_tag_buffer(char* pbuffer, size_t ubuffersize, const char* pdata, size_t udatalen);
+int get_tag_value_from_buffer(char* pbuffer, size_t ubuffersize, const char* pdata, size_t udatalen);
+int get_key_from_header_info(unsigned char* pkey, size_t ukeysize, char* pheader, size_t udatalen, const filecryption_callback_t* pcallback);

+ 8 - 0
Other/win/libfilecryption/stdafx.cpp

@@ -0,0 +1,8 @@
+// stdafx.cpp : 只包括标准包含文件的源文件
+// libimageproc.pch 将作为预编译头
+// stdafx.obj 将包含预编译类型信息
+
+#include "stdafx.h"
+
+// TODO: 在 STDAFX.H 中
+// 引用任何所需的附加头文件,而不是在此文件中引用

+ 15 - 0
Other/win/libfilecryption/stdafx.h

@@ -0,0 +1,15 @@
+// stdafx.h : 标准系统包含文件的包含文件,
+// 或是经常使用但不常更改的
+// 特定于项目的包含文件
+//
+
+#pragma once
+
+#if defined(_MSC_VER)
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN             //  从 Windows 头文件中排除极少使用的信息
+#endif //WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif //_MSC_VER
+
+// TODO: 在此处引用程序需要的其他头文件