Go encryption differs from Ruby encryption using same key and iv

huangapple go评论70阅读模式
英文:

Go encryption differs from Ruby encryption using same key and iv

问题

我有以下的Ruby代码:

require 'base64'
require 'openssl'

data = '503666666'

key = '4768c01c4f598828ef80d9982d95f888fb952c5b12189c002123e87f751e3e82'

nonce = '4eFi6Q3PX1478767\n'
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==\n

我想在Golang中复制这段代码。以下是我目前的代码:

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\n"
	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\n", base64.StdEncoding.EncodeToString(ciphertext))
}

然而,Go版本的输出结果是:

+S52HGbLV1xp+GnF0v8VNOqc5J2GY2+SqA==

而不是:

J3AVfNG84bz2UuXcfre7LVjSbMpX9XBq6g==\n

为什么会得到不同的结果?

谢谢。

英文:

I have the following Ruby code:

require 'base64'
require 'openssl'

data = '503666666'

key = '4768c01c4f598828ef80d9982d95f888fb952c5b12189c002123e87f751e3e82'

nonce = '4eFi6Q3PX1478767\n'
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==\n

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\n"
	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\n", base64.StdEncoding.EncodeToString(ciphertext))
}

However the outcome from the Go version is:

> +S52HGbLV1xp+GnF0v8VNOqc5J2GY2+SqA==

vs.

> J3AVfNG84bz2UuXcfre7LVjSbMpX9XBq6g==\n

Why am I getting different results?

Thanks,

答案1

得分: 5

AES 256密码需要一个32字节的密钥。Ruby代码将密钥设置为由十六进制数字组成的64字节字符串。在使用之前,OpenSSL会将字符串截断为32字节(将Ruby代码中的key更改为'4768c01c4f598828ef80d9982d95f888',将得到相同的输出)。

然而,Go代码在使用之前会对密钥进行十六进制解码,将64个十六进制数字转换为所需的32字节密钥。

如果你想要修改Go代码以使其与Ruby的结果相匹配,那么你需要截断密钥并删除十六进制解码步骤:

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

然而,我认为Go版本的密钥处理更好。如果你想要将Ruby版本修改为与Go版本相匹配,你可以在使用之前对密钥进行十六进制解码:

key = [key].pack('H*')
英文:

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*')

huangapple
  • 本文由 发表于 2017年1月19日 08:22:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/41731748.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定