crypto/cipher-XORKeyStream 对 src []byte 做了什么?

问题描述 投票:0回答:2

我在用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加密后变了,怎么回事?

go aes
2个回答
0
投票

我不熟悉 crypto/cypher-XORKeyStream,但如果有帮助,我可以告诉你 XOR 对位的作用。我有一些电子经验,这是 XOR 门的真值表:

输入 X 和 Y 代表两位。输出 Z 是 X 和 Y 的异或结果。

在英语中,你会对自己说“输入,要么是一个,要么是另一个,但不是两个”,结果输出为“真”。

不知道这会有多大帮助,也不知道如何使用 crypto/cypher-XORKeyStream 将其应用于两个以上的输入位。 但这里有一个例子:

X = 00110001010
Y = 11111111111
Z = 11001110101

祝你好运!


0
投票

它将提供的切片中的每个字节与密码密钥流中的一个字节进行异或,或者如文档所述:

    // 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
,这就是为什么您在执行加密后观察到不同的输入缓冲区。

© www.soinside.com 2019 - 2024. All rights reserved.