最近在工作中做数据安全模块,有些非常巧妙的位移、异或计算加解密使用的非常好,下面记录一下。
1、加密代码
参数中 plaintext为明文、plaintext_size=64、ciphertext为密文、ciphertext_size=128
int fake_rsa_encrypt(
const unsigned char* plaintext,
unsigned int plaintext_size,
unsigned char *ciphertext,
size_t *ciphertext_size)
{
struct timeval time;
gettimeofday(&time, NULL);
// microsecond has 1 000 000
// Assuming you did not need quite that accuracy
// Also do not assume the system clock has that accuracy.
srand((time.tv_sec * 1000) + (time.tv_usec / 1000));
if ((plaintext_size < 128) && (!(plaintext_size & 3))) {
int i, j;
for (i = 0; i < (int)(128 - plaintext_size); i += 4) {
long rdm = random();
ciphertext[i + 0] = (rdm >> 24) & 0xff;
ciphertext[i + 1] = (rdm >> 16) & 0xff;
ciphertext[i + 2] = (rdm >> 8) & 0xff;
ciphertext[i + 3] = (rdm)& 0xff;
}
for (i = 128 - plaintext_size, j = 0; i < 128; ++i, ++j) {
ciphertext[i] = plaintext[j] ^ ciphertext[j];
}
}
else {
return -1;
}
*ciphertext_size = 128;
return 0;
}
注意:!(plaintext_size & 3) 的意思是判断是否非0,参考以下文章,传送门:&运算(位运算)
上述代码中有一段
struct timeval time;
gettimeofday(&time, NULL);
// microsecond has 1 000 000
// Assuming you did not need quite that accuracy
// Also do not assume the system clock has that accuracy.
srand((time.tv_sec * 1000) + (time.tv_usec / 1000));
这个代码的含义是将当前时间设置为一个随机种子,然后通过以下代码获取随机数
long rdm = random();
上面这两个方法是配合使用的,需要先用一个独特的数设置种子,然后再获取随机数。
2、解密代码
参数中 ciphertext为密文、plaintext为明文、plaintext_size=64
int fake_rsa_decrypt(
const unsigned char* ciphertext,
unsigned char *plaintext,
size_t *plaintext_size)
{
*plaintext_size = 64;
if (((*plaintext_size) < 128) && (!((*plaintext_size) & 3))) {
int i;
for (i = 0; i < (int)(*plaintext_size); i++) {
plaintext[i] = ciphertext[128 - (*plaintext_size) + i] ^ ciphertext[i];
}
}
else {
return -1;
}
return 0;
}
精妙之处就是 ciphertext 是128位的密文数组,他的前64位保存的是随机数数组,后64位保存的是异或计算后的数组,用后64位和前64位进行异或计算就能够得到加密之前传入的明文数组了,非常巧妙吧。