使用 OpenSSL 时一定要注意不同版本之间的差异

        OpenSSL 常见的一些版本及受支持情况如下表所示:

OpenSSL版本 官方支持情况
0.9.8 系列 不再支持
1.0.0 系列 不再支持
1.0.1 系列 不再支持
1.0.2 系列 将被支持到 2019 年 12 月 31 日
1.1.0 系列 只做安全修复,到 2019 年 9 月 11 日停止支持
1.1.1 系列 将被支持到 2023 年 9 月 11 日

        曾经使用过 1.0.1c,1.0.2d,1.0.2k,1.1.1-pre6,1.1.1,1.1.1c 共 6 个版本,个人的简单体会如下:
1) 1.0.1 与 1.0.2 这两个系列之间变化相对较小,大部分函数接口可通用;
2) 1.0.x 与 1.1.1 这两个系列之间变化比较大,很多在 1.0.x 系列中提供的函数接口到 1.1.1 系列中已被删去或被转变为内部接口,不再对外提供;
3) 截至 2019 年 5月,在 1.1.1 系列中包含 pre1 至 pre9 共 9 个预览版、1.1.1 正式版,1.1.1a 至 1.1.1c 三个延伸版,总共有 13 个版本。1.1.1 系列是从 2018 年 2 月开始发布的,其内容一直在做调整,预览版、正式版、延伸版之间有一定差异。

        下面举例说明一些不同版本之间的差异:

a)在 1.0.2d 版本中可以调用到一些与 ASN.1 编码有关的底层函数,例如:M_i2d_ASN1_OCTET_STRING( ),M_ASN1_BIT_STRING_free( ) 等。在 1.1.1 系列中,这些以 M_ 开头的 ASN.1 编码函数都被删去了。
b)在 1.1.1-pre6 版中,sm2.h 文件所在的路径是 include/openssl。在 1.1.1 版中,sm2.h 文件所在的目录是 include/internal 。
在 1.1.1-pre6 版的 sm2.h 中,SM2 签名和验签函数的声明如下:

int SM2_sign(int type, const unsigned char *dgst, int dgstlen,
             unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);

int SM2_verify(int type, const unsigned char *dgst, int dgstlen,
               const unsigned char *sig, int siglen, EC_KEY *eckey);

        SM2加密和解密函数定义如下:

int SM2_encrypt(const EC_KEY *key,
                const EVP_MD *digest,
                const uint8_t *msg,
                size_t msg_len,
                uint8_t *ciphertext_buf, size_t *ciphertext_len);

int SM2_decrypt(const EC_KEY *key,
                const EVP_MD *digest,
                const uint8_t *ciphertext,
                size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len);

        在 1.1.1 版的 sm2.h 中,SM2 签名和验签函数的声明如下:

int sm2_sign(const unsigned char *dgst, int dgstlen,
             unsigned char *sig, unsigned int *siglen, EC_KEY *eckey);

int sm2_verify(const unsigned char *dgst, int dgstlen,
               const unsigned char *sig, int siglen, EC_KEY *eckey);

        SM2加密和解密函数定义如下:

int sm2_encrypt(const EC_KEY *key,
                const EVP_MD *digest,
                const uint8_t *msg,
                size_t msg_len,
                uint8_t *ciphertext_buf, size_t *ciphertext_len);

int sm2_decrypt(const EC_KEY *key,
                const EVP_MD *digest,
                const uint8_t *ciphertext,
                size_t ciphertext_len, uint8_t *ptext_buf, size_t *ptext_len);

        通过对比可以看出:在 1.1.1 版的 SM2 签名和验签函数中,删掉了一个名为 type 的参数,函数名与 1.1.1-pre6 中的对应函数名在大小写拼写上有差别;1.1.1 版的 SM2 加密和解密函数,与 1.1.1-pre6 版中的对应函数相比,其函数名在大小写拼写上有差别。

        在 1.1.1 版与 1.1.1c 版之间也有差别,例如在 1.1.1 版 ecdh_kdf.c 中实现了一个名为 ECDH_KDF_X9_62( ) 的函数,在 1.1.1c 版 ecdh_kdf.c 中,新增了对一个名为 ecdh_KDF_X9_63( ) 函数的实现,对它的声明放在 internal/ec_int.h 中。ECDH_KDF_X9_62( ) 依然存在,但它的实现过程如下:

int ECDH_KDF_X9_62(unsigned char *out, size_t outlen,
                   const unsigned char *Z, size_t Zlen,
                   const unsigned char *sinfo, size_t sinfolen,
                   const EVP_MD *md)
{
    return ecdh_KDF_X9_63(out, outlen, Z, Zlen, sinfo, sinfolen, md);
}

        可以看出 ECDH_KDF_X9_62( ) 与 ecdh_KDF_X9_63( ) 这两个函数实现的功能是完全相同的,在 1.1.1c 版中将在以前版本里对函数 ECDH_KDF_X9_62( ) 的调用,都改为对新增函数 ecdh_KDF_X9_63( ) 的调用。

        我们在使用 OpenSSL 时,一定要留心不同版本之间的差异,这种差异可能给已有的应用程序带来不兼容的问题。在编程时应尽量选择近期发布的 OpenSSL 系列中的稳定版本。

你可能感兴趣的:(OpenSSL)