c语言中的SHA256实现
Posted
技术标签:
【中文标题】c语言中的SHA256实现【英文标题】:SHA256 implementation in c 【发布时间】:2014-04-05 12:02:35 【问题描述】:我正在尝试从这个网站编程 SHA256 实现:http://bradconte.com/sha256_c 在 MSP430 MCU 板上。我正在使用开源 Energia IDE 进行编程。
这是测试代码:
unsigned char hash[32];
SHA256_CTX ctx;
sha256_init(&ctx);
sha256_update(&ctx,(unsigned char*)"abc",3);
sha256_final(&ctx,hash);
PrintHex(hash);
这将转换为十六进制
void PrintHex(unsigned char * data)
char tmp[16];
for (int i=0; i<32; i++)
sprintf(tmp, "%02x",data[i]);
Serial.print(tmp);
问题是输出总是一个错误的哈希码。
这是输出:
2bb53935edbba17dc04a04854518754d8a66484491b585b0d0700cd2512f5420
是测试代码还是我在这里做错了什么?
【问题讨论】:
您的预期结果是什么? 这是预期的:ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
用于 abc 字符
您能否使用普通编译器在您的桌面上测试您的代码,看看是否可行?
它在普通编译器中工作。那么问题可能是代码在IDE中无法正常工作?
我尝试在 16 位裸机平台 (St10) 上使用此代码并遇到完全相同的问题。
【参考方案1】:
我在我的系统(Mac OS X,x86 64 位)上运行了该代码,它给了我这个:
551ce4769446b343295ea7f819ba1c5557545e29a4de545746b2b246a9831f22
我认为我们可以安全地假设代码是垃圾:我使用一些在线工具验证了 ba7816b... 是正确的哈希值,现在我们看到您的平台和我的平台都产生了不同的结果。我注意到代码中有一些关于字节序的注释,所以我查了一下,你的系统也是小字节序的,所以这应该不是问题。我建议您寻找不同的实现方式。
【讨论】:
没那么快,问题是他假设 ulong 正好有 32 位——这在嵌入式系统上可能是有意义的,但在大多数计算机上却失败了;修复它会给我正确的结果。关于字节序:它是否说明了他假设的平台? @pattex007 如果代码确实无法使用,skalibs 有一个声称与字节顺序无关的实现,并且作者非常关心让他的代码在嵌入式系统上运行。 如何从“hash”变量中获取摘要? 我刚刚在 MacOS 10.11.3 上构建了这段代码,我得到了预期的结果,所以不幸的是,我会否决你的答案。【参考方案2】:你不应该假设字符串编码在 C 中是可移植的。
试试这个代码:
unsigned char message[] = 0x61, 0x62, 0x63;
unsigned char hash[32];
SHA256_CTX ctx;
sha256_init(&ctx);
sha256_update(&ctx,message,sizeof message);
sha256_final(&ctx,hash);
PrintHex(hash);
【讨论】:
【参考方案3】:我的意思是原来的网站不再有效,但我认为我有相同的实现,我在 MSP430 上遇到了同样的问题。问题是很久以前提出的,但仍然有人可能遇到类似的麻烦。
/*********************************************************************
* Filename: sha256.c
* Author: Brad Conte (brad AT bradconte.com)
因此,必须在原始实现中进行一些额外的更改,才能正确计算 MSP430 上的 SHA256 和。它可能取决于编译器 - 目前我使用的是 Texas CCStudio 的一个,这绝对不是 GNU GCC。
首先,sha256.h 文件应该修改如下:
...
/*************************** HEADER FILES ***************************/
#include <stdint.h>
/****************************** MACROS ******************************/
#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
/**************************** DATA TYPES ****************************/
typedef uint8_t BYTE; // 8-bit byte
typedef uint32_t WORD; // 32-bit word, change to "long" for 16-bit machines
typedef struct
BYTE data[64];
WORD datalen;
uint64_t bitlen;
WORD state[8];
SHA256_CTX;
...
在 16 位机器上 unsigned int 是一个没有符号的 16 位整数。所以将 WORD typedef 替换为合适的类型。我认为这很糟糕,使用自己的 WORD 和 BYTE 定义,它们在 stdint.h 头文件中可用。
其次,我认为 sha256_transform 的实现编码错误。 BYTE 上存在按位运算,结果超出比例。
在执行按位运算之前在 BYTE 上添加显式转换后,所有实现都可以在 MSP430 MCU 上正常运行。请看下面的代码:
/*********************** FUNCTION DEFINITIONS ***********************/
void sha256_transform ( SHA256_CTX *ctx, const BYTE data[] )
WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
for ( i = 0, j = 0; i < 16; ++i, j += 4)
/* Add explicit (WORD) conversion before operating on bytes */
m[i] = ((WORD)data[j] << 24) | ((WORD)data[j + 1] << 16) | ((WORD)data[j + 2] << 8) | ((WORD)data[j + 3]);
for ( ; i < 64; ++i)
m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
a = ctx->state[0];
b = ctx->state[1];
我希望这可以帮助某人解决问题。
【讨论】:
以上是关于c语言中的SHA256实现的主要内容,如果未能解决你的问题,请参考以下文章