Как использовать Ruby для расшифровки открытого текста, который был зашифрован с помощью утилиты командной строки openssl с использованием пароля и без соли? - PullRequest
0 голосов
/ 10 июля 2020

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

echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey

Это возвращает:

ryW2

Как я могу расшифровать это значение с помощью Ruby?

Ответы [ 3 ]

1 голос
/ 14 июля 2020

Вот команда, которую вам нужно будет ввести, чтобы зашифровать строку foo в некоторый зашифрованный текст:

echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey -p

И это возвращает:

key=610A2EE688CDA9E724885E23CD2CFDEE
ryW2

ryW2 это ваш зашифрованный текст в кодировке base64.

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

-p требуется, потому что OpenSSL использует внутреннюю функцию EVP_BytesToKey для преобразования парольную фразу для ключа, и для этого не существует эквивалентного Ruby метода. Соответственно, вам придется использовать это значение ключа непосредственно в Ruby при шифровании или дешифровании вместо ключевой фразы.

Расшифровка так же проста:

echo "ryW2" | openssl enc -d -base64 -rc4 -nosalt -pass pass:secretkey

Это возвращает :

foo

Учитывая все это, вот как вы могли бы зашифровать эту строку, используя Ruby, чтобы получить то же значение:

require 'openssl'
require 'base64'

plaintext = 'foo'
cipher = OpenSSL::Cipher.new('rc4')
cipher.encrypt
# Use the key that was generated by EVP_BytesToKey
key = '610A2EE688CDA9E724885E23CD2CFDEE'
# Convert the key to a byte string
key_bytes = key.scan(/../).map { |x| x.hex.chr }.join
cipher.key = key_bytes
ciphertext = cipher.update(plaintext) + cipher.final
base64 = Base64.strict_encode64(ciphertext)

Это возвращает то же значение, что и OpenSSL на командная строка:

ryW2

Расшифровка довольно проста:

decipher = OpenSSL::Cipher.new('rc4')
decipher.decrypt
decipher.key = key_bytes
decrypted = decipher.update(ciphertext) + decipher.final

Это возвращает исходный открытый текст:

foo

В конечном итоге шифрование и дешифрование довольно просты, поскольку пока вы знаете, что EVP_BytesToKey вернет при заданном pass. Вы можете узнать больше о EVP_BytesToKey здесь:

0 голосов
/ 21 июля 2020

Мне не понравилось, что в Ruby нет встроенного способа сделать это. Другой мой ответ на этот вопрос - это функциональный обходной путь, но он требует некоторых трудоемких шагов, от которых я не без ума. Итак, я написал гем под названием evp_bytes_to_key , который сделает это за вас!

Сначала установите драгоценный камень:

gem install evp_bytes_to_key

Затем сгенерируйте свой зашифрованный текст:

echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey

Это возвращает:

ryW2

Затем расшифруйте его в Ruby:

require 'evp_bytes_to_key'
require 'openssl'
require 'base64'

decipher = OpenSSL::Cipher.new('rc4')
decipher.decrypt
decipher.key = EvpBytesToKey::Key.new('secretkey', nil, 128, 0).key
ciphertext = Base64.strict_decode64('ryW2')
plaintext = decipher.update(ciphertext) + decipher.final

Это возвращает исходный открытый текст:

foo

Подробнее примеры использования этого драгоценного камня можно найти в README .

0 голосов
/ 15 июля 2020

Наконец, со ссылкой на выше в Ruby

Кодировать

def encrypt(str, key)
  cipher = OpenSSL::Cipher.new('RC4')
  cipher.key = OpenSSL::Digest.digest('md5', key)
  cipher.decrypt
  Base64.encode64(cipher.update(str) + cipher.final)
end

encrypt('This is Test', 'Test')
=> "JGmpM+ewGA79qaZH\n"

Декодировать

def decrypt(encrypted_string, key)
  decipher = OpenSSL::Cipher.new('RC4')
  decipher.key = OpenSSL::Digest.digest('md5', key)
  decipher.decrypt
  decipher.update(Base64.decode64(encrypted_string)) + decipher.final
end

decrypt("JGmpM+ewGA79qaZH\n", "Test")
=> "This is Test"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...