dongxin1999 2017-01-19 00:22
浏览 132
已采纳

Go加密与使用相同密钥和iv的Ruby加密不同

I have the following Ruby code:

require 'base64'
require 'openssl'

data = '503666666'

key = '4768c01c4f598828ef80d9982d95f888fb952c5b12189c002123e87f751e3e82'

nonce = '4eFi6Q3PX1478767
'
nonce = Base64.decode64(nonce)

c = OpenSSL::Cipher.new('aes-256-gcm')
c.encrypt
c.key = key
c.iv = nonce

result = c.update(data) + c.final
tag = c.auth_tag

puts Base64.encode64(result + tag) # => J3AVfNG84bz2UuXcfre7LVjSbMpX9XBq6g==

that I'm trying to replicate in Golang. Here's what I have so far:

package main

import (
    "fmt"
    "crypto/aes"
    "crypto/cipher"
    "encoding/base64"
    "encoding/hex"
)

func main() {
    data := []byte("503666666")

    key, err := hex.DecodeString(`4768c01c4f598828ef80d9982d95f888fb952c5b12189c002123e87f751e3e82`)
    if err != nil {
        panic(err)
    }

    nonceB64 := "4eFi6Q3PX1478767
"
    nonce, err := base64.StdEncoding.DecodeString(nonceB64)
    if err != nil {
        panic(err)
    }

    block, err := aes.NewCipher(key)
    if err != nil {
        panic(err.Error())
    }

    aesgcm, err := cipher.NewGCM(block)
    if err != nil {
        panic(err.Error())
    }

    ciphertext := aesgcm.Seal(nil, nonce, data, nil)
    fmt.Printf("%s
", base64.StdEncoding.EncodeToString(ciphertext))
}

However the outcome from the Go version is:

+S52HGbLV1xp+GnF0v8VNOqc5J2GY2+SqA==

vs.

J3AVfNG84bz2UuXcfre7LVjSbMpX9XBq6g==

Why am I getting different results?

Thanks,

  • 写回答

1条回答 默认 最新

  • duan0424 2017-01-19 00:31
    关注

    The AES 256 cipher requires a 32 byte key. The Ruby code is setting the key to a 64 byte string consisting of hexadecimal digits. OpenSSL is truncating the string to 32 bytes before use (change key to '4768c01c4f598828ef80d9982d95f888' in the Ruby code and you'll get the same output).

    The Go code however is hex decoding the key before use, converting the 64 hexadecimal digits to the 32 bytes required for the key.

    If you want to change the Go code so that it matches the Ruby result, then you'll need to truncate the key and remove the hex decoding step:

    key := []byte("4768c01c4f598828ef80d9982d95f888")
    

    However, I'd argue that the key handling in the Go version of the code is better. If you want to change the Ruby version to match the Go version, you can hex decode the key before use:

    key = [key].pack('H*')
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 程序不包含适用于入口点的静态Main方法
  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记