.net 如何保护代码中的敏感数据?

zc0qhyus  于 2023-04-22  发布在  .NET
关注(0)|答案(8)|浏览(270)

我正在研究保护我的代码不被反编译的方法。
这里有几个很好的线程描述了混淆和代码打包作为保护代码的可能方法。然而,它们都不是理想的,当使用字符串方法/属性名称时,混淆不适用于反射。许多人根本不推荐使用混淆。
因此,我目前决定不使用上述任何一种方法。* 然而 *,我有部分代码需要加密,例如,带有IP的数据库连接字符串,登录名和密码存储在代码中,作为简单的const string,与电子邮件帐户数据相同。
在ASP.NET中,有一个选项可以将敏感数据移动到.config文件中并对其进行加密,但这需要服务器密钥,即链接到一台计算机。我没有读到太多关于它的内容,但我想桌面应用程序也有类似的功能。但我需要在安装应用程序的任何计算机上工作。
是否有方法对这些数据进行编码/保护,使其无法与反编译代码沿着读取?

noj0wjuj

noj0wjuj1#

第一个建议是不要直接在代码中存储任何敏感的东西。无论你多么巧妙地试图混淆它,你都可以对它进行逆向工程。
我读过一些东西,比如将密码分成几部分,将它们放在代码中的不同位置,并在最终使用它们之前通过一系列函数运行它们......尽管这会使事情变得更加困难,但您仍然可以始终使用调试器监视应用程序,最终您将能够检索秘密信息。
如果我正确地解释了您的场景,那么您所拥有的是要部署在某个客户端的代码,并且您的代码连接到数据库(我想这也是在客户端的监督下),连接到它需要一个密码。这个密码是客户端知道的,所以试图对客户端隐藏它是相当无用的。你 * 做 * 想要的是限制访问该密码的任何人谁不应该知道它。
您通常通过将敏感信息放在一个单独的文件夹中来实现这一点,该文件夹应具有非常严格的权限,只有应用程序和少数选定的人员应具有访问权限。然后,应用程序将在运行时需要时访问这些信息。
此外,加密单独的文件也是一个问题-如果你这样做,那么涉及到的密钥也必须以某种方式保护-无限递归正在进行:)保护对文件的访问通常就足够了,但如果你真的需要尽可能安全,那么一个解决方案是对文件使用基于密码的加密。但这里的想法不是将密码存储在系统的另一个位置,而是作为带外信息(例如在物理保险库中)并在启动应用程序时输入密码。这也有它的问题:启动应用程序需要一个人的物理存在,并且您仍然可以从运行应用程序的机器的RAM中检索密码。但这可能是您在没有专用硬件的情况下所能做的最好的事情。
基于密码的加密的另一个很好的替代方案是依赖于操作系统特定的“密码库”,如Windows的Isolated Storage,这是一种在根本不加密和保持密码带外之间的权衡。

pxq42qpu

pxq42qpu2#

这不是一个加密的答案,但一种“安全”的方法是通过Web服务进行所有数据库调用。然后,您的连接凭据将存储在安全服务器上,客户端将通过那里传递所有调用。
你的可再发行版里没有任何敏感信息...

2jcobegt

2jcobegt3#

我过去曾努力解决这个问题,并提出了三种处理这个问题的方法,但我不确定其中任何一种都是完美的:
1.加密或混淆值,并希望得到最好的结果。当然,加密只是额外的混淆级别,因为密钥必须与其余部分一起交付。
1.通过使用单向加密来消除对密钥本身的需要。使用私钥生成公钥。这可用于许可或密码验证。您可以使用私钥生成许可证,但公钥可用于验证它们。或者使用私钥生成密码,该密码可以使用公钥进行验证,但不能被逆转。
1.创建您自己的系统特定的密钥生成机制,类似于ASP.NET使用的机制。您可以通过为每个安装或站点生成唯一的密钥来限制某些人在步骤1中反转加密/模糊处理的影响。

jtjikinw

jtjikinw4#

有很多方法,但现实是,如果你真的想保护你的代码,唯一的解决方案是使用“专业”产品:-)不要试图重新发明轮子。这些产品通常有加密字符串的选项。真正的问题是另一个:如果没有专业的产品(甚至有专业的产品),Maven可以简单地设置一个断点,然后查看传递给库方法的参数(例如打开连接的参数)。现在...如果你真的想加密你的代码的字符串,这很容易。但是它有用吗?不。
现在,为了不让任何人将此标记为“不是答案”,我将发布一些简单的加密/解密代码:

