如何在 .Net 中安全地存储加密密钥?
如果您有 .Net 应用程序(或任何其他相关应用程序),如何安全地存储内部加密密钥?我不是在谈论用户输入的密钥,而是在程序本身中硬编码的密钥,用于在程序的其他实例之间进行通信。例如,如果您有一个点对点类型的程序,您可能需要对数据包进行加密,以便确定您正在与您的程序的另一个实例而不是其他人的程序进行通信。我的解决方案是将密钥硬编码到客户端中,并以这种方式简单地加密/解密所有内容。
然而,我想知道在 .Net 中这样做是否安全。我没有广泛使用 Reflector 或类似的东西,但据我所知,从 CIL 解构 .Net 应用程序听起来相当容易。对于拥有这些应用程序之一的人来说,去寻找我的神奇数字会很简单吗?
If you have a .Net application (or any other application for that matter,) how do you safely store internal encryption keys? I'm not talking about user-entered keys, but keys that are hard-coded in the program itself, for talking between other instances of the program. For example, if you have a peer to peer type program, you may want to encrypt the packets so you're sure you're talking to another instance of your program, and not someone else's. My solution would be to hard-code a key into the clients, and simply encrypt/decrypt everything that way.
I'm wondering, however, if this is safe to do in .Net. I haven't worked extensively with Reflector or anything of the sort, but from what I hear, it sounds fairly easy to deconstruct .Net applications from CIL. Would going and finding my magic number be trivial for someone with one of these applications?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
绝对无法验证连接另一端的可执行文件是否是您编写的可执行文件。如果用一个密钥加密一个密钥,那么第二个密钥存储在哪里?如果您使用服务器的 Diffie-Hellman 来获取密钥,那么您将该密钥存储在哪里? (提示:在内存中,可以从中转储然后读取)。这是一个永远无法解决的递归问题。
我读到,AOL Instant Messenger 的服务器会定期轮询 AIM 客户端,以获取代码特定地址的哈希值(即计算 SHA1(address1 -> address2)),如果哈希值不正确,则断开客户端连接。这是因为重新分发可执行文件是非法的(并且在每两个间隔之间建立哈希表是不可行的),因此这只是一个法律挑战,而不是技术挑战。
如果您想要真正努力击败逆向工程(并且实际上做得很好)的软件,请尝试将调试器附加到 Skype :-)
There is absolutely no way to verify that the executable on the other end of the connection is the one you wrote. If you encrypt a key with a key, where do you store the second key? If you Diffie-Hellman that with the server's to get a secret key, where do you store that key? (hint: in memory, where it can be dumped from then read). It's a recursive problem that you can never solve.
I've read that AOL Instant Messenger's servers would periodically poll the AIM client for the hash of specific addresses of code (i.e. calculate SHA1(address1 -> address2)) and then disconnect the client if the hash was not correct. This was because it is illegal to redistribute the executable (and unfeasible to build a table of the hash between every two intervals), so this is merely a legal challenge and not a technical one.
If you want software that really tries hard to defeat reverse engineering (and actually does a good job), try attaching a debugger to Skype :-)
您还可以尝试将自定义加密/解密算法放入 C++ 库中,然后使用互操作来来回编组数据。
You can also try putting in your custom encryption/decryption algorithm into a C++ library, then use interop to marshal the data back and forth.
您可以生成非对称密钥(每个会话?),而不是对密钥进行硬编码。您可以将公钥发送给对等方,使用此密钥,对等方可以加密只有您可以解密的消息。
非对称加密速度很慢,您的对等方也可以发送用您的公钥编码的对称密钥,该密钥仅用于此会话。
如果确实需要存储机密数据,可以使用 ProtectedData 类。您可以在设置过程中调用它来存储您的秘密(密钥)。
Instead of hardcoding a key, you could generate an asymmetric key (per session?). You can send the public key to a peer, with this key, the peer can encrypt a message that only you can decrypt.
Asymmetric encryption is slow, you the peer could also send a symmetric key encoded with your public key, that is used for this session only.
If you really need to store secret data, you can use the ProtectedData class. You could call it during setup, to store your secret (key).
如果密钥存储在程序的可执行代码中,或存储在资源中(或在 Windows TCB 中使用可执行代码中的密钥),那么有人可以通过足够的努力对其进行解码。
因为最终有了可执行文件,它们就拥有了获得您添加的任何保护所需的所有信息(因为解码代码也已就位)。
首先:
KISS 原则将对您大有裨益。
If the key is stored in your program's executable code, or in a resource (or in Windows TCB using a key in the executable code) someone could, with enough effort, decoded it.
Because in the end with the executable they have all the information needed to get it whatever protection you add (since the decoding code is in place as well).
To start with:
The KISS principle will serve you well.