go 对称加密算法aes

4,064 阅读1分钟

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,然后再重复分组加密逻辑,如下图