C/C++ 加密解密学习记录
# C/C++ 加密解密学习记录#### 项目地址:(https://github.com/IcEy-999/MyOpenSSL)
趁放假,去实施了一下蓄谋已久的小计划:手打实现各种密码和哈希、熟悉openssl。
代码写的稀碎,主要是学习嘛~
目前已经手打实现了:(这个项目应该还会继续维护一段时间)
HASH:
MD5、SHA1、SHA224、SHA256、SHA384、SHA512、SHA3-224、SHA3-256、SHA3-384、SHA3-512、SM3
加密解密:
通过OpenSSL实现各种密码的例子、RSA
编码:
Base64、
为了加深印象还写了一些文档记录 加密 解密的步骤,在项目目录上,想看哪个就点哪个。
这里贴一篇我记录的 SHA3 的HASH步骤:当然啦!只有步骤,原理咱不深究。
# SHA3
前置知识:B 、W、L 对照表
对于SHA3家族:B固定为1600。所以 W、L也固定了。
### 第一步
设 需要散列的 文本为"M",M的长度为N Bit 。
需要将M 填充到 N mod r = 0;
```c
SHA3-224: r = 1152 SHA3-256: r = 1088
SHA3-384: r = 832 SHA3-512: r = 576
```
填充规则:先串接 01 ,再串接 100....001。图例:
###### 例子1:M 很短时
###### 例子2:M 长时
###### 例子3:填充最少
###### 例子4:填充最多
###### 注意:
在计算机的实际应用中,基本单位是字节,因此填充的部分,也应该是字节。以 8Bit 为单位:
在上图中 M 为最低位的 Bit,最后填补的 Bit 1 为最高位的 Bit。若以 字节的形式表示如下:
例如我需要填补 2个字节才能补足 长度 R Bit:
可以看出:我们补的字节并不是 0x60 与 0x01,而补的是 0x06与 0x80 。这一部分和SHA1、SHA2、MD家族有些许区别。
若只补1个字节:
补的不是 0x61 而是 0x86。
这一部分是一个大坑。
### 第二步
迭代:
对上面的每一段 M 进行迭代。初始向量 S 为 长度为B的全 0 Bit串。
S 会经过多次迭代变化。经过最后一个 函数F 得到的 S 为HASH结果。
取 S 前 (224、256、384、512)Bit 即为HASH输出。
#### 详解 迭代函数 F :
##### 前置知识:
A = S ,S 即为上图的 S 。还有两个工具函数,使用代码表示:
```c
#define A(x,y,z) (W*(5*y+x)+z)
//获得 S 的第 A(x,y,z) 个 Bit 的值(UCHAR 类型表示)
UCHAR Get_Bit(S,A(x,y,z));
//将 S 的第 A(x+1,y+1,z+1) 个 Bit 的值 赋值为 S 的第 A(x,y,z) 个 Bit 的值
VOID Set_Bit(S,A(x+1,y+1,z+1),Get_Bit(S,A(x,y,z)));
```
```c
VOID SHA3_512_Data::KECCAK_P(PUCHAR S) { //这个函数就是 上述流程图中的 函数 F
for (int ir = 12 + 2 * L - Nr; ir <= 12 + 2 * L - 1; ir++) {
Rnd(S, ir);
}
}
```
##### 其中:
##### Rnd:
##### θ(theat):
代码(节选):
```cpp
for (int x = 0; x < 5; x++) {
for (int z = 0; z < W; z++) {
Set_Bit(C, W * x + z, Get_Bit(S, A(x, 0, z)) ^ Get_Bit(S, A(x, 1, z)) ^ Get_Bit(S, A(x, 2, z)) ^ Get_Bit(S, A(x, 3, z)) ^ Get_Bit(S, A(x, 4, z)));
}
}
for (int x = 0; x < 5; x++) {
for (int z = 0; z < W; z++) {
Set_Bit(D, W * x + z, Get_Bit(C, W * mod(x - 1, 5) + z) ^ Get_Bit(C, W * mod(x + 1, 5) + mod(z - 1, W)));
}
}
for (int x = 0; x < 5; x++) {
for (int y = 0; y < 5; y++) {
for (int z = 0; z < W; z++) {
Set_Bit(Sc, A(x, y, z), Get_Bit(D, W * x + z) ^ Get_Bit(S, A(x, y, z)));
}
}
}
```
#####ρ(rho):
代码(节选):
```cpp
for (int z = 0; z < W; z++) {
Set_Bit(Sc, A(0, 0, z), Get_Bit(S, A(0, 0, z)));
}
int x = 1, y = 0;
int newx, newy;
for (int t = 0; t < 24; t++) {
for (int z = 0; z < W; z++) {
Set_Bit(Sc, A(x, y, z), Get_Bit(S, A(x, y, mod(z - ((t + 1) * (t + 2) / 2), W))));
}
newx = y%5;
newy =(2 * x + 3 * y)% 5;
x = newx;
y = newy;
}
```
#####π(pi):
代码(节选):
```cpp
for (int x = 0; x < 5; x++) {
for (int y = 0; y < 5; y++) {
for (int z = 0; z < W; z++) {
j = mod(x + (3 * y), 5);
Set_Bit(Sc, A(x, y, z), Get_Bit(S, A(j,x,z)));
}
}
}
```
##### χ(chi):
代码(节选):
```cpp
for (int x = 0; x < 5; x++) {
for (int y = 0; y < 5; y++) {
for (int z = 0; z < W; z++) {
Set_Bit(Sc, A(x, y, z), Get_Bit(S, A(x, y, z)) ^ ((Get_Bit(S, A(mod(x + 1, 5), y, z)) ^ 1) * Get_Bit(S, A(mod(x + 2, 5), y, z))));
}
}
}
```
##### ι(iota):
代码(节选):
```cpp
memcpy(Sc, S, B / 8);
UCHAR RC = { 0 };
for (int j = 0; j <= L; j++) {
int ls = pow(2, j) - 1;
RC = rc(j + 7 * Ir);
}
for (int z = 0; z < W; z++) {
Set_Bit(Sc, A(0, 0, z), Get_Bit(Sc, A(0, 0, z)) ^ RC);
}
```
##### rc:
代码(节选):
```cpp
UCHAR r = { 1,0,0,0,0,0,0,0,0 };
if (mod(t, 255) == 0) {
return 1;
}
for (int i = 1; i <= mod(t, 255); i++) {
memcpy(&r, &r, 8);
r = 0;
r = r ^ r;
r = r ^ r;
r = r ^ r;
r = r ^ r;
}
return r;
```
### SHA3官方步骤:
1.
2.
3.
一直对C++有关的感兴趣,学习了,感谢分享 写的真好,都是易懂的内容。 感谢楼主分享心得! 感谢楼主分享心得! 正在学习这块知识··感谢分享 感谢楼主分享心得! 感谢分享! 谢谢分享
感谢楼主分享心得!
页:
[1]
2