AES-256-CBC с дайджестом от Ruby до NodeJS

Я надеюсь, что кто-то может пролить свет на проблему, которая беспокоила меня в течение последних нескольких часов.

Я пытаюсь декодировать строку, закодированную в Ruby, таким образом:

#!/usr/bin/env ruby

require 'base64'
require 'openssl'
require 'openssl/cipher'
require 'openssl/digest'

aes = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
aes.encrypt
aes.key = Digest::SHA256.digest('IHazSekretKey') 

p Base64.encode64( aes.update('text to be encrypted') << aes.final )

Выполнение вышеуказанного выдает: "3P86KyOrN2QJ/HFxxo3b7kAsxTgpDMMjROUPclsuXj0=\n"

Теперь я пытаюсь расшифровать эту строку в NodeJS 0.6.17.

#!/usr/bin/env node

var crypto = require('crypto'); 

function decrypto(toDecryptStr) {
  var result,
    encoded   = new Buffer(toDecryptStr, 'base64'),
    decodeKey = crypto.createHash('sha256').update('IHazSekretKey', 'ascii').digest(),
    decipher  = crypto.createDecipher('aes-256-cbc', decodeKey);

  result = decipher.update(encoded);
  result += decipher.final();

  return result;
};

console.log(decrypto('3P86KyOrN2QJ/HFxxo3b7kAsxTgpDMMjROUPclsuXj0='));
console.log(decrypto('3P86KyOrN2QJ/HFxxo3b7kAsxTgpDMMjROUPclsuXj0=\n')

Второй скрипт дает:

nazar@xfce:~/tmp/tst$ ./js_decrypt 
Å'{ H£V)ÜB
Å'{ H£V)ÜB

Любая помощь будет очень признательна, так как мой единственный оставшийся вариант - утопиться в бочке [Джемерсона || Кирин Ичибан] (шучу)

PS есть аналогичный вопрос на SO здесь, который, к сожалению, не это не дало никакого вдохновения для моего случая.


person Nazar    schedule 02.07.2012    source источник
comment
Между ошибками node.js, касающимися использования base64 и неполной документацией, которая относится к вещам, которых нет в стабильной версии, я сдаюсь. Передайте бутылку, пожалуйста. Кстати, ваш origKey также кажется другим в рубине и узле, но это может быть потому, что я конвертирую в base64 для проверки и, по-видимому, есть ошибка. :-С   -  person Gerry    schedule 03.07.2012
comment
Коротко передаю тебе бутылку, @Gerry.... Я собираюсь попробовать еще раз.   -  person Nazar    schedule 03.07.2012


Ответы (1)


Важнейшей недостающей частью является IV, который требуется, когда шифрование/дешифрование должно выполняться через языковые границы, поскольку, по-видимому, шифровальщик сгенерирует случайный IV (или что-то в этом роде - до сих пор не понимаю, как Ruby расшифровывает строку без IV .... но тогда откуда мне знать....), если таковой не предусмотрено.

В следующих фрагментах показано, как зашифровать строку в Ruby и расшифровать в NodeJS.

#!/usr/bin/env ruby

require 'openssl'
require 'base64'
require 'openssl/cipher'
require 'openssl/digest'

aes = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
aes.encrypt
aes.key = Digest::SHA256.digest('IHazSekretKey') 
aes.iv  = '1234567890123456'

p Base64.encode64( aes.update('text to be encrypted') << aes.final )

Вышеприведенное печатает: "eiLbdhFSFrDqvUJmjbUgwD8REjBRoRWWwHHImmMLNZA=\n"

#!/usr/bin/env node

var crypto = require('crypto'); 

function decrypto(toDecryptStr) {
  var result,
    encoded   = new Buffer(toDecryptStr, 'base64'),
    decodeKey = crypto.createHash('sha256').update('IHazSekretKey', 'ascii').digest(),
    decipher  = crypto.createDecipheriv('aes-256-cbc', decodeKey, '1234567890123456');

  result = decipher.update(encoded);
  result += decipher.final();

  return result;
}

console.log(decrypto('eiLbdhFSFrDqvUJmjbUgwD8REjBRoRWWwHHImmMLNZA=\n'))

Сценарий JS теперь правильно расшифровывает строку.

Один неприятный побочный эффект заключается в том, что существующие зашифрованные данные должны быть расшифрованы, а затем повторно зашифрованы с IV, который затем используется в реализации расшифровки.

PITA, но, тем не менее, рабочее решение.

person Nazar    schedule 03.07.2012
comment
до сих пор не понимаю, как Ruby расшифровывает строку без IV › IV по умолчанию имеет значение null: ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/ Кстати, молодец. - person Gerry; 11.07.2012
comment
Ааа.. это объясняет :). Спасибо @Gerry. - person Nazar; 11.07.2012
comment
Пожалуйста. На самом деле я сначала думал, что это может быть проблема с IV, однако я не мог заставить его работать в своем тестировании, поэтому я решил, что это что-то другое. :) - person Gerry; 11.07.2012
comment
Эй, Назар, ты уверен, что твой скрипт работает успешно? Я только что столкнулся с этой ситуацией, когда данные шифруются в ruby, и я хочу расшифровать в узле, поэтому я следую вашему коду, но он застрял при расшифровке. - person Harshal_m_joshi; 21.01.2013
comment
@Harshal_m_joshi, да, это работает, и мы уже довольно давно используем его в производстве. Крайне важно, чтобы IV был идентичен между языковыми границами. ХТ и удачи. - person Nazar; 21.01.2013
comment
@nazar да, это работает со схемами aes-256-cbc. Я пытался с aes-128-cbc, но это не удалось. просто попробуйте зашифровать и расшифровать с помощью aes-128-cbc. извините, забыл упомянуть об этом (aes-128-cbc) в предыдущем комментарии. - person Harshal_m_joshi; 22.01.2013
comment
Есть ли способ получить его без IV? - person 7H3 IN5ID3R; 15.04.2017