加密算法之AES

2018-12-19  本文已影响5人  Carrism

AES

算法原理

AES采用分组密码体制,首先将明文分成以16个字节长度为基准字节段,如果最后不足16字节则同样使用填充。然后分组对每段字节段进行加密得到密文,再将最后得到的密文拼接在一起形成最终的密文。AES算法的密钥长度可以分为128位,256位,512位。

加密过程

  1. 字节替换变换

    任何字节都对应着AES的S盒,S盒是一个映射表,在这个映射表中,任何元素都能够有相应的元素与之对应,并且映射过程是可逆的。


    AES S盒.png
  1. 行移位变换

    AES算法的明文分组要求是每组的字节长度为16,就是因为能够刚好转换成4x4矩阵。然后第一行保持不变,第二行循环左移1个字节,第三行循环左移2个字节,第四行循环左移3个字节


    AES行移位变换.png
  1. 列混淆

    列混淆变换将状态矩阵中的每一列视为系数在GF(2^8 )上的次数小于4的多项式与同一个固定的多项式a(x)进行模多项式m(x)=x^4 +1的乘法运算。在AES中,a(x)={03}x^3 +{01}x^2 +{01}x+{02}

  2. 轮加密

    任何数和自身异或结果为0,所以在加密中明文与密钥异或之后,在解密重新与该密钥进行异或能够得到原来的输入

整个加密过程如下图所示:

AES加解密.png

实现过程

功能实现,在客户端中将明文进行AES加密后通过TCP链接发送至另一个客户端,另一端通过密钥对密文进行解密得到明文

//补码
    func PKCS5Padding(orgData []byte,blockSize int) []byte  {
        padding := blockSize - len(orgData)%blockSize
        paddingBytes := bytes.Repeat([]byte{byte(padding)},padding)
        orgData = append(orgData,paddingBytes...)
        return orgData
}
//AES加密
func AESEncrypt(org []byte,key []byte) []byte  {
        block,_ := aes.NewCipher(key)
        //明文补码
        org = PKCS5Padding(org,block.BlockSize())
        //设置加密方式
        blockMode := cipher.NewCBCEncrypter(block,key)
        // 创建缓冲区
        cypted := make([]byte,len(org))
        //加密
        blockMode.CryptBlocks(cypted,org)
        return cypted
    }
  1. 启动TCP链接并将数据发送出去
    func main() {
        //密钥
        key := "1234567890123456"
        //AES加密
        data := AESEncrypt([]byte("hello World"),[]byte(key))
        //建立TCP链接
        tcp,_ := net.ResolveTCPAddr("tcp","127.0.0.1:1234")
        tcpConn,_ := net.DialTCP("tcp",nil,tcp)
        //发送数据
        tcpConn.Write(data)
}
    //AES解密
func AESDecrypt(cipherTxt []byte,key []byte) []byte  {
        block,_ := aes.NewCipher(key)
        //设置解密模式
        blockMode := cipher.NewCBCDecrypter(block,key)
        //创建缓冲区
        org := make([]byte,len(cipherTxt))
        blockMode.CryptBlocks(org,cipherTxt)
        //去码
        return PKCS5UnPadding(org)
}
//去码
func PKCS5UnPadding(desData []byte) []byte  {
        length := len(desData)
        padding := desData[length - 1]
        sourceData := desData[:length - int(padding)]
        return sourceData
}
    func main() {
        listener,_ := net.Listen("tcp","127.0.0.1:1234")
        defer listener.Close()
        for {
            //只有客户端连接成功才会向下执行
            conn,_:=listener.Accept()
            //创建缓存,存放客户端发送的数据
            data:=make([]byte,1024)
            for {
                //接收客户端发送的数据,n数据的大小
                n,_:=conn.Read(data)
                //data[:n]就是接受到的密文
                fmt.Println("密文为:",data[:n])
                fmt.Println("名文为:",string(AESDecrypt(data[:n],[]byte("1234567890123456"))))
                break
            }
        }
    }
上一篇下一篇

猜你喜欢

热点阅读