Encrypt / secure short string to long

704 Views Asked by At

I would like to encrypt / secure input string in the following format "AB123456789000" (two letters and 12 digits) so that the secured "version" can be stored as long (number) in the database.

I have tried RC2 encryption but it gives me 128 bit which does not fit in 64 bit long.

2

There are 2 best solutions below

0
On

First of all I must have a little rant.

  1. RC2 is outdated and insecure (cryptographic weaknesses found), see Wikipedia. Use it on your own risk.
  2. Why NOT use good cryptography? You want something secure, so just encrypt stuff with AES for example. I don't understand the argument that the resulting encryption has to a 64-bit long. In both Java and C# the standard libraries for encryption all work on byte[], no need to represent it as one long. Every databasesystem should also be able to save binary blobs.

Back to getting your input size down to under 64 bit.

Using ASCII, your 14-letter long string would be 14 bytes (= 112) bits, its encryption won't fit in 64 bits without compressing. You can cheat by saying that the format must be 2 letters and then 12 digits . For encoding, you'd take the first two letters verbatim in their ASCII representation. That would be 2*8 bit = 16 bit. Then take 12 digits as a whole number, e.g. 123456789000 = 0x1cbe991a08 which is 5 bytes (= 40 bit, it fits in a long). The biggest possible number here is 9999999999 which is 0xe8d4a50fff, so everything can still be saved in 5 bytes.

Alltogether we would have 2*8 bit + 5*8 bit = 56 bit, which is small enough to be fitting in one block of the RC2 encryption, which is 64 bit. You can set the last byte to 0x00.

So, in short, the 2 bytes of the encoded version of your plaintext would represent the ASCII value of these two letters, then the the next 5 bytes would be the number as a long.

For example, AB123456789000 would be as such be encoded to 0x41421cbe991a08 ('A' = 0x41, B = 0x42, then 123456789000 = 0x1cbe991a08). You can write encoding and decoding functions in both Java and C# to realize this.

0
On

Encoding to 64 bit could be done pretty simple:

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");
}

Result

Ids: AB123456789000 -> 408042270693896
Ids: AA000000000000 -> 406819302277120
Ids: AA999999999999 -> 407819302277119
Ids: ZZ000000000000 -> 1423867557969920
Ids: ZZ999999999999 -> 1424867557969919