// Generate key. You do it once and save the key in the code
var encryptorForGenerateKey = Aes.Create();
encryptorForGenerateKey.BlockSize = 128;
encryptorForGenerateKey.KeySize = 128;
encryptorForGenerateKey.GenerateKey();
encryptorForGenerateKey.GenerateIV();

var key = encryptorForGenerateKey.Key;
var iv = encryptorForGenerateKey.IV;

// Encrypt: this code doesn't need to be in the program. You create a console
// program to do it
var encryptor = Aes.Create();
var encryptorTransformer = encryptorForGenerateKey.CreateEncryptor(key, iv);

string str = "Hello world";
var bytes = Encoding.UTF8.GetBytes(str);
var encrypted = encryptorTransformer.TransformFinalBlock(bytes, 0, bytes.Length);
var encryptedString = Convert.ToBase64String(encrypted);

Console.WriteLine(encryptedString);

// Decrypt: this code needs to be in the program

var decryptor = Aes.Create();
var decryptorTransformer = decryptor.CreateDecryptor(key, iv);

byte[] encrypted2 = Convert.FromBase64String(encryptedString)

var result = decryptorTransformer.TransformFinalBlock(encrypted2, 0, encrypted2.Length);

var str2 = Encoding.UTF8.GetString(result);

这段代码显然不安全,任何人都可以反编译程序,添加一个Console.WriteLine(str2)重新编译。

nle07wnf

nle07wnf5#

你当然可以在编译之前加密你的字符串,但是如果你使用的是一个简单的db或者http url,你的代码有时需要以纯文本的形式加密。
在这种情况下没有真实的的保护:每个人都可以监听(断点)一个指定的方法,当调用时,看到发生了什么,而不需要真正阅读你的代码。所以,没有真正的保护,也使用混淆在某些时候,你会调用一些.NET方法与纯文本字符串,每个人都可以阅读它。
例如,您可以放置一个COM或C++ dll来存储加密的字符串。非托管dll是不可反编译的,然而,Maven当然可以理解dll的反汇编。正如前面所说,有时您将需要纯数据,而在那一刻,没有保护可以持续。
你唯一能做的就是改变你的架构。
例如,如果你的数据库是在线的,你的应用程序是客户端应用程序,你可以使用web服务连接。这样你就可以只公开用户真正需要使用的web服务,没有用户编写sql查询的风险。然后你可以在服务器上添加保护逻辑,而不是在客户端上。
如果一切都是离线的,你就无能为力了,你可以使用简单的字符串加密使生活变得更加困难,但它永远不会是一个真实的的保护。

p8ekf7hl

p8ekf7hl6#

正如Lucas在其评论中指出的那样,如果您只有一个部分,那么任何反编译您的应用程序的人都可以对其进行逆向工程并解密您的数据库密码。
关于存储凭据,我通常的做法是始终将它们存储在应用程序配置文件中。如果需要保护它,我使用SecureString和一些加密。这可以适用于任何类型的配置信息,而不仅仅是凭据。这里有一篇关于保护配置文件的非常好的文章:Encrypting Passwords in a .NET app.config File

30byixjq

30byixjq7#

也许您应该阅读更多关于加密web.config http://learn.iis.net/page.aspx/141/using-encryption-to-protect-passwords/的内容。
否则你就没什么可做的了。把敏感数据存储在代码中是不可行的,因为任何人都可以用反射器工具打开它并看到它。如果你想让代码或变量对所有人都不可见,你应该在一个私人服务器上创建一个网络服务,它接受数据,通过它的魔力转换数据并将其返回给客户端。这样,在发布和检索数据之间的所有事情都是保密的。

qf9go6mv

qf9go6mv8#

我不确定是否可以在客户端位置保护您的代码,但解决方案可能是将密码存储在Azure Key Vault中并使用Azure Active Directory对其进行身份验证。但是,这仍然可能进行逆向工程。您可以在此处阅读更多信息:https://learn.microsoft.com/en-us/azure/key-vault/

相关问题