C++ 实现SHA-1加密
实验目的
实现SHA-1加密
实验原理
1、增加1000 0000串
建立一个pad数组,储存增加的串,不管原来的字符串有多长,都先增加一个1000 000串,也就是pad[0]=128。
2、拓展字符串
如果字符串长度l%512!=448,那就进行拓展,补充0000 0000串直到达到(l+1)%512==448为止,然后在最后的512-448=64位上面加上一个字符串长度l的二进制串。
3、实现SHA-1循环
ROTL是循环左移。
ft(B,C,D) = (B AND C) OR ((NOT B) AND D) ( 0 <= t <= 19)
ft(B,C,D) = B XOR C XOR D (20 <= t <= 39)
ft(B,C,D) = (B AND C) OR (B AND D) OR (C AND D) (40 <= t <= 59)
ft(B,C,D) = B XOR C XOR D (60 <= t <= 79)
Kt = 0x5A827999 (0 <= t <= 19)
Kt = 0x6ED9EBA1 (20 <= t <= 39)
Kt = 0x8F1BBCDC (40 <= t <= 59)
Kt = 0xCA62C1D6 (60 <= t <= 79)
“+”是模2^32的加法。
实验代码
字符串的拓展函数
void SHA_PAD(string x)
{
long long l = x.length();
long long i = 0;
pad[i] = 128;
i++;
l += 1;
if ((l * 8) % 512 != 448)
{
for (; (l * 8) % 512 != 448; l++)
{
i++;
}
}
l = x.length();
l = l * 8;
int a = 1;
pad[i + 7] = l % 256;
while (l / 256 > 0)
{
l = l / 256;
pad[i + 7 - a] = l % 256;
a++;
}
for (; a < 8; a++)
{
pad[i + 7 - a] = 0;
}
lenth_pad = i + 7;
}
循环左移函数
bitset<32> ROTL(int s, bitset<32> W)
{
bitset<32>m = W << s;
for (int i = 0; i < s; i++)
{
m[i] = W[32 - s + i];
}
return m;
}
模2^32加函数
bitset<32> ADD(bitset<32>a, bitset<32>b)
{
bitset<32> c;
int d = 0;
for (int i = 0; i < 32; i++)
{
c[i] = (a[i] + b[i] + d) % 2;
if (a[i] + b[i] + d >= 2)
{
d = 1;
}
else if (a[i] + b[i] + d < 2)
{
d = 0;
}
}
return c;
}
Ft函数
bitset<32> Ft(int t, bitset<32> B, bitset<32> C, bitset<32> D)
{
if (0 <= t && t <= 19)
{
return ((B&C) | ((~B)&D));
}
else if (20 <= t && t <= 39)
{
return (B^C^D);
}
else if (40 <= t && t <= 59)
{
return ((B&C) | (B&D) | (C&D));
}
else if (60 <= t && t <= 79)
{
return (B^C^D);
}
}
循环体
void DO(bitset<512> M)
{
bitset<32> Wt[80] = { 0 };
for (int i = 0; i < 16; i++)
{
for (int n = 0; n < 32; n++)
{
Wt[i][n] = M[(15 - i) * 32 + n];
}
}
for (int t = 16; t <= 79; t++)
{
Wt[t] = ROTL(1, Wt[t - 3] ^ Wt[t - 8] ^ Wt[t - 14] ^ Wt[t - 16]);
}
bitset<32> A = Ht[0];
bitset<32> B = Ht[1];
bitset<32> C = Ht[2];
bitset<32> D = Ht[3];
bitset<32> E = Ht[4];
for (int t = 0; t <= 79; t++)
{
bitset<32> temp = ADD(ADD(ADD(ROTL(5, A), Ft(t, B, C, D)), ADD(E, Wt[t])), Kt[t/20]);
E = D;
D = C;
C = ROTL(30, B);
B = A;
A = temp;
}
Ht[0] = ADD(Ht[0], A);
Ht[1] = ADD(Ht[1], B);
Ht[2] = ADD(Ht[2], C);
Ht[3] = ADD(Ht[3], D);
Ht[4] = ADD(Ht[4], E);
}
主函数
int main()
{
string x;
cout << "please enter the text:";
getline(cin, x);
SHA_PAD(x);
long long l = 0;
//循环体
while (l < x.length())
{
long long i = l;
string Sx;
for (; (i < 64 + l) && (i < x.length()); i++)
{
bitset<8> mark = int(x[i]);
Sx += mark.to_string();
}
l += 64;
if (i == x.length())
{
if(lenth_pad<=63)
for (int n = 0; n <= lenth_pad; n++)
{
bitset<8> mark = pad[n];
Sx += mark.to_string();
}
else
{
int n = 0;
for (; i < l; i++)
{
bitset<8> mark = pad[n];
n++;
Sx += mark.to_string();
}
bitset<512>Mx(Sx);
DO(Mx);
string last_Sx;
for (; n <= lenth_pad; n++)
{
bitset<8> mark = pad[n];
last_Sx += mark.to_string();
}
bitset<512>last_Mx(last_Sx);
DO(last_Mx);
break;
}
}
bitset<512> Mx(Sx);
DO(Mx);
}
//输出
cout << "The hash of text is:";
for (int i = 0; i < 5; i++)
{
string s = Ht[i].to_string();
for (int n = 0; n < 32;)
{
int result = 0;
for (int m = 0; m < 4; m++)
{
result += (s[n + m] - '0')*pow(2, 3 - m);
}
cout << hex << result;
n += 4;
}
}
return 0;
}
完成
#include <iostream>
#include <string>
#include <bitset>
#include <math.h>
using namespace std;
long long pad[75] = { 0 };
int lenth_pad = 0;
bitset<32> Kt[4] = { 0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6 };
bitset<32> Ht[5] = { 0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0 };
//Ft函数
bitset<32> Ft(int t, bitset<32> B, bitset<32> C, bitset<32> D)
{
if (0 <= t && t <= 19)
{
return ((B&C) | ((~B)&D));
}
else if (20 <= t && t <= 39)
{
return (B^C^D);
}
else if (40 <= t && t <= 59)
{
return ((B&C) | (B&D) | (C&D));
}
else if (60 <= t && t <= 79)
{
return (B^C^D);
}
}
//字符串的拓展函数
void SHA_PAD(string x)
{
long long l = x.length();
long long i = 0;
pad[i] = 128;
i++;
l += 1;
if ((l * 8) % 512 != 448)
{
for (; (l * 8) % 512 != 448; l++)
{
i++;
}
}
l = x.length();
l = l * 8;
int a = 1;
pad[i + 7] = l % 256;
while (l / 256 > 0)
{
l = l / 256;
pad[i + 7 - a] = l % 256;
a++;
}
for (; a < 8; a++)
{
pad[i + 7 - a] = 0;
}
lenth_pad = i + 7;
}
//循环左移函数
bitset<32> ROTL(int s, bitset<32> W)
{
bitset<32>m = W << s;
for (int i = 0; i < s; i++)
{
m[i] = W[32 - s + i];
}
return m;
}
//模2^32加函数
bitset<32> ADD(bitset<32>a, bitset<32>b)
{
bitset<32> c;
int d = 0;
for (int i = 0; i < 32; i++)
{
c[i] = (a[i] + b[i] + d) % 2;
if (a[i] + b[i] + d >= 2)
{
d = 1;
}
else if (a[i] + b[i] + d < 2)
{
d = 0;
}
}
return c;
}
//循环体
void DO(bitset<512> M)
{
bitset<32> Wt[80] = { 0 };
for (int i = 0; i < 16; i++)
{
for (int n = 0; n < 32; n++)
{
Wt[i][n] = M[(15 - i) * 32 + n];
}
}
for (int t = 16; t <= 79; t++)
{
Wt[t] = ROTL(1, Wt[t - 3] ^ Wt[t - 8] ^ Wt[t - 14] ^ Wt[t - 16]);
}
bitset<32> A = Ht[0];
bitset<32> B = Ht[1];
bitset<32> C = Ht[2];
bitset<32> D = Ht[3];
bitset<32> E = Ht[4];
for (int t = 0; t <= 79; t++)
{
bitset<32> temp = ADD(ADD(ADD(ROTL(5, A), Ft(t, B, C, D)), ADD(E, Wt[t])), Kt[t/20]);
E = D;
D = C;
C = ROTL(30, B);
B = A;
A = temp;
}
Ht[0] = ADD(Ht[0], A);
Ht[1] = ADD(Ht[1], B);
Ht[2] = ADD(Ht[2], C);
Ht[3] = ADD(Ht[3], D);
Ht[4] = ADD(Ht[4], E);
}
int main()
{
string x;
cout << "please enter the text:";
getline(cin, x);
SHA_PAD(x);
long long l = 0;
//循环体
while (l < x.length())
{
long long i = l;
string Sx;
for (; (i < 64 + l) && (i < x.length()); i++)
{
bitset<8> mark = int(x[i]);
Sx += mark.to_string();
}
l += 64;
if (i == x.length())
{
if(lenth_pad<=63)
for (int n = 0; n <= lenth_pad; n++)
{
bitset<8> mark = pad[n];
Sx += mark.to_string();
}
else
{
int n = 0;
for (; i < l; i++)
{
bitset<8> mark = pad[n];
n++;
Sx += mark.to_string();
}
bitset<512>Mx(Sx);
DO(Mx);
string last_Sx;
for (; n <= lenth_pad; n++)
{
bitset<8> mark = pad[n];
last_Sx += mark.to_string();
}
bitset<512>last_Mx(last_Sx);
DO(last_Mx);
break;
}
}
bitset<512> Mx(Sx);
DO(Mx);
}
//输出
cout << "The hash of text is:";
for (int i = 0; i < 5; i++)
{
string s = Ht[i].to_string();
for (int n = 0; n < 32;)
{
int result = 0;
for (int m = 0; m < 4; m++)
{
result += (s[n + m] - '0')*pow(2, 3 - m);
}
cout << hex << result;
n += 4;
}
}
getchar();
getchar();
return 0;
}
测试
注意事项
本人很菜,这个博客只是写给我自己看的,有很多写的不好,所以,不喜勿喷,谢谢大家!