如何在安全(C++)中存储加密密钥?

How to store encryption key in safe (C++)?

我想在我的游戏中使用 xxtea 作为数据 encryption/decryption。

这里是库的使用示例:

#include <stdio.h>
#include <string.h>
#include <xxtea.h>

int main() {
    const char *text = "Hello World! 你好,中国!";
    const char *key = "1234567890";
    size_t len;
    unsigned char *encrypt_data = xxtea_encrypt(text, strlen(text), key, &len);
    char *decrypt_data = xxtea_decrypt(encrypt_data, len, key, &len);
    if (strncmp(text, decrypt_data, len) == 0) {
        printf("success!\n");
    }
    else {
        printf("fail!\n");
    }
    free(encrypt_data);
    free(decrypt_data);
    return 0;
}

那如何保证钥匙本身的安全?

这并不容易。前段时间我也给过类似的回答。如果您的情况允许,您可以使用用户将输入的密码 加密密钥并将加密的密钥存储在某处。

然后当你需要密钥的时候,你可以输入密码解密并使用密钥。

这样,当您的密钥以加密形式保存时,您不必担心有人会知道它是什么。

做不到。在大多数情况下,您可以做的是破坏您的密钥、打断单词、拆分、混合、位移位、异或等……以使其更难。但是没有什么能阻止一个非常积极的黑客对您的代码进行逆向工程并获得密钥。

针对这种情况的最佳解决方案称为白盒密码术: https://en.wikipedia.org/wiki/Obfuscation#White_box_cryptography

这个想法是为您的加密生成一个个性化的二进制代码,用 whitebox_decrypt(cypher) 替换您的函数 decrypt(cypher, key) 两者都返回相同的结果。第二个函数 whitebox_decrypt 不包含密钥本身,而是包含与原始解密函数相同结果的个性化算法。再说一次:它可以像所有东西一样进行逆向工程,但它太难了,真的没有人愿意这样做。

然而,这通常是非常昂贵的东西。我不知道免费有什么好东西。它非常适用于保护 DRM 内容。

加密密钥是一个秘密(这是一个技术术语,描述只有应该知道的人才知道的东西)。

将秘密存储在程序中与将其写在一张纸上然后传真给世界上的每个人是一样的。

即这已经不是秘密了。

密钥保密的方法是要求用户输入它,然后在执行解密后删除它的所有痕迹。

正如@ArtjomB 指出的那样,您可以通过不将密钥放入您的程序来保证密钥的安全。在启动期间,授权用户或安全设备将需要提供密钥。

任何看起来不像的东西都不再是加密或安全,而是某种形式的混淆。混淆(或 "DRM")可能介于无用和有点有效之间,具体取决于您将投入多少精力与破解它的兴趣。随着新攻击的出现,您用于改进这一点的持续预算是多少?您预期的攻击者的复杂程度如何?

Apple(举个例子)非常严格地控制着他们的硬件、固件和 OS,并且拥有一个完全致力于不断改进的团队。 iPhone 通常在新版本发布后的几周到几个月内越狱。你应该考虑一个有吸引力的目标的最佳情况。

如果您正在考虑 "well, what can I put together in an afternoon that will stop the ankle biters?",请随心所欲。 XOR 它与其他一些硬编码值。也许将它移位或其他什么。它不会对任何关心的人有太大帮助,但它会阻止最随意的攻击者,至少你不会在它上面浪费大量时间和金钱。

在此基础上,查看您平台的内置解决方案。 OS 帮助很大。特别是,请查看 SLP Services on Windows. Mac provides licensing enforcement if you work through Mac App Store. Or you can look at commercial vendors like eSellerate who have their own proprietary solutions. SafeNet has several products。当然,所有这些都可以(并且经常)被击败。但它们比你几天后开发的任何东西都要强大。

根据定义,您从 Whosebug 获得的任何特定方法都是无用的。唯一的混淆是它的细节是秘密的。如果你知道它是如何工作的,那么你就可以打败它。这就是它与加密的区别。好的加密被设计成即使攻击者知道整个算法也同样强大。这就是为什么混淆技术是专有的。他们几乎必须是。这意味着你要么 (a) 快速构建一个糟糕的,(b) 花费大量时间和金钱构建一个稍微不那么糟糕的,或者 (c) 花费更多的钱来获得一个有点——来自专门从事这些事情的供应商的还过得去。

(如果你在 Whosebug 上问这个问题,你绝对不可能自己构建一个好的程序。如果你自己没有破解过一些程序,你就没有位置建立一些东西来阻止别人。)

最好的混淆是在运行时计算密钥。例如。您可以在 "Press any key..." 或 "Error loading file" 等系统字符串上计算 SHA1 或 MD5。然后使用散列作为 XXTEA 密钥。