以下代码引用( C语言中的HMAC_SHA1加密方法-源码 )历程,并删掉测试函数,便于自己理解罢了.详细请参考原文.(本历程可在NodeMCU上运行 Arduino IDE版本:1.8.9)
删除的函数后的:
1. #define NUM_TEST_CASES 10//有多少条要加密的
2. int test_case_length[];//消息内容长度
3. unsigned char test_cases[];//消息内容
4. int key_lengths[] ;//key长度
5. unsigned char keys[];//key内容
6. int get_testcase(int test_case, unsigned char *plaintext, unsigned char *key, int *key_length_ptr);//用于在同一个数组包涵多个消息 \ key时选择用返回为消息内容长度 我只用单一个所以无用
7.
#ifdef HMAC_DEBUG
Debug out (unsigned char *label, unsigned char *data, int data_length);//用于调试输出
#endif
8. 所有
#ifdef HMAC_DEBUG
***************
#endif
删除后的hmac_sha1.c文件:
#include <stdlib.h>
#include <stdio.h>
#define MAX_MESSAGE_LENGTH 4096//最大消息长度
/********************************************/
/* Test Cases */
/* An array of test cases taken from the */
/* 802.11i specification. */
/********************************************/
unsigned char digest[20]={0};//最终生成的缓存 算完之后是 20 字节的摘要信息
/*****************************/
/**** Function Prototypes ****/
/*****************************/
unsigned long int ft(
int t,
unsigned long int x,
unsigned long int y,
unsigned long int z
);
int get_testcase( int test_case,
unsigned char *plaintext,
unsigned char *key,
int *key_length_ptr);
void sha1 (
unsigned char *message,
int message_length,
unsigned char *digest
);
/****************************************/
/* sha1() */
/* Performs the NIST SHA-1 algorithm */
/****************************************/
unsigned long int ft(
int t,
unsigned long int x,
unsigned long int y,
unsigned long int z
)
{
unsigned long int a,b,c;
if (t < 20) {
a = x & y;
b = (~x) & z;
c = a ^ b;
}
else if (t < 40) {
c = x ^ y ^ z;
}
else if (t < 60) {
a = x & y;
b = a ^ (x & z);
c = b ^ (y & z);
}
else if (t < 80) {
c = (x ^ y) ^ z;
}
return c;
}
unsigned long int k(int t){
unsigned long int c;
if (t < 20) {
c = 0x5a827999;
}
else if (t < 40) {
c = 0x6ed9eba1;
}
else if (t < 60) {
c = 0x8f1bbcdc;
}
else if (t < 80) {
c = 0xca62c1d6;
}
return c;
}
unsigned long int rotr(int bits, unsigned long int a){
unsigned long int c,d,e,f,g;
c = (0x0001 << bits)-1;
d = ~c;
e = (a & d) >> bits;
f = (a & c) << (32 - bits);
g = e | f;
return (g & 0xffffffff );
}
unsigned long int rotl(int bits, unsigned long int a){
unsigned long int c,d,e,f,g;
c = (0x0001 << (32-bits))-1;
d = ~c;
e = (a & c) << bits;
f = (a & d) >> (32 - bits);
g = e | f;
return (g & 0xffffffff );
}
void sha1 (
unsigned char *message,
int message_length,
unsigned char *digest
)
{
int i;
int num_blocks;
int block_remainder;
int padded_length;
unsigned long int l;
unsigned long int t;
unsigned long int h[5];
unsigned long int a,b,c,d,e;
unsigned long int w[80];
unsigned long int temp;
/* Calculate the number of 512 bit blocks */
padded_length = message_length + 8; /* Add length for l */
padded_length = padded_length + 1; /* Add the 0x01 bit postfix */
l = message_length * 8;
num_blocks = padded_length / 64;
block_remainder = padded_length % 64;
if (block_remainder > 0) {
num_blocks++;
}
padded_length = padded_length + (64 - block_remainder);
/* clear the padding field */
for (i = message_length; i < (num_blocks * 64); i++){
message[i] = 0x00;
}
/* insert b1 padding bit */
message[message_length] = 0x80;
/* Insert l */
message[(num_blocks*64)-1] = (unsigned char)( l & 0xff);
message[(num_blocks*64)-2] = (unsigned char)((l >> 8) & 0xff);
message[(num_blocks*64)-3] = (unsigned char)((l >> 16) & 0xff);
message[(num_blocks*64)-4] = (unsigned char)((l >> 24) & 0xff);
/* Set initial hash state */
h[0] = 0x67452301;
h[1] = 0xefcdab89;
h[2] = 0x98badcfe;
h[3] = 0x10325476;
h[4] = 0xc3d2e1f0;
for (i = 0; i < num_blocks; i++){
/* Prepare the message schedule */
for (t=0; t < 80; t++){
if (t < 16){
w[t] = (256*256*256) * message[(i*64)+(t*4)];
w[t] += (256*256 ) * message[(i*64)+(t*4) + 1];
w[t] += (256 ) * message[(i*64)+(t*4) + 2];
w[t] += message[(i*64)+(t*4) + 3];
}
else if (t < 80){
w[t] = rotl(1,(w[t-3] ^ w[t-8] ^ w[t-14] ^ w[t-16]));
}
}
/* Initialize the five working variables */
a = h[0];
b = h[1];
c = h[2];
d = h[3];
e = h[4];
/* iterate a-e 80 times */
for (t = 0; t < 80; t++){
temp = (rotl(5,a) + ft(t,b,c,d)) & 0xffffffff;
temp = (temp + e) & 0xffffffff;
temp = (temp + k(t)) & 0xffffffff;
temp = (temp + w[t]) & 0xffffffff;
e = d;
d = c;
c = rotl(30,b);
b = a;
a = temp;
}
/* compute the ith intermediate hash value */
h[0] = (a + h[0]) & 0xffffffff;
h[1] = (b + h[1]) & 0xffffffff;
h[2] = (c + h[2]) & 0xffffffff;
h[3] = (d + h[3]) & 0xffffffff;
h[4] = (e + h[4]) & 0xffffffff;
}
digest[3] = (unsigned char) ( h[0] & 0xff);
digest[2] = (unsigned char) ((h[0] >> 8) & 0xff);
digest[1] = (unsigned char) ((h[0] >> 16) & 0xff);
digest[0] = (unsigned char) ((h[0] >> 24) & 0xff);
digest[7] = (unsigned char) ( h[1] & 0xff);
digest[6] = (unsigned char) ((h[1] >> 8) & 0xff);
digest[5] = (unsigned char) ((h[1] >> 16) & 0xff);
digest[4] = (unsigned char) ((h[1] >> 24) & 0xff);
digest[11] = (unsigned char) ( h[2] & 0xff);
digest[10] = (unsigned char) ((h[2] >> 8) & 0xff);
digest[9] = (unsigned char) ((h[2] >> 16) & 0xff);
digest[8] = (unsigned char) ((h[2] >> 24) & 0xff);
digest[15] = (unsigned char) ( h[3] & 0xff);
digest[14] = (unsigned char) ((h[3] >> 8) & 0xff);
digest[13] = (unsigned char) ((h[3] >> 16) & 0xff);
digest[12] = (unsigned char) ((h[3] >> 24) & 0xff);
digest[19] = (unsigned char) ( h[4] & 0xff);
digest[18] = (unsigned char) ((h[4] >> 8) & 0xff);
digest[17] = (unsigned char) ((h[4] >> 16) & 0xff);
digest[16] = (unsigned char) ((h[4] >> 24) & 0xff);
}
/******************************************************/
/* hmac-sha1() */
/* Performs the hmac-sha1 keyed secure hash algorithm */
/******************************************************/
void hmac_sha1(
unsigned char *key,
int key_length,
unsigned char *data,
int data_length,
unsigned char *digest
)
{
int b = 64; /* blocksize */
unsigned char ipad = 0x36;
unsigned char opad = 0x5c;
unsigned char k0[64];
unsigned char k0xorIpad[64];
unsigned char step7data[64];
unsigned char step5data[MAX_MESSAGE_LENGTH+128];
unsigned char step8data[64+20];
int i;
for (i=0; i<64; i++) {
k0[i] = 0x00;
}
if (key_length != b){ /* Step 1 */
/* Step 2 */
if (key_length > b){
sha1(key, key_length, digest);
for (i=0;i<20;i++){
k0[i]=digest[i];
}
}
else if (key_length < b){ /* Step 3 */
for (i=0; i<key_length; i++){
k0[i] = key[i];
}
}
}
else{
for (i=0;i<b;i++){
k0[i] = key[i];
}
}
/* Step 4 */
for (i=0; i<64; i++){
k0xorIpad[i] = k0[i] ^ ipad;
}
/* Step 5 */
for (i=0; i<64; i++){
step5data[i] = k0xorIpad[i];
}
for (i=0;i<data_length;i++){
step5data[i+64] = data[i];
}
/* Step 6 */
sha1(step5data, data_length+b, digest);
/* Step 7 */
for (i=0; i<64; i++){
step7data[i] = k0[i] ^ opad;
}
/* Step 8 */
for (i=0;i<64;i++){
step8data[i] = step7data[i];
}
for (i=0;i<20;i++){
step8data[i+64] = digest[i];
}
/* Step 9 */
sha1(step8data, b+20, digest);
}
void hmac_sha1_demo(){
hmac_sha1((unsigned char*)"123asd", 6, (unsigned char*)"test", 4, digest);
Serial.printf ("\nhmac_sha1 =");
Serial.printf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x ",digest[0], digest[1], digest[2], digest[3], digest[4],digest[5], digest[6], digest[7], digest[8], digest[9]);
Serial.printf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n\n",digest[10], digest[11], digest[12], digest[13], digest[14],digest[15], digest[16], digest[17], digest[18], digest[19]);
Serial.printf("\r\n-------------------------end---------------------");
}
示例:
void setup(){
hmac_sha1_demo();
}
void loop(){ }
HMAC在线计算工具
结果:
网友评论