2

如何使用最多 19 位数字BigInteger并使用以下规则对其进行加密:

  • 结果必须仅基于数字和小写英文字母。
  • 所有输出必须与任何输入具有相同的长度。长度必须在 11 到 16 个字符之间,具体取决于您的方法,但对于所有可能的输入应该是一致的
  • 没有简单的模式。例如,如果您加密 000...1 和 000...2,结果应该看起来完全不同。
  • 完全没有碰撞
  • 应该可以解密回原来的BigInteger。

我尝试过的事情

  • 取原始数字,通过某个键对它进行异或运算,将其乘以一个因子并将其转换为 36 进制字符串。该因素的目的是扩大范围,因此不会有太多的 0 填充。该因子必须在 1 到 之间36^16/10^19。这种方法的问题在于 a) 它不够“安全”,并且 b) 接近的数字具有非常相似的结果。

  • 这个答案。但是,结果往往太短或太长,之前使用的因子方法在这里不起作用。

4

3 回答 3

3

19 位略小于 64 位,因此您可以简单地使用 8 字节分组密码(如 ECB 模式下的 TDEA)来加密 BigInteger 值。首先检索 BigInteger 的默认 64 位编码,然后使用密钥加密,最后进行 base 36 编码。结果将是少于 16 个字符的几个字符,但您始终可以使用任何值填充。

请注意,如果您将相同的值加密两次,您将得到相同的结果,因此在这方面密文确实会泄漏一些有关纯文本的信息。

于 2013-03-16T18:03:46.090 回答
0

这是一段似乎可以做到的代码,前提是您可以将 转换BigIntegerulong(9999999999999999999 实际上是ulong)。结果始终是一个固定的 16 个字符的字符串(十六进制)。

    byte[] key = // put your 16-bytes private key here
    byte[] iv = Guid.NewGuid().ToByteArray(); // or anything that varies and you can carry

    string s = EncryptUInt64(ul, key, iv); // encode
    ulong dul = DecryptUInt64(s, key, iv).Value; // decode if possible


    public static string EncryptUInt64(ulong ul, byte[] key, byte[] iv)
    {
        using (MemoryStream output = new MemoryStream())
        using (var algo = TripleDES.Create())
        {
            algo.Padding = PaddingMode.None;
            using (CryptoStream stream = new CryptoStream(output, algo.CreateEncryptor(key, iv), CryptoStreamMode.Write))
            {
                byte[] ulb = BitConverter.GetBytes(ul);
                stream.Write(ulb, 0, ulb.Length);
            }
            return BitConverter.ToUInt64(output.ToArray(), 0).ToString("x16");
        }
    }

    public static ulong? DecryptUInt64(string text, byte[] key, byte[] iv)
    {
        if (text == null)
            return null;

        ulong ul;
        if (!ulong.TryParse(text, NumberStyles.HexNumber, null, out ul))
            return null;

        using (MemoryStream input = new MemoryStream(BitConverter.GetBytes(ul)))
        using (var algo = TripleDES.Create())
        {
            algo.Padding = PaddingMode.None;
            using (CryptoStream stream = new CryptoStream(input, algo.CreateDecryptor(key, iv), CryptoStreamMode.Read))
            {
                byte[] olb = new byte[8];
                try
                {
                    stream.Read(olb, 0, olb.Length);
                }
                catch
                {
                    return null;
                }
                return BitConverter.ToUInt64(olb, 0);
            }
        }
    }
于 2013-03-21T14:46:35.357 回答
0

您想要的技术是保存加密的格式。这将允许您将 19 位数字加密为另一个 19 位数字。

不幸的是,这种技术的高效版本有点难以实现,而且如果你选择错误的参数,实际上可能会非常不安全。有它的图书馆。 这个是开源的。不幸的是,它在 C++ 中,不清楚它是否在 Windows 上运行。 Voltage也有一个库,尽管它可能要花钱,而且我不确定它们支持哪些语言。

于 2013-03-21T05:51:34.763 回答