为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 golang 中匹配 phpseclib1 Rijndael.php CBC AES 加密?

如何在 golang 中匹配 phpseclib1 Rijndael.php CBC AES 加密?

Go
慕桂英3389331 2022-03-07 16:30:44
我像这样加密:  plaintextstr := "0000000000000thankustackoverflow"  plaintext := []byte(plaintextstr)  key := []byte("abcdefghijklmnop")  block, _ := aes.NewCipher(key)  ciphertext := make([]byte, aes.BlockSize+len(plaintext))  iv := ciphertext[:aes.BlockSize]  mode := cipher.NewCBCEncrypter(block, iv)  mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)  fmt.Printf("%x\n", ciphertext)输出是:000000000000000000000000000000000d77aa6646bb541808ed23c88d4b06d30f42b01d6e806a02b29086bc82892334f但是用 PHP 编写的此代码的另一个版本的输出是:d77aa6646bb541808ed23c88d4b06d30f42b01d6e806a02b29086bc82892334fbf21ea861abbc3d72e44731978bb76c2请注意,00000000000000000000000000000000 是末尾缺失数据的确切长度。它是 32,即原始纯文本字符串的大小。知道如何在 golang 中左移所有内容并获取丢失的数据吗?PHP:<?phpinclude('Crypt/AES.php');$aes = new Crypt_AES();$aes->setKey('abcdefghijklmnop');echo bin2hex($aes->encrypt("0000000000000thankustackoverflow"));https://github.com/andrewarrow/phpseclib1/blob/master/Crypt/AES.php https://github.com/andrewarrow/phpseclib1/blob/master/Crypt/Rijndael.php调试php输出:00000000000000000000000000000000 <--- IV30303030303030303030303030746861 block 0d77aa6646bb541808ed23c88d4b06d30 crypted 06e6b75737461636b6f766572666c6f77 block 16f42b01d6e806a02b29086bc82892334f crypted 1610101010101010101010101010101010 block 32bf21ea861abbc3d72e44731978bb76c2 crypted 32
查看完整描述

2 回答

?
米脂

TA贡献1836条经验 获得超3个赞

这不是一个移位问题,它是一个输出缓冲区大小问题,因为 iv 是加密数据的前缀。

IV 是一个空块 (0x00),因为它从未设置为值。它被添加到加密数据之前,这很常见。需要添加一个填充块,因为输入数据是块大小的精确倍数。

这个输出缓冲区需要是 iv 的大小 + 数据的大小 + 填充块的大小。(16 + 32 + 16 = 64)

向输出缓冲区添加另一个块大小:

ciphertext := make([]byte, aes.BlockSize + len(plaintext) + aes.BlockSize)


查看完整回答
反对 回复 2022-03-07
?
忽然笑

TA贡献1806条经验 获得超5个赞

PHP 版本正在编码一个额外的 16 字节的“空”字符串,该字符串用 16 秒填充!


  p1 := "0000000000000tha"

  p2 := "nkustackoverflow"


  p1b := []byte(p1)

  p2b := []byte(p2)

  p3b, _ := hex.DecodeString("10101010101010101010101010101010")

  fmt.Println(p3b)


  key := []byte("abcdefghijklmnop")

  block, _ := aes.NewCipher(key)

  ciphertext := make([]byte, aes.BlockSize+16)

  iv := ciphertext[:aes.BlockSize]

  mode := cipher.NewCBCEncrypter(block, iv)


  i := 0

  for {

    if i == 0 {

      mode.CryptBlocks(ciphertext[aes.BlockSize:], p1b)

    } else if i == 1 {

      mode.CryptBlocks(ciphertext[aes.BlockSize:], p2b)

    } else if i == 2 {

      mode.CryptBlocks(ciphertext[aes.BlockSize:], p3b)

    }

    fmt.Printf("%x\n", ciphertext[16:])

    i += 1

    if i > 2 {

      break

    }

  }

这段代码identical在 golang 中打印 php 的内容。


查看完整回答
反对 回复 2022-03-07
  • 2 回答
  • 0 关注
  • 166 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号