一般文件的完整性要使用md5或者sha进行完整性校验,这里提供两个函数,
intact_update_sha 是计算指定文件SHA值并保存到SHA文件
intact_check_sha 计算文件SHA值并和SHA文件进行对比
编译方法:
gcc demo.c -lssl -lcrypto
#include
#include
#include
#include
#include
#include
#include
#include
enum {
ERR_OK,
ERR_FAIL,
ERR_OPEN,
ERR_OPEN_SHA,
ERR_PATH,
ERR_PARAM,
ERR_NOEXIST,
ERR_NOEXIST_SHA,
ERR_KEY,
ERR_MALLOC,
};
#define MAX_BUFFER_SIZE 1024
#define SHA_FILE_PATH "/home/hfs/sha/%s.sha"
#define SHA_FILE_DIR "/home/hfs/sha"
static int intact_get_sha_file_path(char *path)
{
int offset = 0;
for (int i = 0; i < strlen(path); i++) {
if (*(path + i) == '/')
offset = i;
}
return offset;
}
int intact_check_sha(char *path)
{
SHA256_CTX ctx;
char buffer[MAX_BUFFER_SIZE];
char sha_str[MAX_BUFFER_SIZE];
int len = 0;
FILE *fp = NULL;
FILE *fp_sha = NULL;
unsigned char sha[SHA256_DIGEST_LENGTH];
char tmp[MAX_BUFFER_SIZE] = {0};
char sha_file[MAX_BUFFER_SIZE] = {0};
int offset;
if (path == NULL) {
return ERR_PARAM;
}
if (access(path, F_OK)) {
return ERR_NOEXIST;
}
strcpy(tmp, path);
if (tmp[strlen(tmp) - 1] == '/') {
tmp[strlen(tmp) - 1] = '\0';
}
offset = intact_get_sha_file_path(tmp);
if (offset == 0) {
return ERR_PATH;
}
sprintf(sha_file, SHA_FILE_PATH, tmp + offset + 1);
if (access(sha_file, F_OK)) {
return ERR_NOEXIST_SHA;
}
fp = fopen(path, "r");
if (fp == NULL) {
return ERR_OPEN;
}
fp_sha = fopen(sha_file, "r");
if (fp == NULL) {
fclose(fp);
fp = NULL;
return ERR_OPEN_SHA;
}
SHA256_Init(&ctx);
while ((len = fread(buffer, 1, MAX_BUFFER_SIZE, fp)) > 0) {
SHA256_Update(&ctx, buffer, len);
memset(buffer, 0, sizeof(buffer));
}
SHA256_Final(&(sha[0]), &ctx);
sprintf(sha_str, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
sha[0], sha[1], sha[2], sha[3], sha[4], sha[5], sha[6], sha[7],
sha[8], sha[9], sha[10], sha[11], sha[12], sha[13], sha[14], sha[15]);
fread(buffer, 1, MAX_BUFFER_SIZE, fp_sha);
if (strncmp(sha_str, buffer, 32) == 0) {
fclose(fp);
fp = NULL;
fclose(fp_sha);
fp_sha = NULL;
return ERR_OK;
}
fclose(fp);
fp = NULL;
fclose(fp_sha);
fp_sha = NULL;
return ERR_FAIL;
}
int intact_update_sha(char *path)
{
SHA256_CTX ctx;
char buffer[MAX_BUFFER_SIZE];
char sha_str[MAX_BUFFER_SIZE] = {0};
int len = 0;
FILE *fp = NULL;
FILE *fp_sha = NULL;
unsigned char sha[SHA256_DIGEST_LENGTH];
char tmp[MAX_BUFFER_SIZE] = {0};
char sha_file[MAX_BUFFER_SIZE] = {0};
int offset;
if (path == NULL) {
return ERR_PARAM;
}
if (access(path, F_OK)) {
return ERR_NOEXIST;
}
strcpy(tmp, path);
if (tmp[strlen(tmp) - 1] == '/') {
tmp[strlen(tmp) - 1] = '\0';
}
offset = intact_get_sha_file_path(tmp);
if (offset == 0) {
return ERR_PATH;
}
sprintf(sha_file, SHA_FILE_PATH, tmp + offset + 1);
if (access(SHA_FILE_DIR, F_OK)) {
mkdir(SHA_FILE_DIR, S_IRUSR | S_IWUSR | S_IXUSR);
}
fp = fopen(path, "r");
if (fp == NULL) {
return ERR_OPEN;
}
fp_sha = fopen(sha_file, "w+");
if (fp == NULL) {
fclose(fp);
fp = NULL;
return ERR_OPEN_SHA;
}
SHA256_Init(&ctx);
while ((len = fread(buffer, 1, MAX_BUFFER_SIZE, fp)) > 0) {
SHA256_Update(&ctx, buffer, len);
memset(buffer, 0, sizeof(buffer));
}
SHA256_Final(&(sha[0]), &ctx);
sprintf(sha_str, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
sha[0], sha[1], sha[2], sha[3], sha[4], sha[5], sha[6], sha[7],
sha[8], sha[9], sha[10], sha[11], sha[12], sha[13], sha[14], sha[15]);
fwrite(sha_str, 1, MAX_BUFFER_SIZE, fp_sha);
fclose(fp);
fp = NULL;
fclose(fp_sha);
fp_sha = NULL;
return ERR_OK;
}