Совместимость LockBox / Node Crypto

Я пытаюсь (и не могу) расшифровать в Delphi с использованием LockBox 3 сообщение, зашифрованное с помощью криптографической библиотеки Node.js.

Код node.js:

var crypto = require('crypto');
var cipher = crypto.createCipher('aes-256-ctr', 'my password');
var crypted = cipher.update('hello world', 'utf8', 'base64');
crypted += cipher.final(output_encoding);
console.log(crypted);

Результатом этого является

oyC1KRVx3JZBLlI=

Код Delphi:

var
  Codec: TCodec;
  CipherText: AnsiString;
begin
  Codec := TCodec.Create(nil);
  try
    Codec.CryptoLibrary := TCryptographicLibrary.Create(Codec);
    //
    Codec.StreamCipherId = 'native.StreamToBlock';
    Codec.BlockCipherId  = 'native.AES-256';
    Codec.ChainModeId    = 'native.CTR';
    //
    Codec.Password := 'my password';
    Codec.DecryptAnsiString(CipherText, 'oyC1KRVx3JZBLlI=');
    //
    Result := string(CipherText);
  finally
    Codec.Free;
  end;
end;

Что мне не хватает?


person Z..    schedule 12.02.2016    source источник
comment
Вам не хватает текста в кодировке base64. Сначала вам нужно декодировать base64, а затем AES. Кроме того, приведение типов строк может нарушить ваш текст. Это UTF8, поэтому вам, вероятно, следует использовать UTF8ToString.   -  person smooty86    schedule 13.02.2016
comment
DecryptAnsiString ожидает Base64   -  person Z..    schedule 13.02.2016
comment
Вы уверены, что обе библиотеки используют один и тот же метод для генерации ключей шифрования из пароля?   -  person quasoft    schedule 13.02.2016
comment
@Danev Трудно в это поверить. Почему бы не заняться отладкой?   -  person David Heffernan    schedule 13.02.2016
comment
В дополнение к ответу quasoft на этом сайте есть еще много вопросов по той же проблеме. Либо о кодировке, IV или заполнении.   -  person Jan Doggen    schedule 13.02.2016


Ответы (1)


В чем проблема?

Проблема в том, что обе библиотеки используют разные ключи и векторы инициализации (IV) внутри.

Помните, что шифр AES работает не с паролями, а с ключами и IV.

Когда вы предоставляете пароль для криптографической библиотеки, она использует некоторый внутренний механизм для автоматического получения ключа и IV.

Этот механизм неочевиден, но обычно описывается в документации криптографических библиотек.

В документации модуля crypto в node.js говорится, что он использует функцию EVP_BytesToKey OpenSSL для получения ключа и IV:

crypto.createCipher (алгоритм, пароль) - создает и возвращает объект Cipher, который использует заданный алгоритм и пароль.

...

Пароль используется для получения ключа шифрования и вектора инициализации (IV). Значение должно быть либо строкой в ​​двоичной кодировке, либо [Buffer [].

Реализация crypto.createCipher () извлекает ключи с помощью функции OpenSSL EVP_BytesToKey с алгоритмом дайджеста, установленным на MD5, одна итерация и без соли. Отсутствие соли допускает словарные атаки, поскольку один и тот же пароль всегда создает один и тот же ключ. Малое количество итераций и некриптографически безопасный алгоритм хеширования позволяют очень быстро проверять пароли.

Цитата из документации по Node.js v5.6.0.

Как решить проблему?

Правильное решение - использовать криптографически безопасный алгоритм хеширования для получения ключа из пароля, а затем вручную предоставить ключи и IV в криптографическую библиотеку, какой бы она ни была.

Быстрое и грязное (и крайне небезопасное) решение - найти подпрограмму Delphi, эквивалентную EVP_BytesToKey, и просто использовать ее, чтобы заставить ее работать.

Не забудьте также убедиться, что вы используете ту же схему заполнения. TCodec должен позволить вам выбрать PaddingScheme из padPKCS, который должен быть совместим с модулем шифрования в node.js. Если не работает, попробуйте и другие варианты.


Другой вариант - использовать OpenSSL в Delphi, который уже должен быть совместим с тем, что используется в node.js.


Также см. Этот вопрос с проблемой, аналогичной вашей:

person quasoft    schedule 13.02.2016
comment
Схема заполнения для блочных шифров TPLB3 - это кража зашифрованного текста. - person Sean B. Durkin; 16.02.2016