猿问

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

我像这样加密:


  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:


<?php


include('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 <--- IV

30303030303030303030303030746861 block 0

d77aa6646bb541808ed23c88d4b06d30 crypted 0

6e6b75737461636b6f766572666c6f77 block 16

f42b01d6e806a02b29086bc82892334f crypted 16

10101010101010101010101010101010 block 32

bf21ea861abbc3d72e44731978bb76c2 crypted 32


慕桂英3389331
浏览 167回答 2
2回答

米脂

这不是一个移位问题,它是一个输出缓冲区大小问题,因为 iv 是加密数据的前缀。IV 是一个空块 (0x00),因为它从未设置为值。它被添加到加密数据之前,这很常见。需要添加一个填充块,因为输入数据是块大小的精确倍数。这个输出缓冲区需要是 iv 的大小 + 数据的大小 + 填充块的大小。(16 + 32 + 16 = 64)向输出缓冲区添加另一个块大小:ciphertext&nbsp;:=&nbsp;make([]byte,&nbsp;aes.BlockSize&nbsp;+&nbsp;len(plaintext)&nbsp;+&nbsp;aes.BlockSize)

忽然笑

PHP 版本正在编码一个额外的 16 字节的“空”字符串,该字符串用 16 秒填充!&nbsp; p1 := "0000000000000tha"&nbsp; p2 := "nkustackoverflow"&nbsp; p1b := []byte(p1)&nbsp; p2b := []byte(p2)&nbsp; p3b, _ := hex.DecodeString("10101010101010101010101010101010")&nbsp; fmt.Println(p3b)&nbsp; key := []byte("abcdefghijklmnop")&nbsp; block, _ := aes.NewCipher(key)&nbsp; ciphertext := make([]byte, aes.BlockSize+16)&nbsp; iv := ciphertext[:aes.BlockSize]&nbsp; mode := cipher.NewCBCEncrypter(block, iv)&nbsp; i := 0&nbsp; for {&nbsp; &nbsp; if i == 0 {&nbsp; &nbsp; &nbsp; mode.CryptBlocks(ciphertext[aes.BlockSize:], p1b)&nbsp; &nbsp; } else if i == 1 {&nbsp; &nbsp; &nbsp; mode.CryptBlocks(ciphertext[aes.BlockSize:], p2b)&nbsp; &nbsp; } else if i == 2 {&nbsp; &nbsp; &nbsp; mode.CryptBlocks(ciphertext[aes.BlockSize:], p3b)&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Printf("%x\n", ciphertext[16:])&nbsp; &nbsp; i += 1&nbsp; &nbsp; if i > 2 {&nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; }&nbsp; }这段代码identical在 golang 中打印 php 的内容。
随时随地看视频慕课网APP

相关分类

Go
我要回答