当前位置: 首页 > 知识库问答 >
问题:

在ruby中使用OpenSSL解密aes-128-gcm tls包时的一个奇怪现象

宋英杰
2023-03-14

为了学习目的,我暗示了我自己的SSL/TLS库。这些天,当我把加密的消息发送到服务器时,我会收到一个“坏Mac”警报。今天我用这个问题的记录来调试我的代码。

这就是奇怪的事情发生的地方。我使用他的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

请帮助我解决这个问题,我将不胜感激!

共有1个答案

佘缪文
2023-03-14

我终于解决了这个问题!如果有人想使用这个测试向量,不要忘记在zlib压缩时添加“789c”

 类似资料:
  • 我不知道我做错了什么,在这里试图用给定的密钥解密一串十六进制值,使用ruby的OpenSSL密码AES-128-CTR。 我正在使用gem hex_字符串将我的十六进制转换为字节 我知道我遗漏了一些小东西,因为我有类似的代码实现AES-128-CBC。我是否需要一个计数器,为密文中128字节的每一块递增IV?

  • 执行此操作后,当运行/opt/bin/openssl密码时,列表中看不到aes-128-ccm密码: 但如果运行/opt/bin/openssl enc-help 2>&1,我会看到“-aes-128-ccm”: 我使用命令(在前面提到的文章中给出)重新安装了ruby 2.0.0p0和rvm。然后运行。返回以下错误: 我的问题是如何在Ruby中添加对AES-128-CCM的支持/我在这里做错了什么

  • 我只想用这3种模式测试openSSL中的AES:128192和256密钥长度,但我解密的文本与我的输入不同,我不知道为什么。此外,当我传递一个巨大的输入长度(比如1024字节)时,我的程序显示。。。我的意见总是一样的,但这并不重要,至少现在是这样。代码如下: 编辑: 当我将输出大小更改为而不是时,我得到了结果: 那么,是否有可能存在Outpus大小和IV大小的问题?它们应该有什么尺寸(AES-CB

  • 最近,我终于(在stackoverflow的用户@WhozCraig的帮助下)开始在CBC模式下使用AES。现在,我想用AES IGE做同样的事情。我看了并尝试构建自己的测试。但是,我再次遇到了输入和输出大小合适的问题。其他一切都很好,因为我从以前的代码中复制了它:AES(aes-cbc-128、aes-cbc-192、aes-cbc-256)使用openssl C进行加密/解密。 现在,当我传递

  • 我只需要通过代码加密AES CBC 128位模式的字符串。我使用openssl库完成了这项工作,但无法获得正确的输出。 到目前为止,我已经完成了。 我的十六进制输出是:B0 15 751B50 80 D4 FF 81 68 146BB71B95 99 37 38 但正确的输出是:< code > 73 5C 04 F9 57 18 43 7C EE 68 27 59 2B 41 A8 DA (通过

  • 我正在尝试使用带有相同密钥和 iv 的 AES 加密相同的文本。我使用 bash 方法和 ruby 的 openssl stdlib,并对加密结果进行 b64 编码。但结果不同!我试图理解为什么。这是我所做的: 红宝石(1.9.3-p448) 砰砰�� -iv参数设置为上面计算的iv_hex值。 ========================================= 我仔细检查了静脉注