<mark>个人博客:点击进入</mark>
本篇博客做个人查阅使用。
RSA算法
数学基础知识
互质关系
如果两个正整数,除了1以外,没有其他公因子,我们就称这两个数是互质关系
- 任意两个质数构成互质关系
- 一个数是质数,另一个数只要不是前者的倍数,两者就构成互质关系
- 1和任意一个自然数是都是互质关系
- p是大于1的整数,则p和p-1构成互质关系
- p是大于1的奇数,则p和p-2构成互质关系
欧拉函数
在小于等于n的正整数之中,能与n构成互质关系的数的个数
计算这个值的方法叫做欧拉函数,以φ(n)表示
-
如果n=1,则 φ(1) = 1 。因为1与任何数(包括自身)都构成互质关系
-
如果n是质数,则 φ(n)=n-1 。因为质数与小于它的每一个数,都构成互质关系
-
如果n是质数的某一个次方,即 n = p^k (p为质数,k为大于等于1的整数)
φ(pk) = pk - pk-1
-
如果n可以分解成两个互质的整数之积,即
n = p1 × p2
则
φ(n) = φ(p1 × p2) = φ(p1) × φ(p2)
欧拉定理
如果两个正整数a和n互质,则n的欧拉函数 φ(n) 可以让下面的等式成立:
aφ(n)≡1(mod n)
费马小定理:
假设正整数a与质数p互质,因为质数p的φ§等于p-1,则欧拉定理可以写成
ap-1≡1(mod p)
模反元素
如果两个正整数a和n互质,那么一定可以找到整数b,使得 ab-1 被n整除,或者说ab被n除的余数是1。
ab≡1(mod n)
这时候b就叫做a的"模反元素"
RSA算法基本概念
-
RSA加密
密文 = 明文EmodN
公钥 = (E,N)
-
RSA解密
明文 = 密文DmodN
私钥 = (D,N)
公钥 | (E,N) |
私钥 | (D,N) |
密钥对 | (E,D,N) |
加密 | 密文 = 明文EmodN |
解密 | 明文 = 密文DmodN |
生成密钥对过程
-
随机找两个质数p和q,p和q越大越安全,计算他们的乘积
n=p*q
实际算法中p和q的乘积转化为二进制为1024位或2048位,位数越长,算法越难被破解
-
计算n的欧拉函数
L = φ(n)
φ(n)表示在小于等于n的正整数之中,与n构成互质关系的数的个数。
互质关系:互质是公约数只有1的两个整数。
φ(n) = φ(p*q) = φ§*φ(q) = (p-1)*(q-1)
欧拉函数特殊性质:
- 若m,n互质,φ(m*n) = φ(m)*φ(n)
- 若n为质数则,φ(n) = n-1
-
求E
E是随机选取的一个数,满足两个条件:1<E<L;E和L的最大公约数为1
-
求D
D必须满足
1 < D < L E*D mod L = 1
也就是满足乘法逆元E*D≡1(mod L)
D为E关于1模L的乘法逆元
求N | N= p*q ;p,q为质数 |
求L | L = (p-1)*(q-1) |
求E | 1<E<L,E与L互质 |
求D | 1 < D < L,E*D mod L = 1 |
Windows下yafu安装及使用
安装yafu
下载网址:yafu下载
使用yafu
- 进入yafu解压目录,打开cmd命令行
- 输入
yafu-x64
(即yafu64位文件名)
命令:factor(n)
—— n 为需要分解的大数
若n位数过长,将n值保存在文本文档里,最后一定要有换行符
yafu-x64 "factor(@)" -batchfile test.txt
其中test.txt
为保存需分解的大质数的文本文档
使用python来进行RSA加密解密
gmpy2库 安装 请参见 【linux笔记】
有了N求p、q可使用网址大质数分解 或者使用yafu
import gmpy2
N = 103461035900816914121390101299049044413950405173712170434161686539878160984549
E = 65537
p = 282164587459512124844245113950593348271
q = 366669102002966856876605669837014229419
L = (p-1)*(q-1)
D = int(gmpy2.invert(E, L))
''' gmpy2.invert()返回值类型为<class 'mpz'> invert(x,y) 计算 x 关于1模 y 的乘法逆元 '''
enstr = 0xad939ff59f6e70bcbfad406f2494993757eee98b91bc244184a377520d06fc35
destr = gmpy2.powmod(enstr, D, N)
''' gmpy2.powmod()返回值类型为<class 'mpz'> gmpy2.powmod(x,y,z),计算x^y mod z 的值并返回 '''
flag0 = hex(destr)[2:] # flag0类型为str,存的是十六进制表示的字符串
flag1 = bytes.fromhex(flag0) # 将其从十六进制转换为byte类型(此时已解释成字符)
flag = str(flag1, 'utf-8') # 将byte类型转换为str类型
print(flag)
SM4算法
参考链接:欣仔带你零基础入门SM4加密算法
SM4算法简介
SM4是一个分组密码,明文和密文的长度是128位,秘钥的长度是128位。
将128位分成以32位为单位
SM4分步讲解
S盒处理
先进行S盒处理,s盒为特定数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZTF1NKzb-1581058927553)(re加密算法.assets/1.png)]
由于S盒只能处理两位十六进制数,也就是8位,所以处理32位时候采用4个s盒并列来进行加密
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VvqyNywp-1581058927554)(re加密算法.assets/2.png)]
L变换
将S盒输出的32位(例如下图B)作为L变换的输入,
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GBqfX8r7-1581058927554)(re加密算法.assets/4.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LNjokfxb-1581058927555)(re加密算法.assets/3.png)]
也就是L(B)返回B ^ (B<<<2) ^ (B<<<10) ^ (B<<<18) ^ (B<<<24)
轮函数
X0 X1 X2 X3 为128位的明文分成的四个32位
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NXbZEVyL-1581058927555)(re加密算法.assets/6.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nE1U4PMC-1581058927556)(re加密算法.assets/5.png)]
SM4加密算法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1AAwEHIT-1581058927557)(re加密算法.assets/7.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OVR8NWfR-1581058927558)(re加密算法.assets/8.png)]
轮秘钥rk生成
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zAKi7Z4o-1581058927558)(re加密算法.assets/9.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rX8zwiys-1581058927559)(re加密算法.assets/10.png)]
CTF中SM4算法的特征
-
S盒固定
unsigned char TAO[16][16] = { {0xd6,0x90,0xe9,0xfe,0xcc,0xe1,0x3d,0xb7,0x16,0xb6,0x14,0xc2,0x28,0xfb,0x2c,0x05}, {0x2b,0x67,0x9a,0x76,0x2a,0xbe,0x04,0xc3,0xaa,0x44,0x13,0x26,0x49,0x86,0x06,0x99}, {0x9c,0x42,0x50,0xf4,0x91,0xef,0x98,0x7a,0x33,0x54,0x0b,0x43,0xed,0xcf,0xac,0x62}, {0xe4,0xb3,0x1c,0xa9,0xc9,0x08,0xe8,0x95,0x80,0xdf,0x94,0xfa,0x75,0x8f,0x3f,0xa6}, {0x47,0x07,0xa7,0xfc,0xf3,0x73,0x17,0xba,0x83,0x59,0x3c,0x19,0xe6,0x85,0x4f,0xa8}, {0x68,0x6b,0x81,0xb2,0x71,0x64,0xda,0x8b,0xf8,0xeb,0x0f,0x4b,0x70,0x56,0x9d,0x35}, {0x1e,0x24,0x0e,0x5e,0x63,0x58,0xd1,0xa2,0x25,0x22,0x7c,0x3b,0x01,0x21,0x78,0x87}, {0xd4,0x00,0x46,0x57,0x9f,0xd3,0x27,0x52,0x4c,0x36,0x02,0xe7,0xa0,0xc4,0xc8,0x9e}, {0xea,0xbf,0x8a,0xd2,0x40,0xc7,0x38,0xb5,0xa3,0xf7,0xf2,0xce,0xf9,0x61,0x15,0xa1}, {0xe0,0xae,0x5d,0xa4,0x9b,0x34,0x1a,0x55,0xad,0x93,0x32,0x30,0xf5,0x8c,0xb1,0xe3}, {0x1d,0xf6,0xe2,0x2e,0x82,0x66,0xca,0x60,0xc0,0x29,0x23,0xab,0x0d,0x53,0x4e,0x6f}, {0xd5,0xdb,0x37,0x45,0xde,0xfd,0x8e,0x2f,0x03,0xff,0x6a,0x72,0x6d,0x6c,0x5b,0x51}, {0x8d,0x1b,0xaf,0x92,0xbb,0xdd,0xbc,0x7f,0x11,0xd9,0x5c,0x41,0x1f,0x10,0x5a,0xd8}, {0x0a,0xc1,0x31,0x88,0xa5,0xcd,0x7b,0xbd,0x2d,0x74,0xd0,0x12,0xb8,0xe5,0xb4,0xb0}, {0x89,0x69,0x97,0x4a,0x0c,0x96,0x77,0x7e,0x65,0xb9,0xf1,0x09,0xc5,0x6e,0xc6,0x84}, {0x18,0xf0,0x7d,0xec,0x3a,0xdc,0x4d,0x20,0x79,0xee,0x5f,0x3e,0xd7,0xcb,0x39,0x48} };
-
系统参数 FK 固定
unsigned long FK[4] = {0xa3b1bac6, 0x56aa3350, 0x677d9197, 0xb27022dc};
-
固定参数 CK 固定
unsigned long CK[32] = { 0x00070e15, 0x1c232a31, 0x383f464d, 0x545b6269, 0x70777e85, 0x8c939aa1, 0xa8afb6bd, 0xc4cbd2d9, 0xe0e7eef5, 0xfc030a11, 0x181f262d, 0x343b4249, 0x50575e65, 0x6c737a81, 0x888f969d, 0xa4abb2b9, 0xc0c7ced5, 0xdce3eaf1, 0xf8ff060d, 0x141b2229, 0x30373e45, 0x4c535a61, 0x686f767d, 0x848b9299, 0xa0a7aeb5, 0xbcc3cad1, 0xd8dfe6ed, 0xf4fb0209, 0x10171e25, 0x2c333a41, 0x484f565d, 0x646b7279 };
使用python库对SM4算法进行解密
pysm4库 安装 请参见 【linux笔记】
标准128位加密
>>> from pysm4 import encrypt, decrypt
# 明文
>>> clear_num = 0x0123456789abcdeffedcba9876543210
# 密钥
>>> mk = 0x0123456789abcdeffedcba9876543210
# 加密
>>> cipher_num = encrypt(clear_num, mk)
>>> hex(cipher_num)[2:].replace('L', '')
'681edf34d206965e86b3e94f536e4246'
# 解密
>>> clear_num == decrypt(cipher_num, mk)
True
特殊情况参见pysm4安装文档
RC4算法
RC4算法简单讲述
- 生成S盒
开始时,S中元素的值被置为按升序从0到255,即S[0]=0,S[1]=1,…,S[255]=255。同时建立一个临时矢量T(长度与S相同)。如果密钥K的长度为256字节,则将K赋给T(K的长度为可能小于S的长度)。否则,若密钥长度为keylen字节,则将K的值赋给T的前keylen个元素,并循环重复用K的值赋给T剩下的元素,直到T的所有元素都被赋值。
- 打乱S盒
然后用T产生S的初始置换.从S[0]到S [255],对每个S[i],根据由T[i]确定的方案,将S[i]置换为S中的另一字节。
秘钥调度算法(KSA)
void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) //初始化函数
{
int i =0, j = 0;
char k[256] = {0};
unsigned char tmp = 0;
for (i=0;i<256;i++) {
s[i] = i;
k[i] = key[i%Len];
}
for (i=0; i<256; i++) {
j=(j+s[i]+k[i])%256;
tmp = s[i];
s[i] = s[j]; //交换s[i]和s[j]
s[j] = tmp;
}
}
- 矢量S一旦完成初始化,输入密钥就不再被使用。密钥流的生成是从S[0]到S[255],对每个s[i],根据当前S的值,将S[i]与S中的另一字节置换。当S[255]完成置换后,操作继续重复,最后进行异或运算
伪随机生成算法(PRGA)
void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len) //加解密
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for(k=0;k<Len;k++) {
i=(i+1)%256;
j=(j+s[i])%256;
tmp = s[i];
s[i] = s[j]; //交换s[x]和s[y]
s[j] = tmp;
t=(s[i]+s[j])%256;
Data[k] ^= s[t];
}
}
RC4算法解密脚本(c语言)
void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len_k) //初始化函数
{
int i = 0, j = 0;
char k[256] = { 0 };
unsigned char tmp = 0;
for (i = 0; i < 256; i++) {
s[i] = i;
k[i] = key[i % Len_k];
}
for (i = 0; i < 256; i++) {
j = (j + s[i] + k[i]) % 256;
tmp = s[i];
s[i] = s[j]; //交换s[i]和s[j]
s[j] = tmp;
}
}
/*
RC4加解密函数
unsigned char* Data 加解密的数据
unsigned long Len_D 加解密数据的长度
unsigned char* key 密钥
unsigned long Len_k 密钥长度
*/
void rc4_crypt(unsigned char* Data, unsigned long Len_D, unsigned char* key, unsigned long Len_k) //加解密
{
unsigned char s[256];
rc4_init(s, key, Len_k);
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k < Len_D; k++) {
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j]; //交换s[x]和s[y]
s[j] = tmp;
t = (s[i] + s[j]) % 256;
Data[k] ^= s[t];
}
}
MD5加密
MD5基本描述
MD5的输入输出如下
- 输入:任意长的消息,512比特长的分组。
- 输出:160比特的消息摘要。
有时候获得到的md5是16位的,其实那16位是32位md5的长度,是从32位md5值来的。是将32位md5去掉前八位,去掉后八位得到的。
MD5特征(MD5函数的初始化IV)
一般来说,可以通过函数的初始化来判断是不是MD5函数。一般来说,如果一个函数有如下四个初始化的变量,可以猜测该函数为MD5函数,因为这是MD5函数的初始化IV。
var int h0 := 0x67452301
var int h1 := 0xEFCDAB89
var int h2 := 0x98BADCFE
var int h3 := 0x10325476
查询MD5的网站
- http://www.cmd5.com/
- http://www.ttmd5.com/
- http://pmd5.com/
AES算法
待整理
tea系列
tea系列加解密脚本(c语言)
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#define tea_DELTA 0x9e3779b9
/* tea加密函数 32轮加密,请根据需要更改 uint32_t* origin 为要加密的数据是两个32位无符号整数 uint32_t* key 为加密解密密钥,为4个32位无符号整数,即密钥长度为128位 */
void tea_encode(uint32_t* origin, uint32_t* key) {
uint32_t v0 = origin[0], v1 = origin[1], sum = 0, i; /* set up */
uint32_t delta = 0x9e3779b9; /* a key schedule constant */
uint32_t k0 = key[0], k1 = key[1], k2 = key[2], k3 = key[3]; /* cache key */
for (i = 0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
v1 += ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
} /* end cycle */
origin[0] = v0; origin[1] = v1;
}
/* tea解密函数 32轮解密,请根据需要更改 uint32_t* origin 为要加密的数据是两个32位无符号整数 uint32_t* key 为加密解密密钥,为4个32位无符号整数,即密钥长度为128位 */
void tea_decode(uint32_t* origin, uint32_t* key) {
uint32_t v0 = origin[0], v1 = origin[1], i; /* set up */
uint32_t delta = 0x9e3779b9,sum = delta << 5; //32轮运算,所以是2的5次方;16轮运算,所以是2的4次方;8轮运算,所以是2的3次方/* a key schedule constant */
uint32_t k0 = key[0], k1 = key[1], k2 = key[2], k3 = key[3]; /* cache key */
for (i = 0; i < 32; i++) { /* basic cycle start */
v1 -= ((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3);
v0 -= ((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1);
sum -= delta;
} /* end cycle */
origin[0] = v0; origin[1] = v1;
}
/* xtea加密函数 num_rounds 加密轮数 uint32_t* origin 为要加密的数据是两个32位无符号整数 uint32_t* k 为加密解密密钥,为4个32位无符号整数,即密钥长度为128位 */
void xtea_encode(unsigned int num_rounds, uint32_t origin[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0 = origin[0], v1 = origin[1], sum = 0, delta = 0x9E3779B9;
for (i = 0; i < num_rounds; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
}
origin[0] = v0; origin[1] = v1;
}
/* xtea解密函数 num_rounds 加密轮数 uint32_t* origin 为要加密的数据是两个32位无符号整数 uint32_t* k 为加密解密密钥,为4个32位无符号整数,即密钥长度为128位 */
void xtea_decode(unsigned int num_rounds, uint32_t origin[2], uint32_t const key[4]) {
unsigned int i;
uint32_t v0 = origin[0], v1 = origin[1], delta = 0x9E3779B9, sum = delta * num_rounds;
for (i = 0; i < num_rounds; i++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
}
origin[0] = v0; origin[1] = v1;
}
// xxtea加密解密
#if 0
int main()//例子
{
uint32_t v[2] = { 1,2 };
uint32_t const k[4] = { 2,2,3,4 };
int n = 2; //n的绝对值表示v的长度,取正表示加密,取负表示解密
// v为要加密的数据是两个32位无符号整数
// k为加密解密密钥,为4个32位无符号整数,即密钥长度为128位
printf("加密前原始数据:%u %u\n", v[0], v[1]);
xxtea(v, n, k);
printf("加密后的数据:%u %u\n", v[0], v[1]);
xxtea(v, -n, k);
printf("解密后的数据:%u %u\n", v[0], v[1]);
return 0;
}
#endif
#define xxtea_MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
/* origin 为要加密的数据是两个32位无符号整数(若加密字符串先转换为16进制整数) n 的绝对值表示v的长度(即有几个32位整数),取正表示加密,取负表示解密 key 为加密解密密钥,为4个32位无符号整数,即密钥长度为128位 */
void xxtea(uint32_t* origin, int n, uint32_t const key[4])
{
uint32_t y, z, sum;
unsigned p, rounds, e;
if (n > 1) /* Coding Part */
{
rounds = 6 + 52 / n;
sum = 0;
z = origin[n - 1];
do
{
sum += tea_DELTA;
e = (sum >> 2) & 3;
for (p = 0; p < n - 1; p++)
{
y = origin[p + 1];
z = origin[p] += xxtea_MX;
}
y = origin[0];
z = origin[n - 1] += xxtea_MX;
} while (--rounds);
}
else if (n < -1) /* Decoding Part */
{
n = -n;
rounds = 6 + 52 / n;
sum = rounds * tea_DELTA;
y = origin[0];
do
{
e = (sum >> 2) & 3;
for (p = n - 1; p > 0; p--)
{
z = origin[p - 1];
y = origin[p] -= xxtea_MX;
}
z = origin[n - 1];
y = origin[0] -= xxtea_MX;
sum -= tea_DELTA;
} while (--rounds);
}
}
base64加解密
更多讲解请参见 【Base16,Base32,Base64编码详细学习】
base64加解密脚本(c语言)
/* base64加密 const unsigned char* src 需要加密的数组 unsigned char* dst 加密之后存储的数组 */
int base64_encode(const unsigned char* src, unsigned char* dst)
{
size_t len = strlen((const char*)src);
static unsigned char base64char[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
while (len > 2) {
*dst++ = base64char[src[0] >> 2 & 0x3f];
*dst++ = base64char[(src[0] & 0x3) << 4 | src[1] >> 4 & 0xf];
*dst++ = base64char[(src[1] & 0xf) << 2 | src[2] >> 6 & 0x3];
*dst++ = base64char[src[2] & 0x3f];
len -= 3;
src += 3;
}
if (len) {
*dst++ = base64char[src[0] >> 2 & 0x3f];
if (len > 1) {
*dst++ = base64char[((src[0] & 0x3) << 4) | ((src[1] >> 4) & 0xf)];
*dst++ = base64char[(src[1] & 0xf) << 2];
}
else {
*dst++ = base64char[(src[0] & 0x3) << 4];
*dst++ = '=';
}
*dst++ = '=';
}
*dst = 0;
return 0;
}
/* base64解密 const unsigned char* src 需要解密的字符 unsigned char* dst 解密之后存储的数组 */
int base64_decode(const unsigned char* src, unsigned char* dst)
{
static char base64char[] = {
-1 , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1 , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1 , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1 , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63,
-1 , 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
};
int i;
size_t len = strlen((const char*)src);
for (i = 0; i < len; i++) {
if (src[i] == -1) {
return 1; //unexpected characters
}
else if (src[i] == '=') {
len = i;
}
}
if (len % 4 == 1) {
return 2;
}
while (len > 3) {
*dst++ = (unsigned char)(base64char[src[0]] << 2) | (base64char[src[1]] >> 4 & 0x3);
*dst++ = (unsigned char)(base64char[src[1]] << 4) | (base64char[src[2]] >> 2 & 0xf);
*dst++ = (unsigned char)(base64char[src[2]] << 6) | (base64char[src[3]]);
src += 4;
len -= 4;
}
if (len) {
if (len > 1) {
*dst++ = (base64char[src[0]] << 2) | (base64char[src[1]] >> 4 & 0x3);
}
if (len > 2) {
*dst++ = (base64char[src[1]] << 4) | (base64char[src[2]] >> 2 & 0xf);
}
}
*dst = 0;
return 0;
}
/* base64自定义字符表加密 char* src 存放待加密字符串的数组 char* dst 存放加密后字符串的数组 char* mytable 自定义字符表 */
void base64_myen(char* src, char*dst, char* mytable)
{
base64_encode((const unsigned char*)src,(unsigned char*)dst);
int i, j;
char base64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int len_s = strlen(dst);
for (i = 0; i < len_s; i++)
{
for (j = 0; j < 65; j++)
{
if (dst[i] == base64_table[j])
{
dst[i] = mytable[j];
break;
}
}
}
}
/* base64自定义字符表解密 char* src 存放待解密字符串的数组 char* dst 存放解密后字符串的数组 char* mytable 自定义字符表 */
void base64_myde(char* src, char* dst, char* mytable)
{
int i, j;
char base64_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int len_s = strlen(src);
for (i = 0; i < len_s; i++)
{
for (j = 0; j < 65; j++)
{
if (src[i] == mytable[j])
{
src[i] = base64_table[j];
break;
}
}
}
base64_decode((const unsigned char*)src, (unsigned char*)dst);
}