在现代计算机网络中,数据在传输中经常面临被篡改、丢失、重放等问题,为了确保数据的完整性,我们引入完整性校验机制。本文将从完整性校验的定义、数据存储完整性校验、完整性校验值的获取、完整性校验值的作用、完整性校验的使用方法等多个方面进行详细的阐述。

一、完整性校验的方法

完整性校验是通过计算校验和、散列值或者消息认证码的方法来检查数据的完整性。下面来分别介绍这三种方法:

1.计算校验和

计算校验和是一种对数据完整性简单检查的方法,主要应用在数据链路层(如以太网)或网络层(如IP)。计算校验和的方法是对数据段进行二进制加法,得到一个累加和,再将结果在补1的意义下截断为16位,最终得到校验和。当数据传输到接收方时,接收方进行差错检测时同样计算其校验和,如果接收方计算得到的校验和与传输过来的数据包中的校验和不一致,则表明数据已经被损坏或者被篡改。


/* 计算IP数据包的校验和 */
unsigned short checksum (unsigned short *buffer, int size) {
    unsigned long cksum = 0;
    while (size > 1) {
        cksum += *buffer++;
        size -= sizeof(unsigned short);
    }
    if (size) {
        cksum += *(unsigned char*)buffer;
    }
    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum = (cksum >> 16) + cksum;
    return (unsigned short)(~cksum);
}

2.散列值

散列值,也称哈希值,是一种数据完整性检验的高级算法。散列值是通过摘要算法计算出来的,一般来说,这个过程是不可逆的。常见的摘要算法有MD5、SHA1、SHA256等。对于一个给定的数据块,它的散列值是唯一的,只要数据块的内容发生了一点变化,那么这个散列值也会发生很大变化。因此,散列值在数字签名、密码学、数据完整性检查等方面有着广泛应用。


/* 计算字符串的MD5散列值 */
#include<openssl/md5.h>
#include<stdio.h>
#include<string.h>

void calc_md5(char *str, char *md5sum) {
    unsigned char digest[16];
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, str, strlen(str));
    MD5_Final(digest, &ctx);
    for (int i = 0; i < 16; i++) {
        sprintf(&md5sum[i*2], "%02x", (unsigned int)digest[i]);
    }
}

3.消息认证码

消息认证码是一种加密技术,用于检验数据传输的完整性和真实性。消息认证码通常需要一个密钥,算法将密钥与数据一起作为输入进行计算,以便无法知道密钥的第三方无法修改数据而不一致修改消息认证码。常用的消息认证码算法有HMAC-MD5、HMAC-SHA1、HMAC-SHA2等。


/* 计算字符串的HMAC-MD5 */
#include<openssl/hmac.h>
#include<string.h>

#define KEY "mykey"
#define KEYLEN strlen(KEY)

void calc_hmac(char *str, char *hmac) {
    unsigned char digest[EVP_MAX_MD_SIZE];
    unsigned int len = 0;
    HMAC(EVP_md5(), KEY, KEYLEN, (unsigned char *)str, strlen(str), digest, &len);
    for (int i = 0; i < len; i++) {
        sprintf(&hmac[i*2], "%02x", (unsigned int)digest[i]);
    }
}

二、数据存储完整性校验

数据存储完整性校验的主要目标是保证数据在存储介质上的完整性,主要针对的是数据丢失、损坏、篡改等情况。在这种情况下,计算和校验方法已经无法保证数据的完整性。常用的方法是在存储数据前计算其散列值,存储散列值和数据,在读取数据时再重新计算散列值,并根据计算出的散列值和存储时的散列值进行比较,以确保数据的完整性。


/* 计算文件的MD5散列值 */
#include<openssl/md5.h>
#include<stdio.h>
#include<stdlib.h>

void calc_file_md5(char *file, char *md5sum) {
    FILE *fp;
    unsigned char buffer[1024];
    int nread;
    MD5_CTX ctx;
    unsigned char digest[16];
    fp = fopen(file, "rb");
    if (fp == NULL) {
        return;
    }
    MD5_Init(&ctx);
    while ((nread = fread(buffer, 1, sizeof(buffer), fp))) {
        MD5_Update(&ctx, buffer, nread);
    }
    MD5_Final(digest, &ctx);
    for (int i = 0; i < 16; i++) {
        sprintf(&md5sum[i*2], "%02x", (unsigned int)digest[i]);
    }
    fclose(fp);
}

