为 openssl EVP_PKEY 私钥清理内存的 C 代码
Posted
技术标签:
【中文标题】为 openssl EVP_PKEY 私钥清理内存的 C 代码【英文标题】:C code to clean up memory for openssl EVP_PKEY private keys 【发布时间】:2017-03-18 00:04:35 【问题描述】:我开始学习 C/C++ 中的 OpenSSL 编程。我遇到的一个问题是,我怎样才能安全地清除私钥的内存?
例如,我可能有代码:
EVP_PKEY *private_key = PEM_read_bio_PrivateKey( bio, ,,,)
RSA *r = EVP_PKEY_get1_RSA( private_key);
我想在使用 EVP_PKEY_free() 释放它之前彻底清除内存中的 private_key。
非常感谢您的帮助和/或您的建议。 谢谢。
【问题讨论】:
memset(...)
会为你工作吗?
安全清除记忆是一个复杂的课题。这取决于实现如何实现这一点。请注意,不仅是擦除密钥。如果您想阻止其他进程,例如,读取它们并存储已经是一个问题。读取内存。
【参考方案1】:
EVP_PKEY *private_key = PEM_read_bio_PrivateKey( bio, ,,,)
我想在使用
EVP_PKEY_free
释放它之前从内存中彻底清除 private_key。
OpenSSL 的EVP_PKEY_free
会为您擦除私钥。你不必做任何特别的事情。
RSA *r = EVP_PKEY_get1_RSA( private_key);
get1
表示引用计数已增加,您有效地获得了自己的对象副本。 get0
表示您有一个指向现有对象的指针,您应该不在其上调用free
。由于get1
,您必须调用RSA_free
以确保它被删除。与EVP_PKEY_free
一样,RSA_free
将擦除密钥。
请不要拨打memset
。这些是不透明的结构,您必须遵循许多指针才能正确清除子对象。 OpenSSL 1.1.0 中隐藏了更多的字段,因此(如果您愿意的话)将更加难以遵循指针。另见Error: “invalid use of incomplete type ‘RSA aka struct rsa_st” in OpenSSL 1.1.0、Visual Studio and error C2027: use of undefined type 'rsa_st' in OpenSSL 1.1.0、EVP_get_cipherbyname and “undefined struct/union evp_cipher_st” in OpenSSL 1.1.0等
以下是您可能感兴趣的一些额外阅读:
Why does OPENSSL_cleanse look so complex and thread-unsafe? Removing OPENSSL_cleanse from OpenSSL-1.0.1r当调用EVP_PKEY_free
和RSA_free
之类的函数时,它们最终会在内存返回给操作系统之前以调用OPENSSL_cleanse
结束。对于 RSA 私钥,它至少调用 8 次以擦除与 n
、e
、d
、p
、q
、dp
、dq
关联的字节数组,和invq
。
【讨论】:
jww,非常感谢。我检查了我正在使用的 openssl 1.0.1u 的源代码。我没有看到从 EVP_PKEY_free() 调用的任何 OPENSSL_cleanse() 调用。但我确实看到很多从 RSA_free() 调用的 OPENSSL_cleanse()。由于 rsa 密钥只是来自 EVP_PKEY 结构内存区域的引用,我可以安全地假设当我执行 RSA_free() 时,它会擦除 rsa 密钥,因此它还清理了 EVP_PKEY 结构的内存?EVP_PKEY_free()
最终调用EVP_PKEY_free_it()
,它使用EVP_PKEY
结构的ameth
指针调用负责清理特定密钥类型的私钥数据的函数... 抽象,抽象无处不在!以上是关于为 openssl EVP_PKEY 私钥清理内存的 C 代码的主要内容,如果未能解决你的问题,请参考以下文章
php的openssl_sign($data,$sign,$private_key)这个函数的源码是啥?
使用 OpenSSL 和公钥 ssh-keygen 为 SSH 生成私钥