Возможно, мои ожидания ошибочны. Я не специалист по криптографии, я просто простой пользователь. Я изо всех сил старался сделать эту работу без успеха до сих пор.
Исходная информация:
Я пытаюсь TCipher_Blowfish_
Legacy Encryption из Delphi Encryption Compendium, который использует Blowfish Engine (TCipher_Blowfish_
) с режимом работы CTS (cmCTS
). Закрытый ключ хешируется RipeMD256 (THash_RipeMD256
).
Проблемы:
Входной текстовый массив байтов должен быть одного размера CIPHER_BLOCK
. Насколько я могу судить, это не должно.
Из Википедии:
В криптографии, шифрование зашифрованного текста (CTS) - это общий метод использования режима блочного шифрования, который позволяет обрабатывать сообщения, которые не делятся равномерно на блоки, не приводя к расширению зашифрованного текста за счет немного повышенной сложности.
Результат не совпадает с предыдущей:
Я использую:
- Тот же IV
- Тот же пароль
- Один и тот же вводный текст
Унаследованное приложение использует ANSI String, новый использует Unicode, поэтому для каждой строки ввода, которую я назвал Encoding.ASCII.GetBytes("plainText")
, Encoding.ASCII.GetBytes("privatepassword")
.
Байты личного пароля затем хэшируются RipeMD256, я проверял выходные байты, и они одинаковы.
Я могу подтвердить, что проблема специфична для Bouncy Clastle (режим работы или отсутствующая конфигурация/шаг), потому что я загрузил вторую библиотеку Blowfish.cs и использовал вход 8 байтов (того же размера, что и блок шифрования) и используя Encrypt_CBC(bytes[])
с тем же IV результатом будет тот же результат, что и унаследованный формат.
Это эскиз кода, который я использую для Blowfish.cs
и Bouncy Castle
:
Компилятор шифрования Delphi
var
IV: Array [0..7] of Byte (1,2,3,4,5,6,7,8);
Key: String = '12345678';
with TCipher_Blowfish.Create('', nil) do
begin
try
InitKey(Key, @IV); //Key is auto hashed using RIPE256 here;
Result:= CodeString('12345678', paEncode, -1); //Output bytes is later encoded as MIME64 here, the result is the hash.
finally
Free;
end;
end;
Blofish.cs
var hashOfPrivateKey = HashValue(Encoding.ASCII.GetBytes("12345678"));
Blowfish b = new BlowFish(hashOfPrivateKey);
b.IV = new byte[8] { 1, 2, 3, 4, 5, 6, 7, 8};
var input = Encoding.ASCII.GetBytes("12345678");
var output = b.Encrypt_CBC(input);
Я предполагаю, что CTS и CBC всегда будут иметь одинаковый результат, если входной сигнал составляет 8 бит. Неужели это просто удача или совпадение или в основном истина?
Загадочный замок
IBufferedCipher inCipher = CipherUtilities.GetCipher("BLOWFISH/CTS");
var hashOfPrivateKey = HashValue(Encoding.ASCII.GetBytes("12345678"));
var key = new KeyParameter(hashOfPrivateKey);
var IV = new byte[8] { 1, 2, 3, 4, 5, 6, 7, 8};
var cipherParams = new ParametersWithIV(key, IV);
inCipher.Init(true, cipherParams);
var input = Encoding.ASCII.GetBytes("12345678");
//try one: direct with DoFinal
var output = inCipher.DoFinal(input);
// output bytes different from expected
inCipher.Reset();
//try two: ProcessBytes then DoFinal
var outBytes = new byte[input.Length];
var res = inCipher.ProcessBytes(input, 0, input.Length, outBytes, 0);
var r = inCipher.DoFinal(outBytes, res);
// outBytes bytes different from expected
Как я уже сказал, я сравниваю CBC с CTS, исходя из предположения, что при вводе 8 байтов вывод будет таким же. Я не могу перенаправить реализацию с Bouncy Castle, даже если с тем же входом результат не совпадает.
Я не знаю:
- Если режим CTS, используемый в Delphi Encryption Compendium, использует CBC вместе с CTS. Я не мог найти документально нигде.
- Разница между вызовом только DoFinal() и ProcessBytes(), а затем DoFinal() в Bouncy Castle, я полагаю, что это необходимо, когда входной блок больше размера блока двигателя, в этом случае они одного размера.
- Если Delphi Encryption Compendium является правильным/неправильным или если Bouncy Castle является правильным/неправильным. У меня недостаточно знаний в криптографии, чтобы понять реализацию, иначе я не стал бы задавать вопрос здесь (мне нужно руководство).