C# 在C语言中保护加密密钥#

C# 在C语言中保护加密密钥#,c#,vb.net,encryption,cryptography,C#,Vb.net,Encryption,Cryptography,我知道在.NET框架中有许多加密提供程序,以及如何使用它们的基本知识。这很简单 但我关心的是这一点 假设我想使用这些库对XML序列化对象进行加密,以防止篡改以及任何人查看这些文件内容的能力 我经常遇到的问题是,解密这些数据的密钥需要作为常量存储在应用程序中的某个位置。基本上使整个练习毫无意义 那么,如何在可分解的应用程序中安全地存储加密算法的密钥呢 编辑:如果我正确理解下面的两个答案。这意味着本质上任何实现(为了安全)都要求它是只读的或写的,但决不能两者都是?这是否正确?有多种可能的解决方案。其

我知道在.NET框架中有许多加密提供程序,以及如何使用它们的基本知识。这很简单

但我关心的是这一点

假设我想使用这些库对XML序列化对象进行加密,以防止篡改以及任何人查看这些文件内容的能力

我经常遇到的问题是,解密这些数据的密钥需要作为常量存储在应用程序中的某个位置。基本上使整个练习毫无意义

那么,如何在可分解的应用程序中安全地存储加密算法的密钥呢


编辑:如果我正确理解下面的两个答案。这意味着本质上任何实现(为了安全)都要求它是只读的或写的,但决不能两者都是?这是否正确?

有多种可能的解决方案。其中一个正在使用。或者,您可以使用中使用的相同方法


一个好方法是生成一对公钥和私钥。使用私有密钥加密并销毁密钥。使用公钥,您可以解密但不能篡改数据。

我们假设您使用的是某种公钥加密方案,否则它将毫无意义

答案是不要将私钥存储在应用程序中的任何位置。将其存储在只有应用程序才能访问的位置。例如,本地系统中只有管理员和应用程序才有权读取的文件。在受保护的网络共享上。等等


考虑一下我们作为人是如何管理密钥的。我们把我们的私人文件保存在一个文件里,或者一个加密的USB驱动器或者类似的东西。同样的原则也适用于应用程序。

您没有。如果应用程序可以访问该密钥,那么它只是一种模糊的安全性。最好以某种方式对用户进行身份验证(密码是最简单的示例),以确保允许用户访问数据。您不能让应用程序为您这样做,因为它根本不可信。任何人都可以获得存储在应用程序中的信息

如果密钥信息存储在其他地方,恶意用户或应用程序也可能访问它。如果没有,则直接将数据存储到神奇的安全位置


现在,如果您仍然希望沿着这条路走下去,在不进行身份验证的情况下存储敏感数据,那么最好的选择——或者至少是一种简单的、安全性有一半的方法——可能是DPAPI(请参阅中的类)。它将使用机器密钥或用户帐户密钥加密数据(您可以选择)。因此,运行在另一台计算机上或使用另一个用户帐户的程序无法访问它。Windows将尝试保护这些密钥,但实际上,在适当的计算机上或使用适当的用户帐户运行的任何应用程序都可以访问您的数据。

如果您销毁私钥,这是一种只读解决方案。然而,即使这样,恶意用户也可以使用自己的密钥对创建一个新文件,并替换应用程序用于解密的密钥。这当然取决于他修改公钥存储位置的能力。这不就是解决问题吗?如果您确实有一个只有您的应用程序才能访问的受信任位置,那么您可以将数据存储在该位置并对其进行处理。没有“只有管理员和您的应用程序才能访问”这样的位置。如果你的应用程序可以访问它,你的应用程序的用户也可以。可能使用用户的密码进行加密和解密是一个好主意。但这当然会暴露密码。密码的散列可能可以完成这项工作,或者其他一些密码派生值。如果您使用自定义形式的身份验证和加密,您可能是对的。如果您使用的是DPAPI,它将自动处理所有这些内容。据我记忆所及,它还将注意在用户更改密码后数据仍然可以被解密。这也会产生它自己的问题。如果用户想更改密码怎么办?DPAPI会处理的。请参阅:(下面最后一段“DPAPI中的密钥和密码”)。如果您使用密码进行自己的身份验证,则最好对实际文件使用随机密钥,并使用用户密码(散列)对其进行加密存储。如果用户更改密码,您只需重新加密随机密钥。尽可能模糊XML(添加随机数据+使用ROT13原始加密方案+等),并将其序列化为二进制模式或Base64模式。重点是通过程序反汇编使XML解码尽可能困难,以确保用户不必为此花费时间。。。