加密芯片ATSHA204之初识SHA-256

22 篇文章 0 订阅
3 篇文章 0 订阅

草稿存于2021-03-16。下面,为了显示出很专业的样子,贴出百科解释:

说明

  SHA-2,名称来自于安全散列算法2(英语:Secure Hash Algorithm 2)的缩写,一种密码散列函数算法标准,由美国国家安全局研发[3],由美国国家标准与技术研究院(NIST)在2001年发布。属于SHA算法之一,是SHA-1的后继者。其下又可再分为六个不同的算法标准,包括了:SHA-224、SHA-256、SHA-384、SHA-512、SHA-512/224、SHA-512/256。

  由于加密芯片 atsha204 主要使用了 SHA-256 算法,故本文描述的就是 SHA-256 算法。

计算 SHA-256 时,当数据长度 len + 8 大于等于64字节时,分组进行:

分组数    n = ( len + 8 ) / 64 + 1;

每组数据为64字节,最后一组不满 55 字节则补全,剩余 9 字节为固定值与数据长度,一般地方使用 0 填充,在所需计算数据的位置后直接填充 0x80,64字节中的最后四字节为 len * 8

例如,计算一组数据的 SHA-256

要计算的数组 
{0x43,0x43}

则构成的64字节则为(hex):
43 43 80 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 10

计算的 SHA-256 结果为:
a5 63 62 a1 0c 81 6a bf 20 6d 72 cb 91 4e 2d 5c
a4 54 eb 9c 7e 74 4f 88 b1 a1 42 2c 37 9e 99 42

程序

  • 以下例程为计算 {0x43,0x43} 的 SHA-256 值:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

unsigned int sha256_k[64] = {
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};

#define SHFR(x, n)    (x >> n)
#define ROTR(x, n)   ((x >> n) | (x << ((sizeof(x) << 3) - n)))
#define ROTL(x, n)   ((x << n) | (x >> ((sizeof(x) << 3) - n)))
#define CH(x, y, z)  ((x & y) ^ (~x & z))
#define MAJ(x, y, z) ((x & y) ^ (x & z) ^ (y & z))

#define SHA256_F1(x) (ROTR(x,  2) ^ ROTR(x, 13) ^ ROTR(x, 22))
#define SHA256_F2(x) (ROTR(x,  6) ^ ROTR(x, 11) ^ ROTR(x, 25))
#define SHA256_F3(x) (ROTR(x,  7) ^ ROTR(x, 18) ^ SHFR(x,  3))
#define SHA256_F4(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHFR(x, 10))

static void sha256_update(uint8_t *Input,unsigned int *Output)
{
    unsigned int w[64];
    unsigned int wv[8];
    unsigned int t1, t2;
    uint8_t j;


    for (j = 0; j < 16; j++) {
        w[j]=  ((unsigned int)Input[4*j+3])+
            (((unsigned int)Input[4*j+2])<<8)+
            (((unsigned int)Input[4*j+1])<<16)+
            (((unsigned int)Input[4*j])  << 24);    
    }

    for (j = 16; j < 64; j++) {
        w[j]= SHA256_F4(w[j-2]) + w[j-7]+ SHA256_F3(w[j - 15]) + w[j-16];
    }

    for (j = 0; j < 8; j++) {
        wv[j] = Output[j];
    }

    for (j = 0; j < 64; j++) {
        t1 = wv[7] + SHA256_F2(wv[4]) + CH(wv[4], wv[5], wv[6])+ sha256_k[j] + w[j];
        t2 = SHA256_F1(wv[0]) + MAJ(wv[0], wv[1], wv[2]);
        wv[7] = wv[6];
        wv[6] = wv[5];
        wv[5] = wv[4];
        wv[4] = wv[3] + t1;
        wv[3] = wv[2];
        wv[2] = wv[1];
        wv[1] = wv[0];
        wv[0] = t1 + t2;
    }

    for (j = 0; j < 8; j++) {
        Output[j] += wv[j];
    }
}

static void sha256(uint8_t *Input, uint32_t len, uint8_t *Output)
{
    unsigned int sha256_h[8];
    uint8_t sha256_block[256];  //其大小最多可测试 247 字节
    uint16_t i=0;
    uint32_t n = ( len + 8 ) / 64 + 1; //分组数

    sha256_h[0] = 0x6a09e667;
    sha256_h[1] = 0xbb67ae85;
    sha256_h[2] = 0x3c6ef372;
    sha256_h[3] = 0xa54ff53a;
    sha256_h[4] = 0x510e527f;
    sha256_h[5] = 0x9b05688c;
    sha256_h[6] = 0x1f83d9ab;
    sha256_h[7] = 0x5be0cd19;

    memmove(sha256_block, Input, len);
    memset(sha256_block+len, 0x0, n*64-len);

    sha256_block[len] = 0x80;

    for(i=1; i<=4; i++){
        sha256_block[(n*64)-i] = (uint8_t)(8*len>>(i-1)*8);
    }
    for(i=0; i<n; i++){
        sha256_update(&sha256_block[64*i], sha256_h);
    }
    for (i = 0 ; i < 8; i++){
        Output[4*i]  =((uint8_t)(sha256_h[i] >> 24));
        Output[4*i+1]=((uint8_t)(sha256_h[i] >> 16));
        Output[4*i+2]=((uint8_t)(sha256_h[i] >>  8));
        Output[4*i+3]=((uint8_t)(sha256_h[i]));
    }
}

uint8_t testhex[] = {0x43,0x43};
uint8_t outhex[32];

int main(int argc, char **argv)
{
	sha256(testhex, sizeof(testhex), outhex);
	for(int i=0; i < 32; ++i){
		printf("%02x ", outhex[i]);
	}
	printf("\n");
	return 0;
}
  • 若是在linux系统中安装了 openssl ,则会比较简单,直接调用 API
#include <openssl/sha.h>
#include <iostream>
#include <string>
#include <iomanip>

using namespace std;

string sha256(const uint8_t * data, int len)
{    
	unsigned char hash[SHA256_DIGEST_LENGTH];    
	SHA256_CTX sha256;    
	SHA256_Init(&sha256);    
	SHA256_Update(&sha256, data, len);    
	SHA256_Final(hash, &sha256);    
	stringstream ss;    
	for(int i = 0; i < SHA256_DIGEST_LENGTH; i++){        
		ss << hex << setw(2) << setfill('0') << (int)hash[i];    
	}    
	return ss.str();
}

uint8_t  testhex[]={ 0x43,0x43 };

int main(){    
	cout << sha256(testhex, sizeof(testhex)) << endl;      
	return 0;
}

编译时需要加上 -lssl -lcrypto,否则会报错
在这里插入图片描述

g++ -o sha256_test sha256_test.cpp -lssl -lcrypto

相关参考:
https://github.com/nsood/sha204/blob/master/sha256.c
https://github.com/panshq/atsha204a/blob/master/sha204-core.c
https://blog.csdn.net/lwanttowin/article/details/53726450
https://stackoverflow.com/questions/2262386/generate-sha256-with-openssl-and-c/10632725

SHA-256 计算验证网站

https://emn178.github.io/online-tools/sha256.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值