Расшифровать строку с помощью цепочки блоков шифрования AES в Rails - PullRequest
3 голосов
/ 22 декабря 2011

Мне нужно внедрить платежный шлюз в Rails, с которым я раньше не работал или не видел (Payp Westpac в Австралии, если кому-то интересно).

Их документация неплохая, и система довольно логичная, настолько, что до сих пор она была довольно безболезненной (чудо для интеграции платежей).

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

Вот руководство Westpac:

Параметры шифруются с использованием AES с цепочкой блоков шифрования с использованием PCKS-5. Перетяжка. Алгоритм дешифрования должен быть инициализирован 16-байтовым, заполненным нулями вектор инициализации и должен использовать ваш ключ шифрования (его можно найти на странице безопасности в настройках PayWay Net Shopping Cart).

Перед расшифровкой параметры, переданные с перенаправлением, будут выглядеть следующим образом:

  EncryptedParameters=QzFtdn0%2B66KJV5L8ihbr6ofdmrkEQwqMXI3ayF7UpVlRheR7r5fA6
  IqBszeKFoGSyR7c7J4YsXgaOergu5SWD%2FvL%2FzPSrZER9BS7mZGckriBrhYt%2FKMAbTSS8F
  XR72gWJZsul9aGyGbFripp7XxE9NQHVMWCko0NlpWe7oZ0RBIgNpIZ3JojAfX7b1j%2F5ACJ79S
  VeOIK80layBwCmIPOpB%2B%2BNI6krE0wekvkkLKF7CXilj5qITvmv%2FpMqwVDchv%2FUNMfCi
  4uUA4igHGhaZDQcV8U%2BcYRO8dv%2FnqVbAjkNwBqxqN3UPNFz0Tt76%2BP7H48PDpU23c61eM
  7mx%2FZh%2Few5Pd0WkiCwZVkSZoov97BWdnMIw5tOAiqHvAR3%2BnfmGsx

У Westpac нет демоверсий Rails, но у них есть PHP. Вот демоверсия PHP:

function decrypt_parameters( $base64Key, $encryptedParametersText, $signatureText )
{
    $key = base64_decode( $base64Key );
    $iv = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
    $td = mcrypt_module_open('rijndael-128', '', 'cbc', '');

    // Decrypt the parameter text
    mcrypt_generic_init($td, $key, $iv);
    $parametersText = mdecrypt_generic($td, base64_decode( $encryptedParametersText ) );
    $parametersText = pkcs5_unpad( $parametersText );
    mcrypt_generic_deinit($td);
}

Вот что я попробовал в Rails:

def Crypto.decrypt(encrypted_data, key, iv, cipher_type)
    aes = OpenSSL::Cipher::Cipher.new(cipher_type)
    aes.decrypt
    aes.key = key
    aes.iv = iv if iv != nil
    aes.update(encrypted_data) + aes.final  
end

iv = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
key = Base64.decode64("mysecretkey")
data = Base64.decode64("QzFtdn0%2B66KJV5L8ihbr6ofdmrkEQwqMXI3ayF7UpVlRheR7r5fA6
     IqBszeKFoGSyR7c7J4YsXgaOergu5SWD%2FvL%2FzPSrZER9BS7mZGckriBrhYt%2FKMAbTSS8F
     XR72gWJZsul9aGyGbFripp7XxE9NQHVMWCko0NlpWe7oZ0RBIgNpIZ3JojAfX7b1j%2F5ACJ79S
     VeOIK80layBwCmIPOpB%2B%2BNI6krE0wekvkkLKF7CXilj5qITvmv%2FpMqwVDchv%2FUNMfCi
     4uUA4igHGhaZDQcV8U%2BcYRO8dv%2FnqVbAjkNwBqxqN3UPNFz0Tt76%2BP7H48PDpU23c61eM
     7mx%2FZh%2Few5Pd0WkiCwZVkSZoov97BWdnMIw5tOAiqHvAR3%2BnfmGsx")

cleartext = Crypto.decrypt(data, key, iv, "AES-128-CBC")

И я просто передаю тот же вектор инициализации, что и в PHP, хотя я не уверен, что это правильно для Rails.

В любом случае ключ предоставляется и легко декодируется Base64, как и Зашифрованные параметры. В конце дня я получаю эту ошибку:

cipher.rb:21:in `final': wrong final block length (OpenSSL::Cipher::CipherError)
from cipher.rb:21:in `decrypt'
from cipher.rb:29:in `<main>'

По общему признанию, я не очень хорошо разбираюсь в этом криптовалюте, но нахожусь у стены и у меня нет времени (несмотря на интерес), чтобы узнать больше.

1 Ответ

8 голосов
/ 24 декабря 2011

Проблема заключалась в том, что входные данные были дополнительно "URI-escape-экранированными", а декодер ru64 base64 не "заботился" о недопустимом вводе base64 (% не является base64-разрядным), поэтому ошибка не возникала ,

Решение состояло в том, чтобы "удалить" кодировку URI с помощью URI.unescape:

require 'uri'

data = Base64.decode64(
    URI.unescape("QzFtdn0%2B66 ... Iw5tOAiqHvAR3%2BnfmGsx"))

Конечно, если входные данные получены из параметра GET / POST, входные данные, скорее всего, уже «не экранированы» вашим веб-стеком - просто как предостережение (double unescape может вызвать проблемы, если во входных данных появится знак процента %).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...