是否可以组合多个SHA1状态以在Golang中获得最终状态?

是否可以组合多个SHA1状态以在Golang中获得最终状态?,go,cryptography,Go,Cryptography,在Go1.13中,我有一个上传服务器。此服务器接受两种类型的上载 分块和分块+线程。在分块上传时,一切正常。当它们写入磁盘时,我计算每个数据块。用户可以按良好顺序逐个上传多个区块 这意味着,我可以使用BinaryMarshaler将每个块的SHA1状态保存到磁盘,然后读取上一个状态并继续计算下一个块,直到找到最终哈希。最后的散列给了我整个文件的SHA1 当它被排序时,我可以附加到现有状态。但问题从线程开始。。。。(同时) hashComplete:=sha256.New() //从磁盘读取以前的

Go1.13
中,我有一个上传服务器。此服务器接受两种类型的上载

分块分块+线程。在分块上传时,一切正常。当它们写入磁盘时,我计算每个数据块。用户可以按良好顺序逐个上传多个区块

这意味着,我可以使用
BinaryMarshaler
将每个块的
SHA1
状态保存到磁盘,然后读取上一个状态并继续计算下一个块,直到找到最终哈希。最后的散列给了我整个文件的
SHA1

当它被排序时,我可以附加到现有状态。但问题从线程开始。。。。(同时)

hashComplete:=sha256.New()
//从磁盘读取以前的状态
状态,err:=ioutil.ReadFile(ctxPath)
如果出错!=零{
返回错误
}
如果len(state)>0{
解组器,:=hashComplete。(encoding.BinaryUnmarshaler)
如果错误:=unmarshaler.unmarshalbary(状态);错误!=nil{
返回错误
}
}
//在这里我写文件到磁盘和散列。文件对象是简单文件。
writer:=io.MultiWriter(文件,哈希完成)
n、 err:=io.Copy(writer,src)//src是源(io.Reader)
封送拆收器,\ u0:=hashComplete。(encoding.BinaryMarshaler)
newState,err:=marshaler.MarshalBinary()
如果出错!=零{
返回错误
}
shaCtxFile.Write(newState)//这里我正在将最后一个状态保存到磁盘。
//然后,在上传完成后,我阅读了这个文件并从中获得了SHA1十六进制。这是正确的。
现在,这是按特定/良好顺序分块上传的。另一种上传方法是分块+线程。这意味着,用户可以同时上传数据块,然后发送一个请求,按照给定的顺序(在最后一次请求时)将它们连接在一起

我已经计算了每个区块的
SHA1
,并将其保存到磁盘


我的问题是否可以合并这些状态并获得最终哈希值,或者在连接后是否需要重新哈希值。有没有一种方法可以组合这些状态?

假设您指的是整个文件的最终散列,那么没有,您不能组合部分数据的多个SHA-1散列来创建整个文件的散列,就好像它是一次性计算的一样。这是因为初始SHA-1状态始终相同,重新灰化将在该特定状态下重新启动。此外,在计算最终散列值之前,填充最终块并添加长度(散列函数的内部)

但是,您当然可以创建哈希列表或哈希树,在其中定义块的大小。然后可以对块上的所有哈希进行散列,以创建最顶端的哈希值。现在,您的哈希值与文件上的SHA-1不同,但是哈希值与您的定义一致,并且可以重新计算,即使是以多线程方式。它对于文件中的数据仍然是唯一的(当然,假设它按顺序放入散列值),因此可以使用它来验证文件的完整性。而且,据我所知,这是普通安全哈希函数使用多线程哈希计算的唯一方法

有关更多信息,请访问谷歌



当然,SHA-1在抗碰撞方面已被破坏。不幸的是,这正是你使用它的目的。所以请使用SHA-256。如果256位太多,那么使用SHA-256并获取最左边的160位是更安全的选择。

明白了。我肯定会切换到SHA256。我认为,当我们将状态对象保存到磁盘时,可以将它们组合起来。但在阅读了你的答案后,现在它是有意义的。对于散列,我需要它来保证文件的完整性。所以,unique hash无论如何也帮不了我。我使用UUIDv4标识符实现唯一性。安全哈希值被认为是唯一的,因为不可能或应该不可能创建冲突。这就是提供完整性所需要的,至少在假设攻击者时是这样。例如,对于传输错误,CRC可能更有效,更擅长纠正多位错误(因为散列值本身也可能通过错误而改变,CRC也考虑到了这一点)。很高兴听到这一点,因为在这个应用中,我也有CRC。感谢您提供的宝贵信息。CRC足够快,两种方法都可以使用。只要您使用CRC进行错误检测,并使用SHA-256防止故意更改。当然,散列只有在可以与数据分开验证的情况下才能提供保护,否则攻击者只能同时更改这两种数据。如果您必须将其存储在数据旁边,那么您应该使用签名(如果需要,可以通过散列)。现在就实现这一点。再次感谢。