1. Windows环境
- Windows 10
- VS 2019
- nasm汇编工具:https://nasm.us/
- Perl: 官网地址https://www.perl.org/get.html
- OpenSSL:
- 官网地址:https://www.openssl.org/
- Github: https://github.com/openssl/openssl
- Releases: https://www.openssl.org/source/old/
- Tags: https://github.com/openssl/openssl/tags
Perl
Perl有Activestate和Strawberry两种版本,后者比前者多了许多模块,要大很多。
而Strawberry版本安装后带了一个300多M的C开发环境,删掉后把perl.exe路径添加到环境变量即可。
Github建议使用Strawberry版本,这样就不用额外构建模块了。使用msi安装包可以自动添加环境变量,如果使用压缩包版本记着手动添加一下。
装完执行 perl -v
有版本回显则安装成功。
nasm
直接在官网安装最新版,并添加环境变量。
OpenSSL
OpenSSL源码使用3.0 LTS版本,该版本维护到2026年9月7日。本文使用的是3.0.5版本
https://www.openssl.org/source/old/3.0/
除了源码,还有hash和签名,逐个验证一下。
# 先验证完整性。SHA1和SHA256,碰撞一个是有可能的,但两个都碰撞就几乎不可能了:
> certutil -hashfile .\openssl-3.0.5.tar.gz SHA1
SHA1 的 .\openssl-3.0.5.tar.gz 哈希:
a5305213c681a5a4322dad7347a6e66b7b6ef3c7
CertUtil: -hashfile 命令成功完成。
> certutil -hashfile .\openssl-3.0.5.tar.gz SHA256
SHA256 的 .\openssl-3.0.5.tar.gz 哈希:
aa7d8d9bef71ad6525c55ba11e5f4397889ce49c2c9349dcea6d3e4f0b024a7a
CertUtil: -hashfile 命令成功完成。
# 获取签名key
>gpg --verify openssl-3.0.5.tar.gz.asc openssl-3.0.5.tar.gz
gpg: Signature made Tue Jul 5 16:57:31 2022
gpg: using RSA key 7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C
gpg: issuer "levitte@openssl.org"
gpg: Can't check signature: No public key
# 从服务器导入公钥
>gpg --keyserver hkp://keys.gnupg.net --recv-key 7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C
gpg: key D5E9E43F7DF9EE8C: 1 duplicate signature removed
gpg: key D5E9E43F7DF9EE8C: public key "Richard Levitte <richard@levitte.org>" imported
gpg: Total number processed: 1
gpg: imported: 1
# 再次验签
>gpg --verify openssl-3.0.5.tar.gz.asc openssl-3.0.5.tar.gz
gpg: Signature made Tue Jul 5 16:57:31 2022
gpg: using RSA key 7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C
gpg: issuer "levitte@openssl.org"
gpg: Good signature from "Richard Levitte <richard@levitte.org>" [unknown]
gpg: aka "Richard Levitte <richard@opensslfoundation.org>" [unknown]
gpg: aka "Richard Levitte <richard@openssl.com>" [unknown]
gpg: aka "Richard Levitte <levitte@lp.se>" [unknown]
gpg: aka "Richard Levitte <levitte@openssl.org>" [unknown]
gpg: aka "Richard Levitte <richard@opensslfoundation.com>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg: There is no indication that the signature belongs to the owner.
Primary key fingerprint: 7953 AC1F BC3D C8B3 B292 393E D5E9 E43F 7DF9 EE8C
编译
管理员身份打开vs的命令行:win键搜索“prompt”等关键词,或者执行vs安装目录\Community\VC\Auxiliary\Build
下的对应架构脚本。VS官网文档对各个命令行的介绍:
Developer Command Prompt - Sets the environment to use 32-bit, x86-native tools to build 32-bit, x86-native code.
x86 Native Tools Command Prompt - Sets the environment to use 32-bit, x86-native tools to build 32-bit, x86-native code.
x64 Native Tools Command Prompt - Sets the environment to use 64-bit, x64-native tools to build 64-bit, x64-native code.
x86_x64 Cross Tools Command Prompt - Sets the environment to use 32-bit, x86-native tools to build 64-bit, x64-native code.
x64_x86 Cross Tools Command Prompt - Sets the environment to use 64-bit, x64-native tools to build 32-bit, x86-native code.
为了方便调试和学习,我用默认的Developer Command Prompt编译成32位。
执行OpenSSL下的Configure,生成makefile:
# 为了方便调试和学习 选择x86架构
# 所有支持的平台可以在\util\perl\OpenSSL\config.pm查看
# 默认架构则是与当前系统一致
# --prefix指定安装目录
# --debug 生成调试符号
# 其它选项可以查看Configure文件中的注释 如-static
>perl Configure VC-WIN32 --prefix=E:\prooooooooooogram1\openssl\build_x86 --debug
Using os-specific seed configuration
Created configdata.pm
Running configdata.pm
Created makefile.in
Created makefile
**********************************************************************
*** ***
*** OpenSSL has been successfully configured ***
*** ***
*** If you encounter a problem while building, please open an ***
*** issue on GitHub <https://github.com/openssl/openssl/issues> ***
*** and include the output from the following command: ***
*** ***
*** perl configdata.pm --dump ***
*** ***
*** (If you are new to OpenSSL, you might want to consult the ***
*** 'Troubleshooting' section in the INSTALL.md file first) ***
*** ***
**********************************************************************
开始编译,需要等几分钟:
nmake
nmake test
安装,这里如果一开始不指定prefix安装路径,则默认装在c盘ProgramFiles路径,需要管理员权限。
nmake install
这一步将编译结果复制到安装目录里,包括:
- bin:可执行文件、动态库、调试符号;
- html:文档;
- include:头文件;
- lib:为动态库配备的导入库(不是静态库)。
E:\prooooooooooogram1\openssl\build_x86> ls
目录: E:\prooooooooooogram1\openssl\build_x86
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2022/12/14 17:33 bin
d----- 2022/12/14 17:36 html
d----- 2022/12/14 17:32 include
d----- 2022/12/14 17:32 lib
VS测试项目
在build_x86同级目录openssl下新建一个vs工程TestOpenSSL:
PS E:\prooooooooooogram1\openssl> ls
目录: E:\prooooooooooogram1\openssl
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 2022/12/15 9:59 build_x86 # 编译好的openssl库
d----- 2022/12/15 9:55 openssl-3.0.5 # openssl源码
d----- 2022/12/15 10:04 TestOpenSSL # vs工程
-a---- 2022/12/13 14:12 15074407 openssl-3.0.5.tar.gz
-a---- 2022/12/13 14:16 862 openssl-3.0.5.tar.gz.asc
-a---- 2022/12/13 14:16 42 openssl-3.0.5.tar.gz.sha1
-a---- 2022/12/13 14:16 66 openssl-3.0.5.tar.gz.sha256
工程配置如下:
- Debug 模式,Win32平台;
- 调试-工作目录:
..\build_x86\bin\
,与依赖的dll放在同一目录; - VC++目录-包含目录,添加
..\build_x86\include
; - 链接器-依赖库目录:
..\build_x86\lib
- 链接器-输入:添加依赖库
libcrypto.lib
在源码demos目录下找一个示例文件,拷贝过来:
\openssl-3.0.5\demos\cipher\aesccm.c
这里编译运行,会报错:
OPENSSL_Uplink(50AB3378,07): no OPENSSL_Applink
这是openssl在windows平台下的兼容问题,对应文档:
/build_x86/html/man3/OPENSSL_Applink.html
OPENSSL_Applink - glue between OpenSSL BIO and Win32 compiler run-time
解决方法:打开aesccm.c,开头添加如下代码
#define _CRT_SECURE_NO_WARNINGS // disable deprecation warning
#ifdef __cplusplus
extern "C" {
#endif
#ifdef WIN32
#include <openssl/applink.c>
#endif
#ifdef __cplusplus
};
#endif
之后可以顺利运行:
因为openssl编译时生成了调试符号,所以可以单步调试进入底层逻辑:
2. Linux环境
- Ubuntu 20.04
- VS Code远程开发环境,依赖插件:
- c/c++
- Remote SSH
编译
tar -xvf openssl-3.0.5.tar.gz
cd openssl-3.0.5
# 如果要编译32位,则执行./Configure linux-x86, 64位机器上需要安装依赖库
# 安装路径等选项 默认即可
./Configure --debug
make -j2
make test
make install
测试项目
这次把\openssl-3.0.5\demos\cipher\
这个文件夹拿来测试,因为这里其实是有一个makefile的:
E:\prooooooooooogram1\openssl\openssl-3.0.5\demos\cipher> ls
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 2022/7/5 16:57 7247 aesccm.c
-a---- 2022/7/5 16:57 6504 aesgcm.c
-a---- 2022/7/5 16:57 5048 ariacbc.c
-a---- 2022/7/5 16:57 575 Makefile
Makefile内容如下:
CFLAGS = $(OPENSSL_INCS_LOCATION) -g
# 手动添加-g 支持调试
LDFLAGS = $(OPENSSL_LIBS_LOCATION) -lssl -lcrypto
# 链接libssl.so和libcrypto.so
all: aesccm aesgcm ariacbc
aesccm: aesccm.o
aesgcm: aesgcm.o
ariacbc: ariacbc.o
aesccm aesgcm ariacbc:
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
clean:
$(RM) aesccm aesgcm ariacbc *.o
执行命令:
make
./aesccm
#报错
./aesccm: error while loading shared libraries: libcrypto.so.3: cannot open shared object file: No such file or directory
原因是软件包管理器没有更新刚安装的openssl路径,更新一下即可:
$ ldd ./aesccm
linux-vdso.so.1 (0x00007fff1d792000)
libcrypto.so.3 => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9b0e9a8000)
/lib64/ld-linux-x86-64.so.2 (0x00007f9b0eba9000)
$ sudo updatedb
$ locate libcrypto.so.3
/home/starr/openssl-3.0.5/libcrypto.so.3
/usr/local/lib64/libcrypto.so.3
$ sudo vim /etc/ld.so.conf # 添加一行/usr/local/lib64/
$ sudo ldconfig
$ ldd ./aesccm
linux-vdso.so.1 (0x00007fff88fa6000)
libcrypto.so.3 => /usr/local/lib64/libcrypto.so.3 (0x00007f15ced6b000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f15ceb79000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f15ceb73000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f15ceb50000)
/lib64/ld-linux-x86-64.so.2 (0x00007f15cf1f7000)
$ ./aesccm
AES CCM Encrypt:
...
参考资料
openssl/NOTES-WINDOWS.md at master · openssl/openssl · GitHub
openssl/INSTALL.md at master · openssl/openssl · GitHub
Use the Microsoft C++ toolset from the command line | Microsoft Learn