Шифрование и расшифровка 19-значного BigInteger
Как я могу взять максимум 19 цифр длиной BigInteger
и зашифровать его с помощью следующих правил:
- Результат должен быть основан только на цифрах и строчных английских буквах.
- все выходы должны иметь одинаковую длину для любого входа. Длина должна быть от 11 до 16 символов, в зависимости от вашего метода, , но должна быть согласованной для всех возможных входных данных.
- нет простых шаблонов. Например, если вы шифруете 000...1 и 000...2 результаты должны выглядеть полностью различный.
- никаких столкновений вообще
- должен быть в состоянии расшифровать обратно к исходному BigInteger.
Вещи, которые я пробовал
-
Возьмите исходное число, умножьте его на некоторый ключ, умножьте на коэффициент и преобразуйте в базовую строку 36. Цель фактора состоит в том, чтобы расширить диапазон, чтобы не было слишком много заполнения 0. Коэффициент должен быть от 1 до
36^16/10^19
. Проблема с этим методом заключается в том, что а) он недостаточно "безопасен" , и Б) близок цифры дают очень похожие результаты.
3 ответа:
19 цифр-это немного меньше, чем 64 бита, поэтому вы можете просто использовать 8-байтовый блочный шифр, такой как TDEA в режиме ECB, для шифрования значений BigInteger. Сначала извлеките 64-битную кодировку BigInteger по умолчанию,затем зашифруйте секретным ключом и, наконец, кодируйте его на базе 36. Результат будет на несколько символов меньше 16 символов,но вы всегда можете добавить любое значение.
Обратите внимание, что если вы зашифруете одно и то же значение дважды, то получите один и тот же результат, поэтому в этом отношении зашифрованный текст утечка некоторой информации о простом тексте.
Методика вы хотите формат ожесточенной шифрования. Это позволит вам зашифровать 19-значное число как другое 19-значное число.
К сожалению, эффективная версия этой техники несколько сложна в реализации и на самом деле может быть выполнена очень небезопасно, если вы выберете неправильные параматеры. Для этого существуют библиотеки. Этот является открытым исходным кодом. Это в C++, к сожалению, и его не ясно, если он работает на windows. напряжение имеет библиотеку в виде ну, хотя это, по-видимому, стоит денег, и я не уверен, какие языки они поддерживают.
Вот фрагмент кода, который, кажется, делает это, при условии, что вы можете преобразовать
BigInteger
вulong
(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); } } }