2017-01-13 2 views
6

Итак, у меня есть методы шифрования и дешифрования на ruby, и они работают отлично рубином. Я выполнил ответ от this question (How to decrypt message with CryptoJS AES. I have a working Ruby example), но он возвращает пустую строку.CryptoJS не работает с IV и ключом, но работает в Ruby

рубин Код

def load_vars 
     @key = "2e35f242a46d67eeb74aabc37d5e5d05" 
     @algorithm = "aes-128-cbc" 
    end 

    def encryption(data) 
     begin 
      key = @key 
      aes = OpenSSL::Cipher.new(@algorithm) 
      aes.encrypt() 
      aes.key = key 
      iv_value = aes.random_iv 
      aes.iv = iv_value 
      crypt = aes.update(data) + aes.final() 
      crypt_string = (Base64.encode64(iv_value + crypt)) 
      return crypt_string 
     end 
    end 

    def decryption(data) 
     begin 
      key = @key 
      aes = OpenSSL::Cipher.new(@algorithm) 
      iv_value = Base64.decode64(data)[0...16] 
      data_value = Base64.decode64(data)[16..-1] 
      aes.decrypt 
      aes.key = @key 
      aes.iv = iv_value 
      results = aes.update(data_value) + aes.final 
      return results 
     end 
    end 

HTML JSFIDDLE

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core-min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script> 

<script>   
    data = "wlkAKa4ps+Xizx4VIdUSp43yfQvOmt9FNlVTQ1ANsCU=\n"; // The data received from the ruby encryption method 
    key = "2e35f242a46d67eeb74aabc37d5e5d05"; 

    // Decode the base64 data so we can separate iv and crypt text. 
    var rawData = atob(data); 
    var iv = rawData.substring(0,16); 
    var crypttext = rawData.substring(16); 

    // Decrypt... 
    var plaintextArray = CryptoJS.AES.decrypt(
     { ciphertext: CryptoJS.enc.Latin1.parse(crypttext) }, 
     CryptoJS.enc.Hex.parse(key), 
     { iv: CryptoJS.enc.Latin1.parse(iv) } 
    ); 

    console.log(CryptoJS.enc.Latin1.stringify(plaintextArray)); 
</script> 
+1

Ваш код javascript верен, так как он работает со значением 'data' ссылки, поэтому проблема находится в коде Ruby. Я думаю, что проблема заключается в параметре 'key'. При шифровании вы напрямую передаете шестнадцатеричный код, но вы должны предоставить декодированное значение. Не могли бы вы попытаться использовать 'aes.key = key.scan (/../). Collect {| x | x.hex} .pack ('c *') '(извлечен из вашей ссылки). Боюсь, я не могу быть более конкретным, потому что я не знаю Ruby. – pedrofb

+0

Можете ли вы предоставить исходные (незашифрованные) данные, которые генерировали зашифрованные данные: 'data =" wlkAKa4ps + Xizx4VIdUSp43yfQvOmt9FNlVTQ1ANsCU = \ n ";'? Имея исходные данные, мы можем реализовать метод шифрования, который его генерирует и оттуда отлаживает. – peiiion

+1

@SuthanBala, вы пытались с кодом, который я сделал, чтобы преобразовать ключ HEX в байты? – pedrofb

ответ

4

Проблема заключается в том, что Руби ожидает, что ключ, чтобы быть в двоичном формате, а не шестигранным. Так что вам нужно сделать, это:

#!/usr/bin/env ruby 

require 'openssl' 
require 'base64' 

data = "When in Rome do as the Romans do" 
key = "2e35f242a46d67eeb74aabc37d5e5d05" 
aes = OpenSSL::Cipher.new("aes-128-cbc") 
aes.encrypt() 
aes.key = key.scan(/../).collect{|x| x.hex}.pack("c*") 
iv_value = aes.random_iv 
aes.iv = iv_value 
crypt = aes.update(data) + aes.final() 
crypt_string = (Base64.encode64(iv_value + crypt)) 
puts crypt_string 

Для меня, который печатает

mdnLCY6MdwEONY1AxR/vjVKMssB+yrPsz4QMjfl6fDXxv68E0EUxtAqa4VUo 
fTkjq2Hqyd48UV3dyWmEbwXw5Q== 

Если я положил, что в ваш HTML-файл (без изменения кода), я получаю обратно исходное сообщение:

<!DOCTYPE html> 
<html> 
<head> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/components/core-min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script> 

<script>   
data = "mdnLCY6MdwEONY1AxR/vjVKMssB+yrPsz4QMjfl6fDXxv68E0EUxtAqa4VUo\nfTkjq2Hqyd48UV3dyWmEbwXw5Q==\n"; 
key = "2e35f242a46d67eeb74aabc37d5e5d05"; 

var rawData = atob(data); 
var iv = rawData.substring(0,16); 
var crypttext = rawData.substring(16); 

// Decrypt... 
var plaintextArray = CryptoJS.AES.decrypt(
    { ciphertext: CryptoJS.enc.Latin1.parse(crypttext) }, 
    CryptoJS.enc.Hex.parse(key), 
    { iv: CryptoJS.enc.Latin1.parse(iv) } 
); 

console.log(plaintextArray); 
console.log(CryptoJS.enc.Latin1.stringify(plaintextArray)); 
</script> 
</head> 
<body> 
</body> 
</html> 

Так что проблема в том, что ваш код Ruby продуцировал cyphertext. Исправьте ключ и заново зашифруйте, и JS должен начать работать.

+1

Это не то же самое, что и мой комментарий? – pedrofb

+0

Это работает на JavaScript сейчас, спасибо. Но это нарушает метод дешифрования в рубине, который работал раньше. –

+0

Чтобы исправить расшифровку Ruby, вы должны изменить, как вы там устанавливаете ключ (чтобы он соответствовал стороне шифрования). –

Смежные вопросы