Visual Studio 2015 中使用 OpenSSL
该文章根据 CC-BY-4.0 协议发表,转载请遵循该协议。
本文地址:https://fenying.net/post/2015/12/02/using-openssl-with-vs2015/
文章目录
在 Visual Studio 2015 中使用 OpenSSL 的记录。
1. 编译
编译 OpenSSL 没什么难度,直接命令行就可以搞定。不过要注意一点细节。
-
官网下载 OpenSSL-1.0.0s.tar.gz。
-
安装 Perl For Windows,用于生产 mak 脚本,安装一个 ActivePerl 即可。
-
在开始菜单打开 VS2015 x86 本机工具命令提示符。(64位的也差不多,参考 INSTALL.w64)
-
先把 PERL 安装目录写入 PATH。
1SET PATH=%PATH%;PERL安装目录\site\bin;PERL安装目录\bin
-
执行configure,注意 –prefix 是输出目录。
1perl Configure VC-WIN32 no-asm --prefix=x:/openssl
-
接下来先不要急着编译,最重要的是先修改生成的 .mak 文件。因为 .mak 脚本强制把 C 编译警告当成错误处理,这会导致编译失败。
方法是打开 ms/ntdll.mak,修改第 20 行,把 /WX 去掉。
如果你要编译静态库,那么则应该修改 ms/nt.mak,修改方法一样。
注意,如果要编译 DEBUG 版本,那么在 ms/ntdll.mak (或 ms/nt.mak)的第 20 行处,给 /MD(或/MT)后面加一个d,变成 /MDd(或 /MTd),即可。
-
打开 e_os.h,跳到 319 行,把这一行
1# if _MSC_VER>=1300
替换成如下内容并保存。否则会导致链接错误,因为 VC2015 中标准IO流的定义被修改了。
1# if _MSC_VER>=1400 2_ACRTIMP_ALT FILE* __cdecl __acrt_iob_func(unsigned); 3# define stdin (__acrt_iob_func(0)) 4# define stdout (__acrt_iob_func(1)) 5# define stderr (__acrt_iob_func(2)) 6# elif _MSC_VER>=1300
-
现在,开始编译。
编译静态链接库
1nmake -f ms\nt.mak 2nmake -f ms\nt.mak install 3nmake -f ms\nt.mak clean
编译动态链接库
1nmake -f ms\ntdll.mak 2nmake -f ms\ntdll.mak install 3nmake -f ms\ntdll.mak clean
-
测试代码,如果遇到报错
1OPENSSL_Uplink(006E9000,08): no OPENSSL_Applink
则包含文件
1#include <openssl/applink.c>
2. 测试
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <openssl/rsa.h>
5#include <openssl/pem.h>
6#include <openssl/err.h>
7#include <openssl/applink.c>
8#include <openssl/md5.h>
9#include <openssl/sha.h>
10
11#define OPENSSLKEY "test.key"
12#define PUBLICKEY "test_pub.key"
13
14typedef unsigned char byte_t;
15
16byte_t *rsaEncrypt(byte_t *inputData, size_t *inputLength, byte_t *pBuffer, size_t bufLength, char *priKeyPath) {
17
18 RSA *pRSA;
19 FILE *hFile;
20 size_t lenRSA;
21
22 if ((hFile = fopen(priKeyPath, "r")) == NULL)
23 return NULL;
24
25 if ((pRSA = PEM_read_RSA_PUBKEY(hFile, NULL, NULL, NULL)) == NULL)
26 return NULL;
27
28 lenRSA = RSA_size(pRSA);
29
30 if (*inputLength > lenRSA - RSA_PKCS1_PADDING_SIZE || bufLength < lenRSA)
31 return NULL;
32
33 memset(pBuffer, 0, lenRSA);
34
35 if ((lenRSA = RSA_public_encrypt(*inputLength, inputData, pBuffer, pRSA, RSA_PKCS1_PADDING)) == -1) {
36 return NULL;
37 }
38
39 *inputLength = lenRSA;
40
41 RSA_free(pRSA);
42 fclose(hFile);
43 return pBuffer;
44}
45
46byte_t *rsaDecrypt(byte_t *inputData, size_t inputLength, byte_t *pBuffer, size_t bufLength, char *path_key) {
47
48 RSA *pRSA;
49 FILE *hFile;
50 int lenRSA;
51
52 if ((hFile = fopen(path_key, "r")) == NULL)
53 return NULL;
54
55 if ((pRSA = PEM_read_RSAPrivateKey(hFile, NULL, NULL, NULL)) == NULL)
56 return NULL;
57
58 lenRSA = RSA_size(pRSA);
59
60 if (inputLength != lenRSA)
61 return NULL;
62
63 memset(pBuffer, 0, lenRSA);
64
65 if (RSA_private_decrypt(lenRSA, inputData, pBuffer, pRSA, RSA_PKCS1_PADDING) < 0)
66 return NULL;
67
68 RSA_free(pRSA);
69 fclose(hFile);
70 return pBuffer;
71}
72
73int main(int argc, char** argv) {
74 char *pData = "Hello RSA, This is a test.";
75 MD5_CTX md5Data;
76 SHA_CTX sha1Data;
77 byte_t encBuf[512], decBuf[512];
78 size_t lenInput;
79 int i;
80 printf("Input Data:%s\n", pData);
81
82 /* RSA */
83
84 lenInput = strlen(pData);
85
86 rsaEncrypt((byte_t*)pData, &lenInput, encBuf, sizeof(encBuf), PUBLICKEY);
87 printf("after encrypt[%lu]:%s\n", lenInput, encBuf);
88
89 rsaDecrypt(encBuf, lenInput, decBuf, sizeof(decBuf), OPENSSLKEY);
90 printf("after decrypt:%s\n", decBuf);
91
92 /* MD5 */
93
94 lenInput = strlen(pData);
95
96 MD5_Init(&md5Data);
97
98 MD5_Update(&md5Data, pData, lenInput);
99 MD5_Final(encBuf, &md5Data);
100
101 printf("MD5: ");
102 for (i = 0; i < 16; i++)
103 printf("%02x", encBuf[i]);
104 putchar('\n');
105
106 /* SHA-1 */
107
108 lenInput = strlen(pData);
109
110 SHA1_Init(&sha1Data);
111
112 SHA1_Update(&sha1Data, pData, lenInput);
113 SHA1_Final(encBuf, &sha1Data);
114
115 printf("SHA-1: ");
116 for (i = 0; i < 20; i++)
117 printf("%02x", encBuf[i]);
118 putchar('\n');
119
120 return 0;
121}
3. 参考文献
comments powered by Disqus