Зашифровать / защитить короткую строку до длинной
Я хотел бы зашифровать / защитить входную строку в следующем формате "AB123456789000" (две буквы и 12 цифр), чтобы защищенная "версия" могла быть сохранена как длинная (число) в базе данных.
Я пробовал шифрование RC2, но оно дает мне 128 бит, который не подходит для 64 бит.
2 ответа
Кодирование в 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
Прежде всего у меня должна быть маленькая напыщенная речь.
- RC2 устарел и небезопасен (обнаружены криптографические недостатки), см. Википедию. Используйте это на свой страх и риск.
- Почему НЕ использовать хорошую криптографию? Вы хотите что-то безопасное, поэтому просто зашифруйте что-нибудь с помощью AES, например. Я не понимаю аргумент, что полученное шифрование имеет длину 64 бита. В Java и C# все стандартные библиотеки для шифрования работают на
byte[]
нет необходимости представлять его как единое целоеlong
, Каждая система баз данных также должна сохранять двоичные двоичные объекты.
Вернемся к уменьшению размера ввода до 64 бит.
Используя ASCII, ваша 14-буквенная длинная строка будет иметь длину 14 байт (= 112), ее шифрование не будет помещаться в 64 бита без сжатия. Вы можете обмануть, сказав, что формат должен быть 2 буквы, а затем 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# для реализации этого.