Я использую свою собственную библиотеку ssl / tls для целей обучения. В эти дни, когда я отправляю зашифрованное сообщение на сервер, я получаю предупреждение «плохой макинтош». Сегодня я использую запись этого вопроса для отладки своего кода.
Вот где произошла странная вещь. Я использую его server_random, client_random и master-secret для генерации client_write_key и client_write_iv. Тогда я получаю тот же вывод, что и его. Однако когда я использую client_wrtie_key и client_write_iv для расшифровки сообщения «GET / HTTP / 1.0 \ n», я получаю следующий вывод:
Q▒W▒ ▒7▒3▒▒▒
Это так отличается от правильного сообщения! Весь мой вывод отладки:
C:/Users/ayanamists/.babun/cygwin/home/ayanamists/my_ssl_in_ruby/encrypt_handler/aes_gcm_handler.rb:87:in `final': OpenSSL::Cipher::CipherError
from C:/Users/ayanamists/.babun/cygwin/home/ayanamists/my_ssl_in_ruby/encrypt_handler/aes_gcm_handler.rb:87:in `recv_decrypt'
from decrypt.rb:72:in `<main>'
client write key is
4b 11 9d fb fc 93 0a be 13 00 30 bd 53 c3 bf 78
nonce is
20 29 ca e2 c9 1d e0 05 e2 ae 50 a8
what to be decrypt:
a5 7a be e5 5c 18 36 67 b1 36 34 3f ee f4 a3 87 cb 7c f8 30 30
the tag is
a4 7e 23 0a f2 68 37 8c 4f 33 c8 b5 ba b3 d2 6d
the additional data is
00 00 00 00 00 00 00 01 17 03 03 00 00 15
decrypter is
OpenSSL::Cipher::AES
Q▒W▒ ▒7▒3▒▒▒
output is
bd 8c e8 87 b7 ab c6 f7 eb 31 fd cb 65 4c d4 a9 16 ae 1b ca da
the correct is
47 45 54 20 2f 20 48 54 54 50 2f 31 2e 30 0a
Вы видите, что мой ключ и одноразовый номер ничем не отличаются от его ключа и одноразового номера, но почему результат неверен? Код:
require_relative 'encrypt_message_handler'
require 'pp'
class AES_CGM_Handler
include EncryptMessageHandler
attr_accessor :send_cipher, :recv_cipher, :send_implicit, :recv_implicit,
:send_seq_num, :recv_seq_num
def initialize(server_random, client_random, certificate = '', length = 0,
usage = 'client', version_major = 0x03, version_minor = 0x03)
if block_given?
@master = yield
@version = [0x03, 0x03]
else
super(server_random, client_random, certificate)
end
# the nonce of AES_GCM is defined by:
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# + 0 1 2 3 | 0 1 2 3 4 5 6 7 +
# + salt | nonce_explicit +
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
# salt is server_write_iv or client_write_iv, so you need 4 * 2
# and length need to /8(bit->byte) and * 2(both server and client), so it's length/4
key_block = (length/4 + 4 * 2).tls_prf(@master, "key expansion", server_random + client_random)
arr = key_block.unpack "a#{length/8}a#{length/8}a4a4"
client_write_key = arr[0]
server_write_key = arr[1]
client_write_iv = arr[2]
server_write_iv = arr[3]
@send_cipher = OpenSSL::Cipher::AES.new(length, :GCM).encrypt
@recv_cipher = OpenSSL::Cipher::AES.new(length, :GCM).decrypt
if usage == 'client'
@send_cipher.key = client_write_key
@send_implicit = client_write_iv
@recv_cipher.key = server_write_key
@recv_implicit = server_write_iv
puts "server write key is #{server_write_key.to_hex}"
elsif usage == 'server'
@send_cipher.key = server_write_key
@send_implicit = server_write_iv
@recv_cipher.key = client_write_key
@recv_implicit = client_write_iv
puts "client write key is\n #{client_write_key.to_hex}"
else
raise "AES_GCM_HANDLER: BAD_ARGUMENT"
end
@send_seq_num = 0
@recv_seq_num = 0
end
def send_encrypt(type = 22, seqence = '')
nonce_explicit = OpenSSL::Random.random_bytes(8)
nonce = @send_implicit + nonce_explicit
@send_cipher.iv = nonce
length = seqence.length
#the handle of seq_num may be wrong
@send_cipher.auth_data = [0, @send_seq_num,
type, @version[0], @version[1], 0 ,length].pack("NNCCCCn")
encrypt = @send_cipher.update(seqence) + @send_cipher.final
encrypt = encrypt + @send_cipher.auth_tag
return encrypt
end
def recv_decrypt(type = 22, sequence = '', seq_num = 0)
if seq_num != 0
@recv_seq_num = seq_num
end
template = 'a8a*'
arr = sequence.unpack(template)
nonce_explicit = arr[0]
length = sequence.length - 8 - 16
sequence = arr[1]
encrypted = sequence[0, sequence.length - 16]
@recv_cipher.auth_tag = sequence[sequence.length - 16, sequence.length]
@recv_cipher.iv = @recv_implicit + nonce_explicit
puts "nonce is\n #{(@recv_implicit + nonce_explicit).to_hex}"
puts "what to be decrypt: \n #{encrypted.to_hex}"
puts "the tag is \n #{sequence[sequence.length - 16, sequence.length].to_hex}"
@recv_cipher.auth_data =
[0, @recv_seq_num, type ,@version[0], @version[1], 0 ,length].pack("NNCCCCn")
puts "the additional data is\n #{([0, @recv_seq_num, type ,@version[0], @version[1], 0 ,length].pack("NNCCCCn")).to_hex }"
puts "decrypter is\n #{@recv_cipher.class}"
puts @recv_cipher.update(encrypted)
puts "output is\n #{@recv_cipher.update(encrypted).to_hex}"
puts "the correct is\n #{"GET / HTTP/1.0\n".to_hex}"
decrypt = @recv_cipher.update(encrypted) + @recv_cipher.final
return decrypt
end
end
Пожалуйста, помогите мне решить эту проблему, я буду очень признателен!