小端数据和 sha 256
我必须生成小端形式的数据的 sha256 哈希值。我想知道在使用 sha 256 算法之前是否必须先将其转换为大端字节序。或者,如果该算法是“字节序无关的”。
编辑:抱歉,我想我不清楚。我想知道的是: sha256 算法需要用某些位填充消息的末尾。第一步是在消息末尾添加 1。然后,用零填充它直到末尾。最后,您必须添加消息的长度(以位为单位)。我想知道的是这种填充是否可以以小端方式执行。例如,对于 640 位消息,我可以将最后一个字写为 0x280(大端)或 0x8002000(小端)。这个填充可以用小尾数法完成吗?
I have to generate sha256 hashes of data that is in little endian form. I would like to know if I have to convert it to big endian first, before using the sha 256 algorithm. Or if, the algorithm is "endian-agnostic".
EDIT: Sorry, I think I wasnt clear. What I would like to know is the following: The sha256 algorithm requires to pad the end of a message with certain bits. The first step is to add a 1 at the end of the message. Then, to pad it with zero up to the end. At the very end, you must add the length of the message in bits. What I would like to know is if this padding can be performed in little endian. For example, for a 640 bit message, I could write the last word as 0x280 (in big endian), or 0x8002000 (in little endian). Can this padding be done in little endian?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
发布评论
评论(3)
SHA-256 实现本身应该负责填充 - 除非您正在实现自己的专用 SHA-256 代码,否则您不必处理这个问题。如果是,请注意“预处理步骤”中指定的填充规则表示长度是 64 位大端整数。请参阅 SHA-2 - 维基百科
甚至很难弄清楚“与字节序无关”会是什么意思是,但是哈希算法的所有位、字节和单词的顺序非常重要,所以我肯定不会使用这个术语。
让我回复一下 sha 256 和 sha 512。
简而言之:
该算法本身与字节序无关。字节序敏感部分是数据从字节缓冲区导入到算法工作变量时以及导出回摘要结果(也是字节缓冲区)时。如果导入/导出包括转换,则字节序很重要。
铸造可能发生在哪里:
在 sha 512 中,有一个 128 字节的工作缓冲区。
在我的代码中,其定义如下:
union
{
U64 w [80]; (see U64 example below)
byte buffer [128];
};
输入数据被复制到此字节缓冲区,然后在 W 上完成工作。这意味着数据被转换为某种 64 位类型。该数据必须被交换。就我而言,它被替换为小端机器。
更好的方法是准备一个 get 宏,该宏获取每个字节并将其放置在 u64 类型中的正确位置。
当算法完成时,摘要结果从工作变量输出到某个字节缓冲区,如果这是由 memcpy 完成的,那么它也必须被交换。
在 32 位机器上实施 sha 512(专为 64 位机器设计)时,可能会发生另一次转换。在我的例子中,我定义了一个 64 位类型:
typedef struct {
uint high;
uint low;
} U64;
假设我也为小端定义它,如下所示:
typedef struct {
uint low;
uint high;
} U64;
然后 k 算法初始化是这样完成的:
static const SHA_U64 k[80] =
{
{0xD728AE22, 0x428A2F98}, {0x23EF65CD, 0x71374491}, ...
...
...
}
但我需要 k[0].high 的逻辑值在任何机器上都是一样的。
因此,在这个例子中,我需要另一个 k 数组,其中高值和低值交换。
将数据存储在工作参数中后,任何按位操作在大/小端机器上都会产生相同的结果。
好的方法是避免任何强制转换:
使用宏将字节从输入缓冲区导入到您的工作参数。
使用逻辑值而不考虑内存映射。
使用宏导出输出以摘要结果。
用于从字节缓冲区获取 32 位到 int32 的宏(BE = big endian):
#define GET_BE_BYTES_FROM32(a)
((((NQ_UINT32) (a)[0]) << 24) |
(((NQ_UINT32) (a)[1]) << 16) |
(((NQ_UINT32) (a)[2]) << 8) |
((NQ_UINT32) (a)[3]))
#define GET_LE_BYTES_FROM32(a)
((((NQ_UINT32) (a)[3]) << 24) |
(((NQ_UINT32) (a)[2]) << 16) |
(((NQ_UINT32) (a)[1]) << 8) |
((NQ_UINT32) (a)[0]))
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如果您想要的只是一个好的哈希值,那么 SHA256 与字节序无关。但如果您正在编写 SHA256 并希望通过正确的实现获得相同的结果,那么您必须在小端硬件上玩游戏。 SHA256 结合了算术加法(mod 2*32)和布尔运算,因此内部与字节序无关。
SHA256 is endian-agnostic if all you want is a good hash. But if you are writing SHA256 and want to the same results with a correct implementation then you must play games on little endian hardware. SHA256 combines arithmetic addition (mod 2*32) and boolean operation thus is not endian-agnostic internally.