使用openssl进行PKI开发:从安装到实践

需积分: 10 3 下载量 69 浏览量 更新于2024-07-22 收藏 409KB PDF 举报
"openssl代码实例——基于openssl1.0.0e的PKI开发指南" 本文档主要围绕openssl库,一个广泛应用于密码学和信息安全领域的开源软件,提供了一系列代码实例,旨在帮助C程序员快速掌握基于openssl的PKI(Public Key Infrastructure,公钥基础设施)开发技能。openssl库包含了丰富的密码学算法,如RSA、AES等,以及X.509证书处理、SSL/TLS协议等功能,是理解和实践密码学技术的重要工具。 在开始学习之前,确保已具备基本的C编程知识和对Linux或Windows操作系统的基本操作。在Linux环境下,安装openssl的步骤如下: 1. 下载openssl源码包,例如openssl-1.0.0e.tar.gz。 2. 使用`tar`命令解压缩。 3. 进入解压后的目录,执行`./config`配置编译选项,包括安装路径、是否编译动态库以及启用特定加密算法,如camellia。 4. 接着运行`make depend`和`make install`来编译和安装openssl。 5. 最后,更新系统动态库配置,使系统能够找到新安装的openssl库。 在Windows环境下,使用Visual Studio进行openssl的编译和配置: 1. 解压openssl源码至C盘并重命名目录。 2. 运行Perl的`Configure`脚本,选择VC-WIN32编译目标。 3. 打开Visual Studio命令提示符,切换到openssl源码目录。 4. 使用`nmake -f ms/ntdll.mak`编译openssl,生成的库文件将位于特定目录下。 5. 在VS2010项目属性中配置包含目录,以便项目可以找到openssl的头文件。 通过这些实例,你可以学习到如何使用openssl库进行密钥对生成、数字签名、证书请求、证书签发、SSL连接等相关操作。这些知识对于进行安全通信、数据加密、身份验证等信息安全任务至关重要。同时,openssl库的代码实现了许多高级的加密技巧,阅读和理解这些代码将极大地提升你的编程能力,特别是在处理复杂的安全问题时。 此外,openssl还支持各种密码学算法,如RSA、DSA、ECC等非对称加密算法,以及AES、DES、Blowfish等对称加密算法,还有哈希函数如MD5、SHA系列。熟悉openssl API的使用,将使你在处理诸如数据加密、解密、消息认证码(MAC)计算、数字签名等任务时游刃有余。 在实际应用中,openssl还广泛用于HTTPS服务器、邮件安全、FTP安全连接等场景。通过深入学习openssl,你不仅可以掌握密码学基础,还能了解如何在实际项目中应用这些技术,为你的信息安全职业生涯打下坚实的基础。
2018-07-11 上传
0、此例程调试环境 运行uname -a的结果如下: Linux freescale 3.0.35-2666-gbdde708-g6f31253 #1 SMP PREEMPT Thu Nov 30 15:45:33 CST 2017 armv7l GNU/Linux 简称2017 armv7l GNU/Linux 1、openssl 直接处理AES的API 在openssl/aes.h定义。是基本的AES库函数接口,可以直接调用,但是那个接口是没有填充的。而如果要与Java通信,必须要有填充模式。所以看第2条。 2、利用openssl EVP接口 在openssl/evp.h中定义。在这个接口中提供的AES是默认是pkcs5padding方式填充方案。 3、注意openssl新老版本的区别 看如下这段 One of the primary differences between master (OpenSSL 1.1.0) and the 1.0.2 version is that many types have been made opaque, i.e. applications are no longer allowed to look inside the internals of the structures. The biggest impact on applications is that: 1)You cannot instantiate these structures directly on the stack. So instead of: EVP_CIPHER_CTX ctx; you must instead do: EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); .... EVP_CIPHER_CTX_free(ctx); 2)You must only use the provided accessor functions to access the internals of the structure. 4、注意加密的内容是数据不限制是否为字符串 openssl接口加密的是数据,不限制是否为字符串,我看到有些人在加密时使用strlen(),来获取要加密的长度,如果是对字符串加密的话没有问题,如果不是字符串的话,用它获取的长度是到第一个0处,因为这个函数获取的是字符串长度,字符串是以零为终止的。 5、在调用EVP_EncryptFinal_ex时不要画蛇添足 正常加解密处理过程,引用网友的代码如下,经测试正确。 int kk_encrypt(unsigned char *plaintext, int plaintext_len, unsigned char *key, unsigned char *iv, unsigned char *ciphertext) { EVP_CIPHER_CTX *ctx; int len; int ciphertext_len; ctx = EVP_CIPHER_CTX_new(); EVP_EncryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv); //EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv); EVP_EncryptUpdate(ctx, ciphertext, &len;, plaintext, plaintext_len); ciphertext_len = len; EVP_EncryptFinal_ex(ctx, ciphertext + len, &len;); ciphertext_len += len; EVP_CIPHER_CTX_free(ctx); return ciphertext_len; } int kk_decrypt(unsigned char *ciphertext, int ciphertext_len, unsigned char *key, unsigned char *iv, unsigned char *plaintext) { EVP_CIPHER_CTX *ctx; int len; int plaintext_len; ctx = EVP_CIPHER_CTX_new(); EVP_DecryptInit_ex(ctx, EVP_aes_128_cbc(), NULL, key, iv); //EVP_DecryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, key, iv); EVP_DecryptUpdate(ctx, plaintext, &len;, ciphertext, ciphertext_len); plaintext_len = len; EVP_DecryptFinal_ex(ctx, plaintext + len, &len;); plaintext_len += len; EVP_CIPHER_CTX_free(ctx); return plaintext_len; } 我看到有人提供的代码在加密长度正好是16字节的整数倍时特意不去调用EVP_EncryptFinal_ex,这实在是画蛇添足啊,不论什么情况下,最后一定要调用EVP_EncryptFinal_ex一次,然后结束加密过程。 6、Base64陷阱 如果用到了base64,要注意如下: 1)base64算法是将3个字节变成4个可显示字符。所以在如果数据长度不是3字节对齐时,会补0凑齐。 2)在解密时先要解base64,再解AES。在解base64后,要减掉补上的0。算法就去查看base64后的字符串尾处有几个=号,最多是2个,如果正好要加密的数据是3的倍数,不需要补0,那么base64后的数据尾处就没有=,如果补了1个0,就有一个=号。 算法如下: int encode_str_size = EVP_EncodeBlock(base64, en, el); int length = EVP_DecodeBlock(base64_out, base64, encode_str_size ); //EVP_DecodeBlock内部同样调用EVP_DecodeInit + EVP_DecodeUpdate + Evp_DecodeFinal实现,但是并未处理尾部的'='字符,因此结果字符串长度总是为3的倍数 while(base64[--encode_str_size] == '=') length--; 算法网友提供,测试正确。