首页 > Note > 使用 openssl 进行 RSA 加解密

使用 openssl 进行 RSA 加解密

2019年1月18日 发表评论 阅读评论

在我之前的一篇博客中 RSA 公钥加密原理 中, 对 RSA 非对称加密原理做了简单的阐述。这篇博客主要聊如何使用 OPENSSL 进行密钥对的生成,以及非对称加解密。

一. 生成密钥对

在 OPENSSL 中, RSA 是一个很重要的结构体。它的定义在 rsa_locl.h 中,面包含了在原理中提到的所有重要的变量 随机质数 p, q, 公钥指数 e, 私钥指数 d, 以及模数 n

生成密钥函数:

  • bits 密钥的规模(modulus)。小于 1028 位的密钥是不安全的,小于 512 则会返回 0
  • e 公开的指数。它应该是一个奇数(odd number), 一般是 3, 1765537
  • cb 生成大随机数的回调函数。一般使用 NULL 即可, 默认为 BN_GENCB_call()

生成公私钥并写入文件的代码示例:

二. 公私钥加解密

公私钥加解密两个步骤, 一是载入密钥, 二是加解密。
载入密钥使用 API :

当载入失败时返回 NULL。

而加解密中两个重要的 API 是:

  • flen 是输入数据的长度,必须小于等于 modulus = RSA_size(rsa) 个字节, 且和参数 padding 相关。当 flen 不满足要求时,将会出现 "data too small for key size""data too large for key size" 错误。 flen 与 padding 的对应关系如下:
    • RSA_PKCS1_PADDING , flen <= modulus - 11
    • RSA_SSLV23_PADDING , flen <= modulus - 11
    • RSA_NO_PADDING , flen = modulus
    • RSA_PKCS1_OAEP_PADDING , flen <= modulus - 41 (2 倍的 SHA1 长度 + 1)
  • padding 是填充模式,当 flen 满足上述关系时,将会进行填充:
    • RSA_PKCS1_PADDING , 最常用的模式,使用 PKCS #1 v1.5 标准,前两字节填充 0x00, 0x02,接着的 modulus - flen - 3 字节使用 随机非 '\0' 值填充,接着填充一个字节的 0x00, 然后是 from 数据
    • RSA_SSLV23_PADDING , 前两个字节填充 0x00,0x02 , 接着的 modulus - flen - 3 - 8 字节填充 随机非 '\0' 值,然后填充 8 个 0x03, 接着填充一个字节的 0x00 ,然后是 from 数据
    • RSA_NO_PADDING , 不需要填充
    • RSA_PKCS1_OAEP_PADDING , 前20字节使用 SHA1 填充, 接着填充至少 20 字节的 0x00, 最后填充 0x01,接着是 from 数据

如图所示:

公私钥加解密示例:

三. Tips

多半是因为代码运行库不匹配导致的。在Windows 中,运行时库有这几种:

  • Single Threaded /ML - MS VC++ often defaults to this for the release version of a new project.
  • Debug Single Threaded /MLd - MS VC++ often defaults to this for the debug version of a new project.
  • Multithreaded/MT
  • Debug Multithreaded /MTd
  • Multithreaded DLL /MD - OpenSSL defaults to this.
  • Debug Multithreaded DLL /MDd

运行库不一致可能导致程序崩溃(通常是在进行IO操作时)。这种情况下可以重新编译 OPENSSL, 或者修改程序的运行库。更简单的办法,可以尝试添加一个文件引用:

 

 

 

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.