OpenSSL入门-常用密码

安装

来这里下载二进制https://wiki.openssl.org/index.php/Binaries 并进行安装,不要选择Lite版,且注意将动态链接库放在安装目录下。

新建一个Visual Studio项目,项目属性中的VC++目录下有个包含目录,添加OpenSSL的include目录,库目录添加lib目录对应模式的子目录。链接器设置中输入的附加依赖项添加:

1
2
libssl.lib
libcrypto.lib

最后将bin目录下的libcrypto-3-x64.dll和libssl-3-x64.dll拷贝到工程目录下。

能运行以下代码就算成功:

1
2
3
4
5
6
7
#include <iostream>
#include "openssl/evp.h"
int main(void) {
OpenSSL_add_all_algorithms();
std::cout << "Hello World!\n";
return 0;
};

RC4

RC4_set_key来生成密钥流:

1
2
3
4
5
void RC4_SET_KEY(
RC4_KEY* key, //输出生成的密钥流
int len, //data长度
const unsigned char* data //用户设置的密钥
);

RC4实现加密或解密:

1
2
3
4
5
6
void RC4(
RC4_KEY* key, //密钥流
unsigned long len, //indata长度
const unsigned char* indata, //输入的数据
unsigned char* outdata //结果
);

例如:

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
26
27
28
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <openssl/rc4.h>
int main(int argc, char* argv[]) {
RC4_KEY key; //密钥流结构体
const char* data = "Hello,World!!";
int length = strlen(data);
RC4_set_key(&key, length, (unsigned char*)data);
const char* indata = "This is plain text !!!!";
int len = strlen(indata);
printf("strlen(indata)=%d\n", len);
char* outdata;//分配密文空间
outdata = (char*)malloc(sizeof(unsigned char) * (len + 1));
memset(outdata, 0, len + 1);//初始为0
printf("\tindata=%s\n", indata);
RC4(&key, strlen(indata), (unsigned char*)indata, (unsigned char*)outdata);
printf("\toutdata=%s\n", outdata);
printf("strlen(outdata)=%d\n", strlen(outdata));
char* plain;//分配明文空间
plain = (char*)malloc(sizeof(unsigned char) * (len + 1));
memset(plain, 0, len + 1);//初始化为0
RC4_set_key(&key, length, (unsigned char*)data);
RC4(&key, strlen(outdata), (unsigned char*)outdata, (unsigned char*)plain);
printf("\tplain=%s\n", plain);
printf("strlen(plain)=%d\n", strlen(plain));
return 0;
};

C语言版:

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
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "pch.h"
#include <iostream>
//RC4算法对数据的加密和解密
#include <stdio.h>
#define MAX_CHAR_LEN 10000
void produceKeystream(int textlength, unsigned char key[],int keylength, unsigned char keystream[]){
unsigned int S[256];
int i, j = 0, k;
unsigned char tmp;
for (i = 0; i < 256; i++)
S[i] = i;
for (i = 0; i < 256; i++) {
j = (j + S[i] + key[i % keylength]) % 256;
tmp = S[i];
S[i] = S[j];
S[j] = tmp;
}
i = j = k = 0;
while (k < textlength) {
i = (i + 1) % 256;
j = (j + S[i]) % 256;
tmp = S[i];
S[i] = S[j];
S[j] = tmp;
keystream[k++] = S[(S[i] + S[j]) % 256];
}
}
void rc4encdec(int textlength, unsigned char plaintext[],unsigned char keystream[],unsigned char ciphertext[]){
int i;
for (i = 0; i < textlength; i++)
ciphertext[i] = keystream[i] ^ plaintext[i];
}
int main(int argc, char *argv[]){
unsigned char plaintext[MAX_CHAR_LEN];
unsigned char chktext[MAX_CHAR_LEN];
unsigned char key[32];
unsigned char keystream[MAX_CHAR_LEN];
unsigned char ciphertext[MAX_CHAR_LEN];
unsigned c;
int i = 0, textlength, keylength;
FILE *fp;
if ((fp = fopen("明文.txt", "r")) == NULL) {
printf("file \"%s\" not found!\n", *argv);
return 0;
}
while ((c = getc(fp)) != EOF)
plaintext[i++] = c;
textlength = i;
fclose(fp);
/* input a key */
printf("passwd: ");
for (i = 0; (c = getchar()) != '\n'; i++)
key[i] = c;
key[i] = '\0';
keylength = i;
/* use key to generate a keystream */
produceKeystream(textlength, key, keylength, keystream);
/* use the keystream and plaintext to generate ciphertext */
rc4encdec(textlength, plaintext, keystream, ciphertext);
fp = fopen("密文.txt", "w");
for (int i = 0; i < textlength; i++)
putc(ciphertext[i], fp);
fclose(fp);
rc4encdec(textlength, ciphertext, keystream, chktext);
if (memcmp(chktext, plaintext, textlength) == 0)
puts("源明文和解密后的明文内容相同!加解密成功!!\n");
fp = fopen("解密后的明文.txt", "w");
for (int i = 0; i < textlength; i++)
putc(chktext[i], fp);
fclose(fp);
return 0;
}