哪个存储类可以防止私钥的逆向工程?

Posted

技术标签:

【中文标题】哪个存储类可以防止私钥的逆向工程?【英文标题】:Which storage-class to prevent reverse-engineering of private key? 【发布时间】:2014-04-07 06:29:10 【问题描述】:

我有一个使用私钥的 C 函数,并希望防止任何人读出此密钥。 不仅来自二进制文件 - 还来自源存储库。密钥不是明文形式,但仍应尽可能难以访问它。 我的计划是将这个 c 文件编译为一个目标文件,并将这个目标文件(带有混淆的 privateKey 数组)放入源存储库。但我不确定我应该将密钥放在哪个存储类/范围中(本地堆栈变量、静态变量 - 本地/全局...)。

1.) 全局静态

static unsigned char const privateKey[] = 
  0x44, 0x8e, 0x54, 0xae, 0x64, 0x74, 0xbe, ...
;
void myFunction()
  //do something with privateKey

2.) 局部堆栈变量

void myFunction()
  unsigned char const privateKey[] = 
    0x44, 0x8e, 0x54, 0xae, 0x64, 0x74, 0xbe, ...
  ;
  //do something with privateKey

3.) 局部静态

void myFunction()
  static unsigned char const privateKey[] = 
    0x44, 0x8e, 0x54, 0xae, 0x64, 0x74, 0xbe, ...
  ;
  //do something with privateKey

我刚刚用 nm 查看了这 3 个解决方案的目标文件 - 在第二个解决方案中,我什至没有看到键的符号(但我担心使用调试器很容易读取键,因为它是在运行时放置在堆栈上)。解决方案 3 在 nm 中看起来像:

00000000 T myFunction
00000200 t __6_privateKey.2

和解决方案 1 类似:

00000000 T myFunction
00000200 t privateKey

在哪里放置密钥最安全的存储类 - 或者在安全性方面根本没有区别?还有其他更安全的解决方案吗?

【问题讨论】:

没有安全存储类这样的东西,除非你用用户指定的密码保护它。然后它会有点安全。查看 PKSC12 (en.wikipedia.org/wiki/PKCS12) 了解一些信息。 您不必调用变量privateKey。你可以让它像 x 一样晦涩难懂。为了使代码可读,#define privateKey x。所以代码可以使用privateKey,但内部链接器变量是x。 【参考方案1】:

无论你把它放在哪里,它都会作为一些常量数组存储在可执行文件中,如果你使用动态存储类(例如:local var),它将被复制。我认为使用任何这种技巧都不会改变密钥的安全性。

一个一般性建议:如果您想重新发明一些密码轮。不要这样做。 非常可能会失败。许多著名的尝试在你之前都失败了(WIFI 安全、DVD 加密......)

【讨论】:

尤其是任何有权访问 repo 的人都可以构建一个简单的程序以同样的方式链接到目标文件。您唯一的选择是使用未存储在存储库中的密钥材料加密密钥,或者将密钥存储在存储库之外。【参考方案2】:

如果您用户的计算机可以执行代码并访问数据,那么控制计算机的用户也可以。没有所谓的“只有程序才能看到的东西”。

虽然有一些尝试制作“防篡改软件”,例如 TPM,但我认为这不会解决您的问题(这基本上需要用户合作并承诺在您执行时不会查看) .您需要更改更高级别的策略以更改您的要求。

【讨论】:

【参考方案3】:

其他答案是正确的。您无法向需要使用它的用户隐藏密钥。

您可以做的最好的事情是将密钥放在物理上不同的计算机上,然后使用网络(互联网/局域网)传递密钥。当然,这会增加更多问题,因为您需要对用户进行身份验证,并保护传输中的密钥。

这是一个广泛的专业领域,称为Key Management。

我在此处给出的答案中概述了一种解决方案:How to properly do private key management

【讨论】:

以上是关于哪个存储类可以防止私钥的逆向工程?的主要内容,如果未能解决你的问题,请参考以下文章

WinRT 存储 RSA 私钥的位置

安卓逆向 -- 算法基础(数字签名)

是否可以在远程 Windows 服务器上确定证书私钥的文件名?

RSA 私钥的 PKCS#1 和 PKCS#8 格式 [关闭]

RSA的公钥和私钥到底哪个才是用来加密和哪个用来解密

如何获取 PCCERT_CONTEXT 的私钥的 NCRYPT_KEY_HANDLE?