ctr加密模式(计数器模式)
package main
import (
"crypto/aes"
"crypto/cipher"
"fmt"
"log"
)
const (
aesKey = "12345678abcdefgh"
aesIv = "abcdabcd12345678"
)
//加密
func AesEny(plaintext []byte) []byte {
var(
block cipher.Block
err error
)
//创建aes
if block, err = aes.NewCipher([]byte(aesKey)); err != nil{
log.Fatal(err)
}
//创建ctr
stream := cipher.NewCTR(block, []byte(aesIv))
//加密, src,dst 可以为同一个内存地址
stream.XORKeyStream(plaintext, plaintext)
return plaintext
}
//解密
func AesDec1(ciptext []byte) []byte {
var(
block cipher.Block
err error
)
//创建aes
if block, err = aes.NewCipher([]byte(aesKey)); err != nil{
log.Fatal(err)
}
//创建ctr
stream := cipher.NewCTR(block,[]byte(aesIv))
stream.XORKeyStream(ciptext, ciptext)
return ciptext
}
//解密
func AesDec2(ciptext []byte) []byte {
//对密文再进行一次按位异或就可以得到明文
//例如:3的二进制是0011和8的二进制1000按位异或(相同为0,不同为1)后得到1011,
//对1011和8的二进制1000再进行按位异或得到0011即是3
return AesEny(ciptext)
}
func main() {
plaintext := []byte("我 爱 你")
fmt.Println("明文", string(plaintext))
ciptext := AesEny(plaintext)
fmt.Println("加密", ciptext)
//platext1 := AesDec1(ciptext)
//fmt.Println("解密", string(platext1))
platext2 := AesDec2(ciptext)
fmt.Println("解密", string(platext2))
}说明:
- aes最少以16个字节分组,密钥key和随机数种子Iv和分组字节数相同也是16个字节
- CTR加密模式不需要分组填充
- CTR加密模式是将随机数加密后和明文分组进行按位异或(XOR)操作,即得到密文(所以解密时只要对密文再进行一次按位异或就可以得到明文),下次分组加密时随机数加1,然后再重复分组加密逻辑,如下图