AES

130035028553414

特征:分组密码、对称加密,算法复杂、密钥长度有多种可能,最常见的是128bits,也就是16个字节。

b站视频学习AES加密过程:

https://www.bilibili.com/video/BV1i341187fK/?spm_id_from=333.337.search-card.all.click&vd_source=a85daf8eb54f32264d9f6976d087fe98

AES加解密代码实现学习:

https://ppppz.net/2022/01/31/AES-P-Z/

(PZ大佬的博客链接)

本人最开始是想自己写的,后来实在不想debug了,于是就抄下了大佬的代码。

RC4

  • 流密码、对称加密、加解密使用同一种算法(最后使用了xor)
  • 有一个s[] 作为黑盒,利用密钥对黑盒进行变换,使得黑盒中变得复杂(初始化)
  • 最终使用黑盒中的数据对明文进行流加密,理论上来说明文密文是等长的
  • 但是由于字符变量取值是0-127,但是密文的取值却是0-255,因此存在显示字符问题
  • 在最终显示密文时可能存在几种情况,一种就是直接显示,可能会出现乱码,一种是用16进制进行输出,但这样会导致密文长度和明文长度不一致,另外一种就是使用base64编码输出,这样的话相当于进行了两次加密,但是密文一定可以很好地显示
  • 特征代码 :
i=(i+1)%256;
j=(j+s[j])%256;
swap(s[i],s[j]);
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
unsigned char s[256];
void rc4_start( char key[],int n){
int j=0;
for(int i=0;i<256;i++){
s[i]=-1-i;
j=(j+s[i]+key[i%n])%256;
swap(s[i],s[j]);
}

}
unsigned char secr[256];
void rc4_enc( unsigned char pub[],int n){
int i=0,j=0;
for(int k=0;k<n;k++){
i=(i+1)%256;
j=(j+s[i])%256;
swap(s[i],s[j]);
unsigned char temp=s[(s[i]+s[j])%256]^pub[k];
secr[k]=temp;

}
}
int main(){
char key[]="THISISAFAKEFLAG";

rc4_start(key,strlen(key));

unsigned char pub[] =
{
0x44, 0x3F, 0x53, 0x2F, 0x73, 0x86, 0x3E, 0xAE, 0x55, 0xBE,
0x18, 0x5F, 0x74, 0x68, 0x33, 0x5F, 0xF2, 0x06, 0x6D, 0x62};
rc4_enc(pub,20);
for(int i=0;i<20;i++)cout<<secr[i];
return 0;
}

上面为自己手写的代码。

其加解密完全使用同样的算法。

base64

  • 无密钥,加密过程中信息无丢失
  • 将三个字符的字节(24位)划分成四个字符的字节,每一个字节为6位,高两位补2个0
  • 加解密简单
  • 特征代码:
b1=c1>>2;
b2=((c1&0x3)<<4)|(c2>>4);
b3=((c2&0xF)<<2)|(c3>>6);
b4=c3&0x3F;

以下为本人手写解密算法

#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<map>
using namespace std;
// base64 解密
char base64t[64]={'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};

map<char,int>alter;
int r=0;
void change(char* c1,char*c2,char *c3,char *c4){
int a1,a2,a3,a4,b1,b2,b3,b4;
b1=*c1;
b2=*c2;
b3=*c3;
b4=*c4;
b1=alter[(char)b1];
b2=alter[(char)b2];
b3=alter[(char)b3];
b4=alter[(char)b4];
//cout<<b1<<" "<<b2<<" "<<b3<<" "<<b4<<endl;
a1=((b1<<2)%256)+(b2>>4);
a2=((b2<<4)%256)+(b3>>2);
a3=((b3<<6)%256)+b4;
//cout<<a1<<" "<<a2<<" "<<a3<<endl;
*c1=a1;
*c2=a2;
*c3=a3;
*c4=0;
}
vector<char>ans;
void endw(char* c1,char*c2,char *c3,char *c4){
int a1,b1,a2,b2,a3,b3,a4,b4;
b1=*c1;
b2=*c2;
b3=*c3;
b4=*c4;
if(b4!='='){
b1=alter[(char)b1];
b2=alter[(char)b2];
b3=alter[(char)b3];
b4=alter[(char)b4];
//cout<<b1<<" "<<b2<<" "<<b3<<" "<<b4<<endl;
a1=((b1<<2)%256)+(b2>>4);
a2=((b2<<4)%256)+(b3>>2);
a3=((b3<<6)%256)+b4;
r+=3;
ans.push_back(char(a1));
ans.push_back(char(a2));
ans.push_back(char(a3));
}
if(b4=='='){
if(b3=='='){
b1=alter[(char)b1];
b2=alter[(char)b2];
r+=1;
a1=((b1<<2)%256)+(b2>>4);
ans.push_back(char(a1));
}
if(b3!='='){
b1=alter[(char)b1];
b2=alter[(char)b2];
b3=alter[(char)b3];
r+=2;
a1=((b1<<2)%256)+(b2>>4);
a2=((b2<<4)%256)+(b3>>2);
ans.push_back(char(a1));
ans.push_back(char(a2));
}
}
}
int main(){
for(int i=0;i<64;i++){
alter[base64t[i]]=i;
}
string s;
cin>>s;
int len=s.length();
int n=len-4;
for(int i=0;i<n;i+=4){
char b1=s[i];
char b2=s[i+1];
char b3=s[i+2];
char b4=s[i+3];
change(&b1,&b2,&b3,&b4);
r=r+3;
ans.push_back(b1);
ans.push_back(b2);
ans.push_back(b3);
}
char e1,e2,e3,e4;
e1=s[len-4];
e2=s[len-3];
e3=s[len-2];
e4=s[len-1];
endw(&e1,&e2,&e3,&e4);
for(int i=0;i<r;i++)cout<<ans[i];
system("pause");
return 0;
}

一下为2023.3.12更新

TEA

明文8字节,密钥16字节,加解密简单

关键代码:

v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1); 
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);

XTEA

link:

https://blog.csdn.net/gsls200808/article/details/48243019

好吧确实我太懒了

XXTEA

link同上

好吧确实我还是太懒了。