从密码 aes 256 GCM 戈朗中提取标签

我在Ruby中有加密和解密,并尝试用Go重写。我一步一步地尝试,所以从Ruby中的加密开始,并尝试在go中解密,这是有效的。但是当我尝试在Go中写入加密并在Ruby中解密时。当我尝试提取标签时,我遇到了困难,我解释了为什么我需要提取auth标签的原因


加密 在红宝石中


plaintext = "Foo bar"

cipher = OpenSSL::Cipher.new('aes-256-gcm')

cipher.encrypt

cipher.iv = iv # string 12 len

cipher.key = key # string 32 len

cipher.auth_data = # string 12 len

cipherText = cipher.update(JSON.generate({value: plaintext})) + cipher.final

authTag = cipher.auth_tag

hexString = (iv + cipherText + authTag).unpack('H*').first

我尝试连接一个初始向量,一个密文和身份验证标签,所以在解密之前,我可以提取它们,特别是身份验证标签,因为我需要在Ruby中调用Cipher#final之前设置它


auth_tag


必须在调用密码#解密,密码#key=和密码#iv=之后,但在调用密码#final之前设置标记。执行所有解密后,将在调用密码#final时自动验证标记


这是高浪中的函数加密


ciphertext := aesgcm.Seal(nil, []byte(iv), []byte(plaintext), []byte(authData))

src := iv + string(ciphertext) // + try to add authentication tag here

fmt.Printf(hex.EncodeToString([]byte(src)))

如何提取身份验证标签并将其与iv和密文连接起来,以便我可以在ruby中使用解密功能进行解密


raw_data = [hexString].pack('H*')

cipher_text = raw_data.slice(12, raw_data.length - 28)

auth_tag = raw_data.slice(raw_data.length - 16, 16)


cipher = OpenSSL::Cipher.new('aes-256-gcm').decrypt

cipher.iv = iv # string 12 len

cipher.key = key # string 32 len

cipher.auth_data = # string 12 len

cipher.auth_tag = auth_tag

JSON.parse(cipher.update(cipher_text) + cipher.final)

我希望能够在Go中进行加密,并尝试在Ruby中解密。


qq_遁去的一_1
浏览 229回答 2
2回答

蓝山帝景

您希望加密流如下所示:func encrypt(in []byte, key []byte) (out []byte, err error) {&nbsp; &nbsp; c, err := aes.NewCipher(key)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }&nbsp; &nbsp; gcm, err := cipher.NewGCM(c)&nbsp; &nbsp; if err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }&nbsp; &nbsp; nonce := make([]byte, gcm.NonceSize())&nbsp; &nbsp; if _, err = io.ReadFull(rand.Reader, nonce); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; return&nbsp; &nbsp; }&nbsp; &nbsp; out = gcm.Seal(nonce, nonce, in, nil) // include the nonce in the preable of 'out'&nbsp; &nbsp; return}根据 aes,您的输入长度应为 16、24 或 32 个字节。新密码文档。key上述函数中的加密字节将包括前缀(长度为 16、24 或 32 个字节) - 因此可以在解密阶段轻松提取,如下所示:outnonce// `in` here is ciphertextnonce, ciphertext := in[:ns], in[ns:]其中计算如下:nsc, err := aes.NewCipher(key)if err != nil {&nbsp; &nbsp; return}gcm, err := cipher.NewGCM(c)if err != nil {&nbsp; &nbsp; return}ns := gcm.NonceSize()if len(in) < ns {&nbsp; &nbsp; err = fmt.Errorf("missing nonce - input shorter than %d bytes", ns)&nbsp; &nbsp; return}编辑:如果您使用默认密码设置进行加密(见上文):gogcm,&nbsp;err&nbsp;:=&nbsp;cipher.NewGCM(c)从源中,标记字节大小将为 。16注意:如果是密码。使用新GCM标签大小&nbsp;- 然后大小显然会有所不同(基本上在字节之间的任何地方)1216因此,让我们假设标签大小为 ,掌握此知识,并且知道完整的有效负载安排是:16IV/nonce&nbsp;+&nbsp;raw_ciphertext&nbsp;+&nbsp;auth_tag解密的一侧是有效载荷的最后16个字节;并且raw_ciphertext是 up 之后的所有字节,直到 开始的位置。auth_tagRubyIV/nonceauth_tag

海绵宝宝撒

aesgcm.Seal自动将 GCM 标记附加到密文的末尾。您可以在源代码中看到它:&nbsp; &nbsp; var tag [gcmTagSize]byte&nbsp; &nbsp; g.auth(tag[:], out[:len(plaintext)], data, &tagMask)&nbsp; &nbsp; copy(out[len(plaintext):], tag[:])&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// <---------------- here所以你已经完成了,你不需要其他任何东西。 已返回末尾附加了 auth 标记的密文。gcm.Seal同样,您也不需要提取 的 auth 标记,它也会自动执行此操作:gcm.Open&nbsp; &nbsp; tag := ciphertext[len(ciphertext)-g.tagSize:]&nbsp; &nbsp; &nbsp; &nbsp; // <---------------- here&nbsp; &nbsp; ciphertext = ciphertext[:len(ciphertext)-g.tagSize]因此,在解密过程中,您所要做的就是提取IV(nonce)并将其余部分作为密文传递。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go