有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java加密/安全短字符串到长字符串

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

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


共 (2) 个答案

  1. # 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
    
  2. # 2 楼答案

    首先,我必须有点咆哮

    1. RC2已过时且不安全(发现密码漏洞),请参见Wikipedia。风险自负
    2. 为什么不使用好的加密技术?你想要一些安全的东西,比如用AES加密。我不理解这样的论点,即最终的加密必须是64位长的。在Java和C#中,用于加密的标准库都在byte[]上工作,无需将其表示为一个long。每个数据库系统也应该能够保存二进制blob

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

    使用ASCII,14个字母长的字符串将是14字节(=112)位,如果不进行压缩,它的加密将不适合64位。你可以说的格式必须是两个字母,然后是12位数字,以此来作弊。对于编码,您需要以ASCII表示形式逐字记录前两个字母。这将是2*8位=16位。然后将12位数字作为一个整数,例如123456789000 = 0x1cbe991a08,即5个字节(=40位,适合于long)。这里最大的可能数字是9999999999,也就是0xe8d4a50fff,所以所有内容仍然可以保存在5个字节中

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

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

    比如说,, AB123456789000将被编码为0x41421cbe991a08'A' = 0x41, B = 0x42,然后123456789000 = 0x1cbe991a08)。可以用Java和C编写编码和解码函数来实现这一点