我有两个用于使用AES加密和解密邮件的脚本。
此处encrypt.rb
:
require 'openssl'
require 'base64'
require 'digest'
KEY = 'sekrit_key'
MESSAGE = "My Name is Rabbit and I don't know anything!"
cipher = OpenSSL::Cipher::AES256.new(:CFB)
cipher.encrypt
cipher.key = KEY
# hexdigest the IV to make sure encode64 doesn't fuck up
iv = Digest::MD5.hexdigest(cipher.random_iv)
cipher.iv = iv
encrypted = cipher.update(secret_message)+cipher.final
puts Base64.urlsafe_encode64(iv+'|'+encrypted.encode)
...和decrypt.rb
:
require 'openssl'
require 'base64'
KEY = 'sekrit_key'
encrypted_message = STDIN.read.strip
parts = Base64.urlsafe_decode64(encrypted_message ).split('|')
iv = parts[0]
encrypted = parts[1]
decipher = OpenSSL::Cipher::AES256.new(:CFB)
decipher.decrypt
decipher.key = KEY
decipher.iv = iv
message = decipher.update(encrypted)+decipher.final
if message.eql?("My Name is Rabbit and I don't know anything!")
print '.'
else
puts
puts encrypted_message
puts message
end
当我现在连续运行两个脚本时,我的输出经常被切断!
$ while true; do ruby encrypt.rb | ruby decrypt.rb; done
....
YmZhNDg2ODJjNGZiOGIzZTcyMzAwYzMxZWUwNWI0Y2V8w2aJk930EL3gh3rfQsd2B3xZKy5wjoCzlZoYHBgmv6m51ZwAWQHGtCJoNRg=
My Name is Rabbi
..
YjMwNDQxOGRjMjg4NGEzOThmM2IwNGFiZDBiZTQxZGZ8OfLyjGQGKV3PPUpCvfL08IDuk7M7d3w7fj6F5Rql94jkRdwaCuuMfedqtFk=
My Name is Rabbit and
..
OWUxYzFlZWU5MTc4NGZjYWYxYzZiOGEwOTBjOGMxYzJ8g7I4X_Dt6K9ufByMhLBGlpoYCv8vlR0lTBqP-zS647tmmFh81rXdR8T-UkM=
My Name i
....
# and so on
为什么我的这么多邮件被切断了?
更新:在encrypt.rb
中使用固定的IV(例如,用cipher.random_iv
代替KEY
)而不是随机生成时,问题不会发生
答案 0 :(得分:1)
问题源于您将二进制数据视为字符串这一事实。 iv
以及encrypted.encode
都是二进制文件,您将它们与“|”连接起来(一个字符串)。 iv
以及消息都可能包含管道符,这会在拆分时导致问题。一般来说,最好将两个部分分别作为基础。
这是工作代码:
encrypt.rb
require 'openssl'
require 'base64'
require 'digest'
KEY = 'sekrit_key123456' * 2
MESSAGE = "My Name is Rabbit and I don't know anything!"
cipher = OpenSSL::Cipher::AES256.new(:CFB)
cipher.encrypt
cipher.key = KEY
iv = cipher.random_iv
encrypted = cipher.update(MESSAGE)+cipher.final
puts Base64.strict_encode64(iv)+'|'+Base64.strict_encode64(encrypted.encode)
decrypt.rb
require 'openssl'
require 'base64'
KEY = 'sekrit_key123456' * 2 # key needs to be the right length
encrypted_message = STDIN.read.strip
parts = encrypted_message.split('|')
iv = Base64.strict_decode64(parts[0])
encrypted = Base64.strict_decode64(parts[1])
decipher = OpenSSL::Cipher::AES256.new(:CFB)
decipher.decrypt
decipher.key = KEY
decipher.iv = iv
message = decipher.update(encrypted)+decipher.final
if message.eql?("My Name is Rabbit and I don't know anything!")
print '.'
else
puts
puts encrypted_message
puts message
end
另请注意random_iv
已将iv
分配给密码,因此您不需要(请参阅http://apidock.com/ruby/v1_9_3_125/OpenSSL/Cipher/random_iv下的来源)。