0

我想以以下格式加密/保护输入字符串“AB123456789000”(两个字母和 12 位数字),以便安全的“版本”可以在数据库中存储为长(数字)。

我尝试过 RC2 加密,但它给了我 128 位,不适合 64 位长。

4

2 回答 2

1

首先,我必须有一点咆哮。

  1. RC2 已过时且不安全(发现加密弱点),请参阅Wikipedia。自行承担使用风险。
  2. 为什么不使用好的密码学?你想要一些安全的东西,所以只需使用 AES 加密东西。我不理解生成的加密必须为 64 位长的论点。在 Java 和 C# 中,用于加密的标准库都适用byte[],无需将其表示为一个long。每个数据库系统也应该能够保存二进制 blob。

回到将输入大小降至 64 位以下。

使用 ASCII,您的 14 个字母长字符串将是 14 字节(= 112)位,如果不压缩,它的加密将不适合 64 位。您可以通过说格式必须是2 个字母,然后是 12 个数字来作弊。对于编码,您将在其 ASCII 表示中逐字获取前两个字母。那将是 2*8 位 = 16 位。然后将 12 位数字作为一个整数,例如123456789000 = 0x1cbe991a085 个字节(= 40 位,它适合 a long)。这里可能的最大数字99999999990xe8d4a50fff,所以仍然可以将所有内容保存在 5 个字节中。

总之,我们将有 2*8 位 + 5*8 位 = 56 位,它小到足以适合 RC2 加密的一个块,即 64 位。您可以将最后一个字节设置为0x00.

因此,简而言之,明文的编码版本的 2 个字节将代表这两个字母的 ASCII 值,然后接下来的 5 个字节将是数字作为long.

例如, AB123456789000将被编码为0x41421cbe991a08( 'A' = 0x41, B = 0x42, then 123456789000 = 0x1cbe991a08)。您可以在 Java 和 C# 中编写编码和解码函数来实现这一点。

于 2016-04-24T17:07:07.457 回答
1

编码为 64 位可以非常简单:

public static long toId(String id) {
    long numPart = Long.parseLong(id.substring(2));
    long letterPart = Long.parseLong(id.substring(0, 2), 36);

    long res = (letterPart << 40) | numPart;

    System.out.println("Ids: " + id + " -> " + res);

    return res;
}

public static void main(String[] args) {
    toId("AB123456789000");
    toId("AA000000000000");
    toId("AA999999999999");
    toId("ZZ000000000000");
    toId("ZZ999999999999");
}

结果

Ids: AB123456789000 -> 408042270693896
Ids: AA000000000000 -> 406819302277120
Ids: AA999999999999 -> 407819302277119
Ids: ZZ000000000000 -> 1423867557969920
Ids: ZZ999999999999 -> 1424867557969919
于 2016-04-24T17:10:21.723 回答