Base64的加密与解密

2020年7月26日18:26:42 发表评论

今天逛CTF的时候偶然碰到一道Base64解密的题目,题目是这样的:

#题目已更新 2020-1-11 11:09# 一种很著名的编码,你会吗? 请将以下“密码”解码后,得到flag。 N0NDRTc5OEUtNjkyMC00NjI2LUE4RDctMzUyQUUyQUMyODk5

当时一下子没反应过来是base64,印象中Base64是有很多百分号组成。因为没有说密钥,所以就试了试最简单的移位替换密码,结果非常的Amazing啊!

Base64的加密与解密

一个有意义的串都没有,然后因为没有给出密钥,又排除了base64,只好不再花多余的时间尝试了,毕竟密码算法储备量不是很足。最后知道它是Base64加密的。

Base64加密与解密

1.准备

明文=[ABC]

数组=[ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=]

2.把明文用ASCII表示

对照ASCII表,明文= [01000001,01000010,01000011]

3.把明文分成三个字节一组

得到两组,一组=[01000001,01000010,01000011]

4.将每组拆分成4个6位,并在每个6位前面补两个0凑成一个字节

[    010000,     010100,     001001,     000011]    再补两个0得到

[00010000, 00010100, 00001001, 00000011]

5.转化成十进制,对应给出数组的下标

转换成十进制为:[16,20,9,3]         对应的值为:QUJD,即为密文。

问题:如果明文字节数不是3的整数倍怎么办?

如果字节数不是3的整数倍,余数为1的话,补4个0凑成两个6位的,其他两个6位对应就用”=“表示,即ABCD对应的格式就是******==。

如果余数位2的话,补2两个0凑成3个6位的,其他一个六位的对应就用”=“表示,即:ABCDE对应的格式就是*******=。

编程,用C++编程写出Base64的加密和解密程序

/**********************************main.c************************************/
#include<iostrem> 
#include"base64.h"
using namespace std;

int main()
{
	int n = -1;
	int len = 100;
	unsigned char*code = NULL;
	unsigned char*plainText = NULL;
	while (true) {
		cout << "list" << endl;
		cout << "1.encrypt base64" << endl;
		cout << "2.decrypt base64" << endl;
		cout << "3.exit" << endl;
		cout << "what do you want? "; cin >> n;
		if (n == 1) {
			cout << "good! please input the string max length:"; 
                        cin >> len;
			plainText = (unsigned char*)malloc(sizeof(char)*len);
			cout << "then input a string you want to encrypt:";
			cin >> plainText;
			//encrypt
			code = base64Encrypt(plainText);
			cout << code << endl;
		}
		else if (n == 2) {
			cout << "good! please input the code max length:"; 
			cin >> len;
			code = (unsigned char*)malloc(sizeof(char)*len);
			cout << "then input the code you want to decrypt:"; 
			cin >> code;
			//decrypt
			plainText = base64Decrypt(code);
			cout << plainText << endl;
		}
		if (code != NULL)free(code);
		if (plainText != NULL)free(plainText);
		else exit(0);
	}
	return 0;
}
/*********************************base64.h**********************************/

unsigned char dict[66] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
//encrypt a string with base64
unsigned char* base64Encrypt(unsigned char*plainText) {
	//get plainText's real length
	int len=-1;
	int mod=0;  // =len%3
	while(plainText[++len]!='\0');
	mod=len%3;
	if (len%3!=0)len = (len/3+1)*3;
	//malloc space for code
	unsigned char* code = (unsigned char*)malloc(sizeof(char)*len/3*4+1);
	//encrypt 11111111 11111111 11111111
	for (int i=0; i < len/3; i++) { 
		code[i*4+0]=dict[plainText[i*3+0] >>2];
		code[i*4+1]=dict[((unsigned char)(plainText[i*3+0]<<6)>>2)+(plainText[i*3+1]>>4)];
		code[i*4+2]=dict[((unsigned char)(plainText[i*3+1]<<4)>>2)+(plainText[i*3+2]>>6)];
		code[i*4+3]=dict[(unsigned char)(plainText[i*3+2] << 2)>>2];
		if (i==len/3-1 && (mod==1 || mod==2)) {
			code[i*4+3] = dict[64];
		}
		if (i==len/3-1 && mod == 1) {
			code[i * 4 + 2] = dict[64];
		}
	}
	code[len / 3 * 4] = '\0';
	return code;
}
//decrypt the code with base64
unsigned char* base64Decrypt(unsigned char*code) {
	//get code's real length
	int len = 0;
	while(code[len++] != '\0');
	//malloc space for plainText
	unsigned char* plainText = (unsigned char*)malloc(sizeof(char)*len/4*3+1);
	//decrypt
	for (int i=0; i < len; i++) {
		for (int j=0; j < 65; j++)
			if (code[i] == dict[j]) {
				code[i]=j; break;
			}
	}
	for (int i = 0; i < len / 4; i++) {
		plainText[i*3+0]=((unsigned char)code[i*4+0]<<2)+(code[i*4+1]>>4);
		plainText[i*3+1]=((unsigned char)code[i*4+1]<<4)+(code[i*4+2]>>2);
		plainText[i*3+2]=((unsigned char)code[i*4+2]<<6)+(code[i*4+3]);
		if (i==len/4-1&&code[i*4+3]==64)plainText[i*3+2]=' ';
		if (i==len/4-1&&code[i*4+2]==64)plainText[i*3+1]=' ';
	}
	plainText[len/4*3] = '\0';
	return plainText;
}

编译好的程序

Base64的加密与解密

下面是白嫖用户的福利,点击即可下载编译好的exe文件链接。提取码:1qe9 。

flyingsheep

发表评论