如何模糊字符串常量?

我们有一个包含敏感信息的应用程序,我正在尽力保护它。 敏感信息包括:

  1. 主要算法
  2. 加密/解密算法的关键

我一直在研究混淆代码,但它似乎没什么帮助,因为我仍然可以反编译它。 但是,我最担心的是,当您对代码进行反编译时,用于加密序列号等的密钥清晰可见,即使它是混淆的。

任何人都可以建议我如何保护这些字符串?

我意识到其中一种方法可能是从应用程序本身删除任何解密,虽然这可能部分可能,有一些function必须使用加密/解密 – 主要是为了保存配置文件和传递’授权’令牌到DLL执行计算。

如果有人有足够的动力打破它,那么所有的努力都将是徒劳的。 即使是最大的软件公司,也没有人能够解决这个问题。

我正尽力保护它

我不是说这是一个严厉的批评,只是你需要意识到你想要达到的目标当前被认为是不可能的。

混淆是通过默默无闻的安全,它确实有一些好处,因为它将阻止最无能的黑客企图,但主要是浪费的努力,或许可以更好地花在其他发展领域。

在回答您的原始问题时,您将遇到智能编译器的问题,他们可能会自动将字符串拼凑到已编译的应用程序中,从而消除您的一些混淆工作作为编译优化。 这也很难维护,所以我会重新考虑你的风险分析模型,也许会让自己屈服于它可以破解的事实,如果它有任何价值可能会。

有办法做你想要的,但它并不便宜,并不容易。

这值得么?

在考虑是否保护软件时,我们首先要回答一些问题:

  1. 这种情况发生的可能性有多大?
  2. 您的算法和数据对其他人有什么价值?
  3. 购买使用软件的许可证的成本是多少?
  4. 他们复制算法和数据的成本是多少?
  5. 他们对您的算法和数据进行逆向工程的成本是多少?
  6. 保护算法和数据的成本是多少?

如果这些产生了保护您的算法/数据的重要经济要求,那么您应该考虑这样做。 例如,如果服务的价值和客户的成本都很高,但是反向工程代码的成本远远低于自己开发代码的成本,那么人们可能会尝试它。

所以,这会导致你的问题

  • 您如何保护算法和数据?

灰心丧气

困惑

您建议的选项,混淆代码,与上面的经济学混淆 – 它试图显着增加他们的成本(上面的5)而不会增加你的成本(6)。 加密function中心的研究对此进行了一些有趣的研究。 问题是,与DVD加密一样,如果在3,4和5之间存在足够的差异,则注定会失败,最终有人会这样做。

发现

另一种选择可能是隐写术的一种forms,它允许您识别谁解密您的数据并开始分发它。 例如,如果您有100个不同的浮点值作为数据的一部分,并且每个值的LSB中的1位错误不会导致应用程序出现问题,请将唯一(对每个客户)标识符编码为这些位。 问题是,如果某人有权访问您的应用程序数据的多个副本,那么它显然会有所不同,从而更容易识别隐藏的消息。

保护

SaaS – 软件即服务

更安全的选择可能是将软件的关键部分作为服务提供 ,而不是将其包含在您的应用程序中。

从概念上讲,您的应用程序将收集运行算法所需的所有数据,将其作为请求打包到云中的服务器(由您控制​​),然后您的服务将计算结果并将其传递回客户端,哪个会显示出来。

这将您所有的专有机密数据和算法保存在您完全控制的域中,并消除客户端提取的任何可能性。

明显的缺点是客户端与服务提供相关,受服务器及其互联网连接的支配。 不幸的是,很多人出于这些原因反对SaaS 。 从好的方面来说,它们始终是最新的错误修复程序,而您的计算群集可能比运行用户界面的PC具有更高的性能。

这将是一个巨大的进步,并且可能会有巨大的成本6,但是保持算法和数据完全安全的几种方法之一。

软件保护加密狗

虽然传统的软件保护加密狗可以防止软件盗版,但它们无法防止提取代码中的算法和数据。

较新的代码移植加密狗(如SenseLock )似乎能够做你想要的。 使用这些设备,您可以从应用程序中取出代码并将其移植到安全加密狗处理器。 与SaaS一样,您的应用程序会捆绑数据,将其传递给加密狗(可能是连接到您计算机的USB设备)并回读结果。

与SaaS不同,数据带宽不太可能成为问题,但应用程序的性能可能会受到SDP性能的限制。

†这是我在谷歌搜索中找到的第一个例子。

值得信赖的平台

另一种可能在未来可行的选择是使用可信平台模块和可信执行技术来保护代码的关键区域。 每当客户安装您的软件时,他们都会为您提供硬件指纹,并为您提供该特定系统的解锁密钥。

然后,该密钥将允许在可信环境中解密和执行代码,其中加密的代码和数据在可信平台之外是不可访问的。 如果有关可信环境的任何内容发生了变化,它将使密钥无效,并且该function将丢失。

对于客户而言,这样做的优势在于他们的数据保持在本地,并且他们不需要购买新的加密狗来提高性能,但它有可能创建持续的支持要求以及您的客户可能会对此感到沮丧。箍他们不得不跳过使用他们购买和支付的软件 – 失去你的善意。

结论

你想做的不是简单或便宜。 它可能需要在软件,基础设施或两者上进行大量投资。 在开始这条道路之前,您需要知道投资是值得的。

我最近读了一个非常简单的OP解决方案。

简单地将常量声明为只读字符串,而不是const字符串。 那很简单。 显然,const变量被写入二进制文件中的堆栈区域,但是以纯文本forms写入,而readonly字符串被添加到构造函数中并写为字节数组而不是文本。

即如果你搜索它,你将找不到它。

那是个问题,对吗?

使用自定义算法( 通过默默无闻的安全性? ),结合将密钥存储在应用程序中,根本不安全。

如果要存储某种密码,则可以使用单向散列函数来确保解密数据在代码中的任何位置都不可用。

如果您需要使用对称加密算法,请使用众所周知且经过测试的算法,如AES-256 。 但是密钥显然不能存储在你的代码中。

[编辑]

既然你提到了序列号的加密,我相信你的单向散列函数(比如SHA-256 )会更好地满足你的需求。

我们的想法是在构建时将您的序列号散列到它们的散列表示中,这些表示不能被反转(SHA-256被认为是一种非常安全的算法 ,比如MD5)。 在运行时,您只需要将相同的哈希函数应用于用户输入,并仅比较哈希值 。 这样,攻击者无法获得任何实际序列号。

@Tom Gullen给出了正确的答案。

我只是提出了一些建议,说明如何让用户更难以访问您的密钥和算法。

至于算法:不要在编译时编译算法,而是在运行时编译。 为此,您需要指定一个包含算法方法的接口。 该接口用于运行它。 然后将算法的源代码添加为加密字符串(嵌入式资源)。 在运行时解密它并使用CodeDom将其编译为.NET类。

密钥:通常的方法是将密钥的扩展部分存储在应用程序的不同位置。 将每个部分存储为byte[]而不是string以使其更难找到它们。

如果您的所有用户都具有互联网连接:请使用SSL获取算法源代码和密钥。

请注意,所有内容都将在运行时拼凑在一起,任何具有更多知识的人都可以检查/调试应用程序以查找所有内容。

我不认为你可以很容易地混淆字符串常量,所以如果可能的话,不要使用它们:)你可以使用汇编资源,那些你可以加密但你想要的。

取决于你想要做什么,但你可以使用非对称加密吗? 这样你只需要存储公钥而不需要对它们进行模糊处理。