三、完整性校验值如何获取

完整性校验值可以通过上述介绍的三种完整性校验方法中的一种方法来获取。当然,在不同应用场景下,不同的方法会有不同的适用性。一些常见的获取完整性校验值的方法包括:

1.文件散列值生成工具

在文件传输或者存储时,可以使用MD5、SHA1等工具计算文件的散列值,并将计算结果保存下来,方便后续校验使用。例如,在Linux系统下可以使用md5sum命令来计算文件的MD5值,并将结果输出到文件当中。


$ md5sum myfile.txt > myfile.md5

2.在线完整性校验工具

一些在线工具如MD5在线生成器、SHA1在线生成器等,可以帮助用户计算数据的完整性校验值。用户只需将数据粘贴或者上传到在线工具当中,即可得到相应的校验值。

四、完整性校验值的作用

完整性校验值是用于校验数据完整性的重要参数。一方面,在数据传输过程中,如果接收方计算得到的校验值与发送方发送的数据包中的校验值不一致,则表明数据在传输过程中可能被篡改、丢失或损坏;另一方面,对于重要数据的存储,计算存储时的散列值,可用于判断数据是否已被篡改。

五、完整性校验怎么用

在实际应用过程中,完整性校验可以通过如下几个步骤来应用:

1.计算完整性校验值

在数据传输之前或者数据存储之前,可以使用MD5、SHA1、消息认证码等方法计算完整性校验值。

2.发送或存储数据和完整性校验值

将数据和计算得到的完整性校验值分别传输或存储到接收方。

3.接收方计算完整性校验值并比较

接收方使用与发送方相同的完整性校验算法计算数据的完整性校验值,并与发送方发送的完整性校验值进行比较。如果两个值一致,则表明数据是完整的。

六、完整性校验值类型

常用的完整性校验值类型包括MD5、SHA1、SHA256等。在具体应用场景中,需要根据数据安全要求选择合适的完整性校验值类型。例如,在密码存储方面,常用的是SHA256。

七、完整性校验值怎么填写

完整性校验值的填写根据实际场景和应用的算法不同而有所差异。例如,在HTTP请求中,完整性校验值可以通过在请求头中添加一个字段,如如下代码所示:


GET /index.html HTTP/1.1
Host: www.example.com
Checksum: MD5:1234567890

在这个例子中,完整性校验值的类型是MD5,值为1234567890。

八、完整性校验值怎么生成

在生成完整性校验值的过程中,需要根据具体算法的要求来计算。以MD5为例:


/* 计算字符串的MD5散列值 */
#include<openssl/md5.h>
#include<stdio.h>
#include<string.h>

void calc_md5(char *str, char *md5sum) {
    unsigned char digest[16];
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, str, strlen(str));
    MD5_Final(digest, &ctx);
    for (int i = 0; i < 16; i++) {
        sprintf(&md5sum[i*2], "%02x", (unsigned int)digest[i]);
    }
}

如果要对文件进行完整性校验,则只需要将fopen函数打开文件句柄代入MD5_Update即可。

九、完整性校验下载文件失败

在下载文件时,完整性校验往往是一个必要的步骤。例如,在下载安装包、电影、音乐等文件时,下载过程中发生网络中断、服务器宕机等情况是很常见的,这些情况均可能导致下载的文件不完整。当我们从下载的文件中运行某个程序或者播放音乐时,很容易因为文件损坏而导致运行失败。

这时,完整性校验就非常有用。如果下载的文件附有完整性校验值,我们可以很方便地使用校验值进行校验。如果校验失败,则表明所下载的文件已被篡改、丢失或损坏,我们应该重新下载文件。常用的下载工具如wget、curl等均支持下载完整性校验值。

结论

完整性校验,是现代计算机网络中的关键技术之一,具有广泛的应用场景。本文从完整性