【问题标题】:encrypted value is not coming back the same each time加密的值不是每次都一样
【发布时间】:2013-02-12 14:59:21
【问题描述】:

我正在使用 Brett 给出的这个例子:

Encrypt and decrypt a string

然后这样做:

public static bool VerifyLicenseKey(string applicationGuid)
{
  Console.WriteLine("G: " + applicationGuid);
  var appSettings = AppSettings.GetInstance();
  if (appSettings == null)
  {
    return false;
  }
  var hwinfo = HardwareInfo.GetHardwareSerial();
  Console.WriteLine("h: " + hwinfo);
  Console.WriteLine("a: " + applicationGuid);
  var currentSerial = Crypto.EncryptStringAES(hwinfo, applicationGuid);
  Console.WriteLine("c: " + currentSerial);
  Console.WriteLine("o: " + appSettings.LicenseSerialNumber);
  if (currentSerial == appSettings.LicenseSerialNumber)
  {
    return true;
  }
  return false;
}

}

GetHardwareSerialapplicationGuid 每次都以相同的方式返回,但当我调用 EncryptStringAES 时却不是。

我是否使用了错误的类?不是每次都一样吗?

如果没有,是否有人有一个更好的例子,其中加密的值是相同的?

【问题讨论】:

  • 这些信息真的是秘密的,还是只需要正确?我想你想要message authentication codedigital signature,而不是加密。
  • 或者您可以使用更简单的 MD5 哈希或 CRC32 校验和。
  • 你到底想在这里做什么?这对我来说没有任何意义。你能解释一下你在这里试图解决什么问题以及为什么你认为加密是一个合适的解决方案吗?加密应该用于两件事且仅用于两件事:(1) 对秘密消息进行编码和解码,以及 (2) 对消息进行数字签名。你似乎没有做这两件事,所以很难评估你在哪里做错了;整件事似乎都错了。
  • 至于您的问题:对于给定的明文加密两次后产生相同的密文,没有任何要求。要求是密文解密时产生明文;可能有许多密文解密为相同的明文。正如我之前所说,如果您没有使用密文来保护秘密消息,那么您使用的是错误的工具。
  • 那你需要加密做什么?如果它是一个简单的机制,那么保持简单。如果您需要的是“请远离”标志,那么您为什么要使用带有激光和鳄鱼的钢闸门?或者,更准确地说,是带有激光和鳄鱼以及敞开的后门的钢闸门?

标签: c# encryption


【解决方案1】:

您的“加密”实际上只是一种混淆,并且很难绕过。 只需要知道您的应用程序 guid(可能是公开的)以及获取相同硬件 ID 的方法(可能不是您编写的,而且很容易找到)。

当然,您希望您的保护工作有多难还取决于您的软件的价值或高容量,因此简单的混淆可能就足够了。忘记 AES,您需要的是哈希算法,例如 SHA 或 MD5,您可以在其中将您的应用程序 guid、硬件编号、用户名等哈希在一起并存储哈希。对于大多数典型用户来说,这足以起到威慑作用。

如果您坚持使用难以破解的保护,您需要的是数字签名和激活程序。见RSACryptoServiceProvider

基本上,您创建一个知道您的私钥的服务,然后将匹配的公钥放入您的软件中。然后从您的软件中,您使用 HardwareInfo 以及您想要验证的任何其他信息调用服务,服务对其进行签名并返回签名哈希。

一旦你在你的客户端拥有它,你就可以使用公钥来检查签名,即使信息可以以明文形式存储,签名也不能轻易地重新创建。

也可以check this question 了解更多信息。

【讨论】:

  • +1 是的,我只是想让普通乔无法在没有工作的情况下将我们的软件从一台计算机复制到另一台计算机。很好的信息。这比我真正需要的要多得多。
  • 天哪,您草拟的解决方案听起来很糟糕。您提议的服务如何不会自动受到选择明文攻击? RSA 的安全性取决于以下事实:使用私钥加密的文本是由密钥持有者创建的
  • @EricLippert 我不理解您的评论,或者您不理解解决方案。选择明文可以攻击哪个部分?这几乎就是所有软件激活的工作原理
  • 您说“您向服务发送消息并使用私钥对其进行签名”的部分。是什么阻止了攻击者向服务发送他们自己选择的消息?
  • @EricLippert 阻止他们的是他们的电子邮件必须在与他们的购买历史相关联的数据库中,或者在您的数据库中随机生成的激活码只能使用一次
【解决方案2】:

您所指的算法使用RijndaelManaged class,它似乎使用IV property 的默认值(非常正确)每当您创建一个新的时自动设置为一个新的随机值实例(参见文档)。

因此,您每次都会得到不同的结果。 (例如,您可以在 Wikipedia 上找到有关 IV 用途的更多信息。)

【讨论】:

  • 啊好的,你有一个非动态加密的例子吗?
  • 您当然可以根据需要设置 IV 属性,尽管这会削弱加密。如果您每次都想要相同的结果,请使用加密哈希,而不是加密算法(尽管目的完全不同)。
  • 你说设置时指的是这个部分:var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV)
  • 是的,我没有看到aesAlg.IV 之前在代码中的任何地方初始化,所以我猜它使用的是默认值。这是一个可以设置的属性。话虽如此,尚不清楚您尝试做的是否是一个好主意。使用不同的 IV 实际上是一件好事。您似乎对加密、签名和散列的目的有点困惑。
  • 是的,这就是我认为 tyvm 的信息
【解决方案3】:

是的,大多数 AES 加密是非确定性的(并且有充分的理由)它对您不起作用,但由于您只想比较加密结果并且您并不想解密,我建议您使用 @987654321 @ 代替。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-24
    • 1970-01-01
    • 2016-11-01
    • 1970-01-01
    相关资源
    最近更新 更多