我在用Go做AES加密,发现加密后源字节变了。如果 cap(source) > len(source),似乎 XORKeyStream 函数会发生变化,它对 src []byte 究竟做了什么?
go 版本 go1.12.5 darwin/amd64
func main() {
byte1 := []byte("123abc")
fmt.Println("content1:", byte1, "len1:", len(byte1), "cap1:", cap(byte1)) // content1: [49 50 51 97 98 99] len1: 6 cap1: 6
buf := bytes.NewBuffer([]byte("123abc"))
byte2, _ := ioutil.ReadAll(buf)
fmt.Println("content2:", byte2, "len2:", len(byte2), "cap2:", cap(byte2)) // content2: [49 50 51 97 98 99] len2: 6 cap2: 1536
_, _, _, err := crypt.AESEnc(byte1)
if err != nil {
log.Fatal(err)
}
fmt.Println("content1:", byte1, "len1:", len(byte1), "cap1:", cap(byte1)) // content1: [49 50 51 97 98 99] len1: 6 cap1: 6
_, _, _, err = crypt.AESEnc(byte2)
if err != nil {
log.Fatal(err)
}
fmt.Println("content2:", byte2, "len2:", len(byte2), "cap2:", cap(byte2)) // content2: [132 200 7 200 195 8] len2: 6 cap2: 1536
}
func AESEnc(data []byte) ([]byte, []byte, string, error) {
key := make([]byte, 16)
iv := make([]byte, 16)
_, err := io.ReadFull(rand.Reader, key)
if err != nil {
return nil, nil, "", err
}
_, err = io.ReadFull(rand.Reader, iv)
if err != nil {
return nil, nil, "", err
}
block, err := aes.NewCipher(key)
if err != nil {
return nil, nil, "", err
}
pdata := pckspadding(data, block.BlockSize())
stream := cipher.NewCFBEncrypter(block, iv)
stream.XORKeyStream(pdata, pdata)
return key, iv, base64.StdEncoding.EncodeToString(pdata), nil
}
func pckspadding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
byte2加密后变了,怎么回事?
它将提供的切片中的每个字节与密码密钥流中的一个字节进行异或,或者如文档所述:
// XORKeyStream XORs each byte in the given slice with a byte from the
// cipher's key stream. Dst and src must overlap entirely or not at all.
//
// If len(dst) < len(src), XORKeyStream should panic. It is acceptable
// to pass a dst bigger than src, and in that case, XORKeyStream will
// only update dst[:len(src)] and will not touch the rest of dst.
//
// Multiple calls to XORKeyStream behave as if the concatenation of
// the src buffers was passed in a single run. That is, Stream
// maintains state and does not reset at each XORKeyStream call.
XORKeyStream(dst, src []byte)
这意味着它会发生变异
dst
,这就是为什么您在执行加密后观察到不同的输入缓冲区。