【问题标题】:Simple obfuscation of string in .NET?.NET 中字符串的简单混淆?
【发布时间】:2012-10-13 02:52:28
【问题描述】:

我需要通过 Internet 发送大约 30 个字符的字符串,这可能最终会成为另一家公司数据库中的 ID。

虽然字符串本身无法识别,但我仍然希望它不会以任何方式被识别。

在 .NET 中混淆这样一个字符串的最简单方法是什么,以便在必要时可以轻松地反转它?

【问题讨论】:

  • 如果可以轻松逆转,那又有什么意义呢?
  • @BaliC 如果你知道怎么做,我想很容易逆转。
  • 您是否有可用于匹配的原始字符串列表?如果是这样,请查看散列算法。
  • @BaliC:我只是想阻止人们检查数据库并立即查看数据。
  • 我会在这里做一个 ROT13 转换一个很好的例子:stackoverflow.com/a/18739120/187030

标签: c# .net string obfuscation


【解决方案1】:

经典的东西怎么样(带有现代风格)。

public static string Caesar(this string source, Int16 shift)
{
    var maxChar = Convert.ToInt32(char.MaxValue);
    var minChar = Convert.ToInt32(char.MinValue);

    var buffer = source.ToCharArray();

    for (var i = 0; i < buffer.Length; i++)
    {
        var shifted = Convert.ToInt32(buffer[i]) + shift;

        if (shifted > maxChar)
        {
            shifted -= maxChar;
        }
        else if (shifted < minChar)
        {
            shifted += maxChar;
        }

        buffer[i] = Convert.ToChar(shifted);
    }

    return new string(buffer);
}

显然你会这样使用

var plain = "Wibble";
var caesered = plain.Caesar(42);
var newPlain = caesered.Caesar(-42);

它很快,您的密钥只是一个Int16,它会阻止不经意的观察者复制粘贴该值,但它并不安全。

【讨论】:

  • - 我喜欢这个 :) 说我将这个字符串存储在一个 html 页面中,并想取消停止并通过 javascript 使用该字符串,你能告诉我它是如何工作的吗?
  • @TheDonSansone,这可能很棘手。虽然我可以编写此函数的 javascript 等效项,但 shift 和 unicode 的某种组合可能会产生不映射到真实 unicode 代码点的 char 值。如果数据以二进制形式在.Net 之间传输,这很好组件,但是当它通过 HTTP 返回到未知浏览器时,我无法确定会发生什么。如果您可以限制字符串中 char 值的范围和 shift 的大小,您可能会没问题,但我很想找到一个“铸铁”替代方案。
  • Jodrell 明白,已找到铸铁替代品;)再次感谢。
【解决方案2】:

怎么样:

    Convert.ToBase64String(Encoding.UTF8.GetBytes(myString));

及其反面:

    Encoding.UTF8.GetString(Convert.FromBase64String(myObfuscatedString));

只要你不介意增加字符串的长度

【讨论】:

  • 唯一的缺点,除了尺寸增加之外,就是 tale tale == 终结者,总是让我觉得,那一定是 base64。
  • @Joe 你能解释一下这个混淆的作用(在位方面)吗?
  • @user2997779 - 它按照它在锡上所说的做:将字符串转换为 base64 编码,如果你看的话,你会发现很多关于这种编码的文档。 Base64 编码不易被大多数人阅读,因此提供了基本级别的混淆,但这种技术并不假装是安全的。
  • @rolls - 恕我直言,如果你关心算法是否容易被猜到,你应该使用加密而不是混淆。
  • 这非常适合混淆。我想在一个简单的 id 字符串中屏蔽文件路径 + 哈希有效负载,该字符串需要看起来干净,加密并不总是与安全本身有关。
【解决方案3】:

尝试使用例如 AES 加密它,如果您知道另一台机器上的加密密钥,您可以轻松地在那里解密它

http://msdn.microsoft.com/en-us/library/system.security.cryptography.aes(v=vs.100).aspx

周围有很多代码示例。例如,我通过快速搜索找到了这篇文章,即使它只有 128 位,我认为它应该可以解决问题

Using AES encryption in C#

【讨论】:

  • 但是您将把密钥存储在哪里?
  • 这是双向的,“牢不可破”且易于实现(而不是编写自己的“加密器”)。
  • 您的应用程序配置文件,例如 asp 中的 appsettings
  • 密钥可以被硬编码——如果它只是为了阻止字符串在第 3 方数据库中可见。
  • @gt,当密钥被硬编码时,牢不可破的声明是没有意义的。
【解决方案4】:

@Jodrell 的回答启发了我,这是我的替代版本。唯一真正的区别是我使用模运算符而不是 if-then-else 构造。

如果你和我一样,以前从未听说过凯撒密码,这里有一个链接:

https://en.wikipedia.org/wiki/Caesar_cipher

   public static partial class MString
   {
      ...

      /// <summary>
      /// Method to perform a very simple (and classical) encryption for a string. This is NOT at 
      /// all secure, it is only intended to make the string value non-obvious at a first glance.
      ///
      /// The shiftOrUnshift argument is an arbitrary "key value", and must be a non-zero integer 
      /// between -65535 and 65535 (inclusive). To decrypt the encrypted string you use the negative 
      /// value. For example, if you encrypt with -42, then you decrypt with +42, or vice-versa.
      ///
      /// This is inspired by, and largely based on, this:
      /// https://stackoverflow.com/a/13026595/253938
      /// </summary>
      /// <param name="inputString">string to be encrypted or decrypted, must not be null</param>
      /// <param name="shiftOrUnshift">see above</param>
      /// <returns>encrypted or decrypted string</returns>
      public static string CaesarCipher(string inputString, int shiftOrUnshift)
      {
         // Check C# is still C#
         Debug.Assert(char.MinValue == 0 && char.MaxValue == UInt16.MaxValue);

         const int C64K = UInt16.MaxValue + 1;

         // Check the arguments
         if (inputString == null)
            throw new ArgumentException("Must not be null.", "inputString");
         if (shiftOrUnshift == 0)
            throw new ArgumentException("Must not be zero.", "shiftOrUnshift");
         if (shiftOrUnshift <= -C64K || shiftOrUnshift >= C64K)
            throw new ArgumentException("Out of range.", "shiftOrUnshift");

         // Perform the Caesar cipher shifting, using modulo operator to provide wrap-around
         char[] charArray = new char[inputString.Length];
         for (int i = 0; i < inputString.Length; i++)
         {
            charArray[i] = 
                  Convert.ToChar((Convert.ToInt32(inputString[i]) + shiftOrUnshift + C64K) % C64K);
         }

         // Return the result as a new string
         return new string(charArray);
      }

      ...
   }

还有一点测试代码:

     // Test CaesarCipher() method
     const string CHelloWorld = "Hello world!";
     const int CCaesarCipherKey = 42;
     string caesarCiphered = MString.CaesarCipher(CHelloWorld, CCaesarCipherKey);
     if (MString.CaesarCipher(caesarCiphered, -CCaesarCipherKey) != CHelloWorld)
        throw new Exception("Oh no!");

【讨论】:

    猜你喜欢
    • 2014-05-21
    • 1970-01-01
    • 1970-01-01
    • 2010-11-02
    • 2017-05-16
    • 1970-01-01
    • 2011-03-14
    • 2013-11-28
    • 1970-01-01
    相关资源
    最近更新 更多