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循环

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;
}

测试

运行结果
网站加密结果

注意事项

本人很菜,这个博客只是写给我自己看的,有很多写的不好,所以,不喜勿喷,谢谢大家!

  • 9
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
SHA-1是一种加密哈希算法,它将任意长度的消息压缩为一个160位的消息摘要。下面是使用C++实现SHA-1算法的示例代码: ```c++ #include <iostream> #include <cstring> #include <cstdint> // 循环左移函数 #define ROTLEFT(a,b) ((a << b) | (a >> (32-b))) // 定义常量K const uint32_t K[] = { 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xca62c1d6 }; // SHA-1算法函数 void sha1(uint8_t* message, uint32_t message_length, uint32_t* digest) { // 初始化缓冲区 uint32_t H[] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 }; // 计算填充位数 uint32_t padding_length = 64 - ((message_length + 8) % 64); // 填充消息 uint8_t* padded_message = new uint8_t[message_length + padding_length + 8]; std::memcpy(padded_message, message, message_length); padded_message[message_length] = 0x80; std::memset(padded_message + message_length + 1, 0, padding_length - 1); // 将消息长度添加到消息末尾 uint64_t message_bit_length = message_length * 8; std::memcpy(padded_message + message_length + padding_length, &message_bit_length, sizeof(message_bit_length)); // 处理每个512位的分组 for (uint32_t i = 0; i < message_length + padding_length + 8; i += 64) { // 将分组划分为16个32位的字 uint32_t* w = new uint32_t[80]; for (uint32_t j = 0; j < 16; j++) { w[j] = (padded_message[i + j * 4] << 24) | (padded_message[i + j * 4 + 1] << 16) | (padded_message[i + j * 4 + 2] << 8) | (padded_message[i + j * 4 + 3]); } // 扩展16个字为80个字 for (uint32_t j = 16; j < 80; j++) { w[j] = ROTLEFT(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1); } // 初始化哈希值 uint32_t a = H[0]; uint32_t b = H[1]; uint32_t c = H[2]; uint32_t d = H[3]; uint32_t e = H[4]; // 主循环 for (uint32_t j = 0; j < 80; j++) { uint32_t f, k; if (j < 20) { f = (b & c) | ((~b) & d); k = K[0]; } else if (j < 40) { f = b ^ c ^ d; k = K[1]; } else if (j < 60) { f = (b & c) | (b & d) | (c & d); k = K[2]; } else { f = b ^ c ^ d; k = K[3]; } uint32_t temp = ROTLEFT(a, 5) + f + e + k + w[j]; e = d; d = c; c = ROTLEFT(b, 30); b = a; a = temp; } // 更新哈希值 H[0] += a; H[1] += b; H[2] += c; H[3] += d; H[4] += e; // 释放内存 delete[] w; } // 保存哈希值 std::memcpy(digest, H, sizeof(H)); // 释放内存 delete[] padded_message; } int main() { uint8_t message[] = "hello world"; uint32_t digest[5]; sha1(message, std::strlen((const char*)message), digest); std::cout << std::hex << digest[0] << digest[1] << digest[2] << digest[3] << digest[4] << std::endl; return 0; } ``` 注意,这只是一个简单的示例代码,实际应用中需要考虑更多安全性和性能方面的问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值