SHA1算法实现及详解

0X1 SHA1算法详解

SHA1算法是Hash算法的一种。SHA1算法的最大输入长度小于2^64比特的消息,输入消息(明文)以512比特的分组为单位处理,输出160比特的消息摘要(密文

整个算法的核心是一个包含4轮循环的模块,每轮循环由20个步骤组成。
如下图:
其中Yq代表原始消息, CVq代表初始化的链接变量,最终我们要的密文就是CYq+1

1. 附加填充位

消息必须进行填充,以使其长度在对512取模以后的余数是448。也就是说,(填充后的消息长度)%512 = 448。即使长度已经满足对512取模后余数是448,填充也必须要进行。填充的规则是填充一个“1”和若干个“0”使其长度模512和448同余。然后附加64比特的无符号整数,其值为原始消息的长度

2. 初始化链接变量

和MD5有些类似,将5个32比特的固定数赋值给5个32比特的寄存器(和汇编里面的寄存器不同,可以理解为变量)A、B、C、D、E作为第一次迭代的链接变量输入:
A = 0x67452301, B = 0xEFCDAB89, C = 0x98BADCFE, D = 0x10325476, E = 0xC3D2E1F0

3. 非线性函数f函数

ft(x,y,z)={Ch(x,y,z)=(x⋀y)⨁(┐x⋀z),0≤t≤19Parity(x,y,z)=x⨁y⨁z,0≤t≤19Maj(x,y,z)=(x⋀y)⨁(x⋀z)⨁(y⋀z)0≤t≤19Parity(x,y,z)=x⨁y⨁z,0≤t≤19f_t(x,y,z) =\begin{cases} Ch(x, y ,z) = (x \bigwedge y) \bigoplus ( \urcorner x \bigwedge z),& 0 \leq t \leq 19 \\ Parity(x, y ,z) =x \bigoplus y\bigoplus z,& 0 \leq t \leq 19 \\ Maj(x, y ,z) = (x \bigwedge y) \bigoplus(x \bigwedge z) \bigoplus(y \bigwedge z) & 0 \leq t \leq 19 \\ Parity(x, y ,z) =x \bigoplus y\bigoplus z,& 0 \leq t \leq 19 \end{cases}ft​(x,y,z)=⎩⎪⎪⎪⎨⎪⎪⎪⎧​Ch(x,y,z)=(x⋀y)⨁(┐x⋀z),Parity(x,y,z)=x⨁y⨁z,Maj(x,y,z)=(x⋀y)⨁(x⋀z)⨁(y⋀z)Parity(x,y,z)=x⨁y⨁z,​0≤t≤190≤t≤190≤t≤190≤t≤19​

4. K值的获取

步数 Kr
r = 1 (0 <= t <= 19) 0x5A827999
r = 2 (20 <= t <= 39) 0x6ED9EBA1
r = 3 (40 <= t <= 59) 0x8F1BBCDC
r = 4 (60 <= t <= 79) 0xCA62C1D6

当然你也可以自己计算,四个值的获取分别是2、3、5和10的平方根,然后乘以2^30 = 1 073 741 824最后取乘积的整数部分。

5. W值的获取

ROTLn(x)表示对32位比特的变量循环左移n比特ROTL^n(x)表示对32位比特的变量循环左移n比特ROTLn(x)表示对32位比特的变量循环左移n比特
注意是循环左移n比特

W一共分为80组,其中从W[0]到W[15]为获得的原始消息均分为16组。

{Wt=Mt(i)0≤t≤15Wt=ROTL1(W(t−3)⨁W(t−8)⨁W(t−14)⨁W(t−16),16≤t≤79\begin{cases} W_t = M_t^{(i)} & 0 \leq t \leq 15 \\ W_t =ROTL^1(W_{(t-3)}\bigoplus W_{(t-8)}\bigoplus W_{(t-14)}\bigoplus W_{(t-16)},& 16 \leq t \leq 79 \end{cases}{Wt​=Mt(i)​Wt​=ROTL1(W(t−3)​⨁W(t−8)​⨁W(t−14)​⨁W(t−16)​,​0≤t≤1516≤t≤79​

6. 步函数

A=(ROTL5(A)+ft(B,C,D)+E+Wt+Kr)mod232B=AC=ROTL30(B)mod232D=CE=DA = (ROTL^5(A) + f^t(B,C,D) + E + W^t + K^r)mod 2^{32}\\B=A\\C= ROTL^{30}(B)mod2^{32}\\D=C\\E=DA=(ROTL5(A)+ft(B,C,D)+E+Wt+Kr)mod232B=AC=ROTL30(B)mod232D=CE=D
其中t是步数,0 <= t <= 79,r为轮数, 0 <= r <= 4.

0X2源代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#pragma warning(disable:4996)//初始化链接变量
unsigned int A = 0x67452301, B = 0xEFCDAB89, C = 0x98BADCFE, D = 0x10325476, E = 0xC3D2E1F0;        //第一次迭代的链接变量unsigned int K[4] = { 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 };                              //循环中用到的常量
unsigned int A0 = 0x67452301, B0 = 0xEFCDAB89, C0 = 0x98BADCFE, D0 = 0x10325476, E0 = 0xC3D2E1F0;// 字节转换,将四个字节转换为一个整型
int CharToWord(unsigned char *context, int i)
{return (((int)context[i] & 0x000000ff) << 24) | (((int)context[i + 1] & 0x000000ff) << 16) | (((int)context[i + 2] & 0x000000ff) << 8) | ((int)context[i + 3] & 0x000000ff);
}// 填充补位获得原始明文
void SHA1_fill(unsigned char *plaintext, unsigned int *group, int length)
{printf("补位后获得的明文:\n");int temp = length / 32, len = length;while (len > 0){if (len = len / 32){for (int j = 0; j < temp; j++){group[j] = CharToWord(plaintext, 4 * j);printf("%08X\n", group[j]);}}else{plaintext[length / 8] = 0x80;group[temp] = CharToWord(plaintext, temp * 4);printf("%08X\n", group[temp]);break;}}group[15] = length;for (int i = temp + 1; i < 16; i++)printf("%08X\n", group[i]);}
// f函数
unsigned int f(int B, int C, int D, int t)
{return (t >= 0 && t <= 19) ? ((B&C) | (~B&D)) : ((t >= 20 && t <= 39) ? (B ^ C ^ D) : ((t >= 40 && t <= 59) ? ((B&C) | (B&D) | (C&D)) : ((t >= 60 && t <= 79) ? B ^ C ^ D : 0)));
}
//获得Kr
unsigned int GetK(int r)
{/*if (r >= 0&& r <= 19){return K[0];}else if (r >= 20 && r <= 39){return K[1];}else if (r >= 40 && r <= 59){return K[2];}else if (r >= 60 && r <= 79){return K[3];}*/return (r >= 0 && r <= 19) ? K[0] : ((r >= 20 && r <= 39) ? K[1] : ((r >= 40 && r <= 59) ? K[2] : ((r >= 60 && r <= 79) ? K[3] : 0)));
}//获得 Wt
void GetW(unsigned int w[])
{/*for (int i = 16; i < 80; i++)w[i] = ((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]) << 1) | ((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]) >> 31);*/for (int i = 16; i < 80; w[i++] = ((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]) << 1) | ((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]) >> 31));
}
// 步函数
void StepFunction(unsigned int w[], int t)
{unsigned int temp = ((A << 5) | (A >> 27)) + f(B, C, D, t) + E + w[t] + GetK(t);E = D, D = C, C = ((B << 30) | (B >> 2)), B = A, A = temp;
}
// 获得密文
void GetCipher(unsigned int * cipher)
{cipher[0] = A0 + A;cipher[1] = B0 + B;cipher[2] = C0 + C;cipher[3] = D0 + D;cipher[4] = E0 + E;
}void SHA1(unsigned char *context,unsigned int * cipher)
{int len = strlen((char*)context) * 8;unsigned int group[80] = { 0 };SHA1_fill(context, group, len);GetW(group);for (int t = 0; t < 80; t++){StepFunction(group, t);}GetCipher(cipher);}
int main()
{unsigned char m[56];unsigned int c[5] = { 0 };printf("请输入长度小于56且不包含空格的明文:");scanf("%s", m);SHA1(m,c);/*密文输出*/printf("密文为:");for (int j = 0; j <= 4; j++) printf("%08X", c[j]);printf("\n");system("pause");return 0;
}

SHA1算法实现及详解相关推荐

  1. c语言实现sha1算法注解,【密码学】SHA1算法实现及详解

    1 SHA1算法简介 安全哈希算法(Secure Hash Algorithm)主要适用于数字签名标准(Digital Signature Standard DSS)里面定义的数字签名算法(Digit ...

  2. python如何调用文件进行换位加密_python 换位密码算法的实例详解

    python 换位密码算法的实例详解 一前言: 换位密码基本原理:先把明文按照固定长度进行分组,然后对每一组的字符进行换位操作,从而实现加密.例如,字符串"Error should neve ...

  3. DL之AlexNet:AlexNet算法的架构详解、损失函数、网络训练和学习之详细攻略

    DL之AlexNet:AlexNet算法的架构详解.损失函数.网络训练和学习之详细攻略 相关文章 Dataset:数据集集合(CV方向数据集)--常见的计算机视觉图像数据集大集合(建议收藏,持续更新) ...

  4. DL之ShuffleNet:ShuffleNet算法的架构详解

    DL之ShuffleNet:ShuffleNet算法的架构详解 相关文章 DL之ShuffleNet:ShuffleNet算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 DL之Shuf ...

  5. DL之MobileNetV2:MobileNetV2算法的架构详解(包括ReLu的意义)

    DL之MobileNet V2:MobileNetV2算法的架构详解 相关文章 DL之MobileNetV2:MobileNetV2算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 DL ...

  6. DL之SqueezeNet:SqueezeNet算法的架构详解

    DL之SqueezeNet:SqueezeNet算法的架构详解 相关文章 DL之SqueezeNet:SqueezeNet算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 DL之Sque ...

  7. ​​​​​​​DL之ResNeXt:ResNeXt算法的架构详解

    DL之ResNeXt:ResNeXt算法的架构详解 相关文章 DL之ResNeXt:ResNeXt算法的简介(论文介绍).架构详解.案例应用等配图集合之详细攻略 DL之ResNeXt:ResNeXt算 ...

  8. 【算法知识】详解堆排序算法

    点击蓝色字关注我们! 什么是堆 「堆」首先是一个完全二叉树,「堆」分为「大顶堆」和「小顶堆」: 「大顶堆」 : 每个节点的值大于或等于其左右孩子节点的值,称为大顶堆. 「小顶堆」同理就是每个节点的值小 ...

  9. 【算法知识】详解基数排序算法

    已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 [算法知识]详解快速排序算法 [算法知识]详解归并排序算法 基本思想 基数排序的思想是将整数按位数切 ...

  10. 【算法知识】详解归并排序算法

    已发布: [算法知识]详解选择冒泡算法 [算法知识]详解选择排序算法 [算法知识]详解插入排序算法 [算法知识]详解快速排序算法 基本思想 归并排序的基本思想是: 先将序列一次次分成子序列,直到子序列 ...

最新文章

  1. 62. Leetcode 34. 在排序数组中查找元素的第一个和最后一个位置 (二分查找-局部有序)
  2. MYSQL 表锁情况查看
  3. 新书出版:《Android深度探索(卷1):HAL与驱动开发》
  4. 密码机项目安装软件时候出现的问题以及对应的解决办法
  5. HTML 内容不能被选择,不能被复制
  6. 单元测试框架TestableMock快速入门(五):复用Mock类与方法
  7. 31个EMC标准电路分享
  8. 学生管理系统IPO图_基于BIM技术的医院建筑运维管理系统构建
  9. VS2005中远程调试的配置方法
  10. 网络工程师考试经验总结
  11. uniapp启动页面
  12. Apple iPhone 8G手机误升级至2.0降级破解日记
  13. 转-快找个程序员做老公吧
  14. RSD处理高分5号高光谱(GF5 AHSI)数据(四)——从地物光谱搜索高光谱数据集
  15. Colossal-AI 分布式人工智能框架
  16. 关于程序员日常接单之淘宝运营
  17. 对象存储OSS基本概念讲解
  18. 第 2-4 课:表格组件详解(Table 和 Data Tables)
  19. 图形处理之 OpenGL
  20. php销毁session退出登陆笔记

热门文章

  1. DISCUZ编辑器工具栏图标不显示
  2. CSS综合案例——淘宝焦点图(轮播图)布局及网页布局总结
  3. 小米路由3刷华硕潘多拉固件教程及软件相关
  4. php磁力链播放源码,Bt种子转磁力链 PHP源码
  5. 《与孩子一起学编程》译者序
  6. 关于E-Prime 2.0 无法呈现音频的一种解决方案
  7. jQuery源码结构
  8. Qt学习之C++基础
  9. java基础之URLDecoder异常解决方法
  10. 捕鱼达人 FishMaster 记录(Done)