【问题标题】:RSA_private_decrypt causes memory leaks on WindowsRSA_private_decrypt 导致 Windows 上的内存泄漏
【发布时间】:2014-08-20 23:29:06
【问题描述】:

我可以使用 openssl 1.0.1h 使用 RSA 加密和解密消息,并使用 Visual Studio C++ 2012 在 Windows 7 x64 上创建公共和私有 RSA-2048 位密钥。我试图检查使用(无论出于何种原因)损坏和/或篡改消息的解密函数(RSA_private_decrypt)并注意到我得到内存泄漏。为了测试这一点,我尝试了以下代码来解密一个空的内存缓冲区:

RSA *       rsa = NULL;
BYTE        source[256];
BYTE        destin[256];
int         iret;

memset(source, 0, 256);
memset(destin, 0, 256);

//  function to set the private and public keys (verified to work with valid data)
iret = SetRSAKey(rsa, ENCRYPTION_KEY_SERVER, ENCRYPTION_KEY_CLIENT);

int length = RSA_size(rsa);

iret = RSA_private_decrypt(length, source, destin, rsa, RSA_PKCS1_OAEP_PADDING);

RSA_free(rsa);

RAND_cleanup ();
EVP_cleanup ();
CRYPTO_cleanup_all_ex_data();

Visual Studio 的 Visual Leak Detector 在退出后报告 4 次内存泄漏:

WARNING: Visual Leak Detector detected memory leaks!
---------- Block 2211 at 0x005037A8: 12 bytes ----------
  Call Stack:
  Data:
    18 5F 51 00    00 00 00 00    E0 15 01 00                    ._Q..... ........

---------- Block 2210 at 0x005135A8: 64 bytes ----------
  Call Stack:
  Data:
    A8 37 50 00    00 00 00 00    00 00 00 00    00 00 00 00     .7P..... ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........

---------- Block 2209 at 0x005160E8: 96 bytes ----------
  Call Stack:
  Data:
    A8 35 51 00    40 BC 30 01    80 BC 30 01    08 00 00 00     .5Q.@.0. ..0.....
    10 00 00 00    00 00 00 00    08 00 00 00    00 02 00 00     ........ ........
    00 01 00 00    01 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    03 00 00 00    02 00 00 00     ........ ........
    01 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    02 00 00 00    00 00 00 00    02 00 00 00    00 00 00 00     ........ ........

---------- Block 2208 at 0x00515F18: 400 bytes ----------
  Call Stack:
  Data:
    00 00 00 00    60 15 00 00    CD CD CD CD    00 00 00 00     ....`... ........
    00 00 00 00    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    79 A0 07 04     ........ ....y...
    72 50 06 04    CD CD CD CD    CD CD CD CD    CD CD CD CD     rP...... ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    00 00 00 00    00 00 00 00     ........ ........
    00 00 00 00    00 00 00 00    CD CD CD CD    D0 FB 3E 01     ........ ......>.
    FC A5 3D 01    CD CD CD CD    CD CD CD CD    CD CD CD CD     ..=..... ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    B5 00 00 00     ........ ........
    68 02 00 00    CD CD CD CD    CD CD CD CD    CD CD CD CD     h....... ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    CD CD CD CD    CD CD CD CD     ........ ........
    CD CD CD CD    CD CD CD CD    02 00 00 00    00 00 00 00     ........ ........

Visual Leak Detector detected 4 memory leaks.
Visual Leak Detector is now exiting.

如果我使用空缓冲区的工作消息(使用 RSA_public_encrypt 加密),则不会发生内存泄漏,并且消息正在按预期解密。但是,当消息以某种方式损坏时,如何摆脱 openssl 中的内存泄漏?

在我尝试解密之前是否有一个功能可以测试消息的完整性,还是我必须创建一个 CRC 并自己检查?

【问题讨论】:

  • ENGINE_cleanup()CONF_modules_unload(1)EVP_cleanup()CRYPTO_cleanup_all_ex_data()ERR_remove_state(0)ERR_free_strings()。您实际上需要为程序中的每个线程调用ERR_remove_state。由于 OpenSSL 开发人员不认为这是一个问题,因此您无法摆脱一些泄漏。不用担心在 Java 中通过 JNI 和 C# 通过 P/Invoke 进行加载和卸载时累积的内存泄漏。
  • 感谢您的信息。 “ERR_remove_state(0)”,或者更准确地说是“ERR_remove_thread_state(NULL);”由于“ERR_remove_state”已被弃用,似乎已经做到了。如果您可以将您的评论发布到答案中,那么我会接受它。

标签: c visual-studio-2012 memory-leaks openssl


【解决方案1】:

我实际上在使用 OpenSSL RSA_verify() 时遇到了同样的内存泄漏问题。泄漏实际上仅在验证失败时发生。 ERR_remove_state(0) 似乎解决了这个问题(来自@jww 的上述评论)。

  ---------- Block 12440 at 0x00000000CD235350: 536 bytes ----------
      Leak Hash: 0x3AD573C8, Count: 1, Total 536 bytes
      Call Stack (TID 13324):
        0x00000000F8841E70 (File and line number not available): MSVCR120D.dll!malloc
        d:\projects\xy_dev\engine\ext\openssl\openssl-1.0.1j\crypto\mem.c (79): ***.exe!default_malloc_ex + 0x27 bytes
        d:\projects\xy_dev\engine\ext\openssl\openssl-1.0.1j\crypto\mem.c (308): ***.exe!CRYPTO_malloc + 0x18 bytes
        d:\projects\xy_dev\engine\ext\openssl\openssl-1.0.1j\crypto\err\err.c (1019): ***.exe!ERR_get_state + 0x17 bytes
        d:\projects\xy_dev\engine\ext\openssl\openssl-1.0.1j\crypto\err\err.c (730): ***.exe!ERR_put_error + 0x5 bytes
        d:\projects\xy_dev\engine\ext\openssl\openssl-1.0.1j\crypto\rsa\rsa_sign.c (312): ***.exe!int_rsa_verify
        d:\projects\xy_dev\engine\ext\openssl\openssl-1.0.1j\crypto\rsa\rsa_sign.c (337): ***.exe!RSA_verify

【讨论】:

    猜你喜欢
    • 2016-10-26
    • 2015-07-06
    • 2014-06-07
    • 2013-11-20
    • 2011-10-28
    • 2016-01-18
    • 2012-12-13
    • 1970-01-01
    • 2011-01-08
    相关资源
    最近更新 更多