不使用初始化向量(IV)的AES128加密

huangapple go评论69阅读模式
英文:

Go AES128 without IV

问题

我正在尝试解密一些没有初始化向量(IV)的AES128数据。Go语言提供了一种使用IV解密的简单方法,但我无法弄清楚如何在不使用IV的情况下进行解密。以下是我目前的代码:

block, err := aes.NewCipher(key)

if err != nil {
    panic(err)
}

if len(data)%aes.BlockSize != 0 {
    panic("密文长度不是块大小的倍数")
}

fmt.Printf("解密结果:\n%s\n", data)

所以我正在努力弄清楚如何使用block进行解密。

谢谢...

英文:

I am trying to decypher some AES128 data that does not have the IV. Go provides easy way to decypher with IV, but I cannot figure out how to go about not using the IV. So here what I have so far:

block, err := aes.NewCipher(key)

if err != nil {
    panic(err)
}

if len(data)%aes.BlockSize != 0 {
    panic("ciphertext is not a multiple of the block size")
}

fmt.Printf("Decyphered:\n%s\n", data)

So I am struggling to figure out how to decypher using the block.

Thanks...

答案1

得分: 2

我假设你在这里使用的是CBC模式,但CFB模式应该也可以工作。

请注意,由于IV不被视为机密,通常将其作为方便起见附加到密文本身之前。

由于这些模式处理IV的方式,如果使用了错误的IV,你只会丢失第一个明文块。如果实际的IV存在,你会在明文输出的开头解密出随机数据,因此尝试使用空IV进行解密不会有任何损害。但是,如果没有原始IV,你无法恢复第一个块(除非使用暴力破解)。

以下是示例代码:

key := []byte("YELLOW SUBMARINE")
plaintext := []byte("exampleplaintext that is longer than a single block and some pad")

if len(plaintext)%aes.BlockSize != 0 {
    panic("plaintext not multiple of block size")
}

block, err := aes.NewCipher(key)
if err != nil {
    panic(err)
}

// IV需要是唯一的,但不需要是安全的。因此,通常将其包含在密文的开头。
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
    panic(err)
}

mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
fmt.Printf("%x\n", ciphertext)

// 现在使用错误的IV进行解密
iv = make([]byte, 16)

// 如果你想要正确的IV,在这种情况下,我们可以从密文中提取它
// iv = ciphertext[:aes.BlockSize]
// ciphertext = ciphertext[aes.BlockSize:]

if len(ciphertext)%aes.BlockSize != 0 {
    panic("ciphertext is not a multiple of the block size")
}

mode = cipher.NewCBCDecrypter(block, iv)
newPlaintext := make([]byte, len(ciphertext))
mode.CryptBlocks(newPlaintext, ciphertext)

fmt.Printf("%s\n", newPlaintext)

希望对你有帮助!

英文:

I'm assuming you're using CBC here, but CFB mode should work the same.

Note that since the IV isn't considered secret, it's often prepended to the ciphertext itself for convenience.

Because of the way these modes handle the IV, if you use the incorrect IV you only lose the first block of plaintext. If the actual IV is there, you end up decrypting random data at the beginning of your plaintext output, so it doesn't hurt to simply try to decrypt it with an empty IV. Without the original IV though, you cannot get back that first block (short of using brute-force).

<kbd>Example</kbd>

key := []byte(&quot;YELLOW SUBMARINE&quot;)
plaintext := []byte(&quot;exampleplaintext that is longer than a single block and some pad&quot;)

if len(plaintext)%aes.BlockSize != 0 {
	panic(&quot;plaintext not multiple of block size&quot;)
}

block, err := aes.NewCipher(key)
if err != nil {
	panic(err)
}

// The IV needs to be unique, but not secure. Therefore it&#39;s common to
// include it at the beginning of the ciphertext.
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
iv := ciphertext[:aes.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
	panic(err)
}

mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
fmt.Printf(&quot;%x\n&quot;, ciphertext)

// Now Decrypt with wrong IV
iv = make([]byte, 16)

// If you wanted the correct IV, in thise case we could pull it from the ciphertext
//iv = ciphertext[:aes.BlockSize]
//ciphertext = ciphertext[aes.BlockSize:]

if len(ciphertext)%aes.BlockSize != 0 {
	panic(&quot;ciphertext is not a multiple of the block size&quot;)
}

mode = cipher.NewCBCDecrypter(block, iv)
newPlaintext := make([]byte, len(ciphertext))
mode.CryptBlocks(newPlaintext, ciphertext)

fmt.Printf(&quot;%s\n&quot;, newPlaintext)

huangapple
  • 本文由 发表于 2014年8月13日 23:46:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/25290596.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定