Мне нужно внедрить платежный шлюз в 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>'
По общему признанию, я не очень хорошо разбираюсь в этом криптовалюте, но нахожусь у стены и у меня нет времени (несмотря на интерес), чтобы узнать больше.