1、如何验证文件是否被修改过
- 只生成一个指纹文件,对指纹文件进行验证
- 当已经存储的文件被修改之后,指纹文件就会跟着变化,即生成一个单向散列函数
- 任意长度的数据都对应固定长度的散列值–减少匹配开销
- 散列值可以随着消息的变化发生改变–方便进行验证修改
- 散列值单项不可逆,可抗碰撞
2、单向hash抗碰撞
(1)所有的函数都要满足弱抗碰撞
给定X和hash值的情况下,不能找到另外一个数与前面hash值相同
(2)强抗碰撞(是可以暴力破解的)
在攻击时,可以设计两个散列值相同的字符串,就可以替换原来的文件信息(MD5、SHA-1 已经被攻破)
3、基于MD5算法检测文件hash值
string GetFileListHash(string filepath) //拿到文件列表哈希值,哈希值都是二进制,字符串String可以用来存储哈希值
{
string hash;
//以二进制方式打开文件
ifstream ifs(filepath, ios::binary);//binary以二进制的方式打开,ifstream是C++文件流的访问方式
if (!ifs)
return hash;
//一次读取多少字节的文件
int block_size = 128;//定义一块的哈希值长度,然后将所有哈希值块拼起来获得哈希值
//文件读取buf
unsigned char buf[1024] = {
0 };
//hash输出
unsigned char out[1024] = {
0 };
while (!ifs.eof())//eof()是都到结尾的意思
{
ifs.read((char*)buf, block_size);
int read_size = ifs.gcount();// 拿到读取的大小数量
if (read_size <= 0)break;
MD5(buf, read_size, out);//简化接口
hash.insert(hash.end(), out, out + 16);//hash.end()是插入的位置(结尾处),out是插入的内容,out+16是结束指针,生成了大串哈希
}//一个哈希是十六字节
ifs.close();
MD5((unsigned char*)hash.data(), hash.size(), out);
return string(out,out+16);
}
4、程序结果
文件未被修改时:
文件被修改时: