目录
AES
发展史
概述
轮函数F
字节代换
行移位
列混淆
轮密钥加
密钥编排
AES和DES的不同之处
分组模式CTR
AES的Go实现
aes包
cipher包
加密/解密
参考
本篇介绍分组密码AES的相关内容及Go实现,分组密码算法设计思想及其他分组模式可查看文章:Go-Des和3Des算法详解与代码
RSA公司举办过破译DES的比赛(DES Challenge):
DES被破解,3DES过度后终于迎来了AES。
版本 | 密钥长度 | 分组长度 | 迭代轮数 |
---|---|---|---|
AES-128 | 4 | 4 | 10 |
AES-192 | 6 | 4 | 12 |
AES-256 | 8 | 4 | 14 |
列的每个元素作为输入用来指定S盒的地址:前4位指定S盒的行,后4位指定S盒的列。由行和列所确定的S盒位置的元素取代了明文矩阵中相应位置的元素。
S盒如下(反向使用S^-1盒即可)
明文:10000111,前4位为8,后四位为7,替换为S(8,7)=17=00010001
行移位操作是作用于S盒的输出的,其中,列的4个行 螺旋 地左移,即第0行左移0字节,第1行左移1字节,第2行左移2字节,第3行左移3字节,如下图所示。从该图中可以看出, 这使得列完全进行了重排,即在移位后的每列中,都包含有 未移位前每个列的一个字节。接下来就可以进行列内混合了。 (逆向行移位变换将中间态数据的后三行执行相反方向的移位操作)
在列混淆变换中,将行移位后的状态阵列的每个列视为GF()上的多项式,再与一个固定的多项式c(x)进行模乘法,要求c(x) 是模可逆的多项式。 c(x)=’03’+’01’+’01’x+’02’。
密钥编排指从种子密钥得到轮密钥的过程,AES的密钥编排由密钥扩展和轮密钥选取两部分组成,其基本原则如下:
密钥扩展
扩展密钥是以4字节字为元素的一维阵列,表示为W[* (Nr +1)],其中前个字取为种子密钥, 以后每个字按递归方式定义。扩展算法根据≤6和>6有所不同。
轮密钥选取
轮密钥i(即第i个轮密钥)由轮密钥缓冲字 W[* i]到W[*(i+1)]给出
加密不同的明文分组所用的计数器值必须不同(模运 算,其中d是分组长度)。
func NewCipher(key []byte) (cipher.Block, error)
创建一个cipher.Block接口。参数key为密钥,长度只能是16、24、32字节,用以选择AES-128、AES-192、AES-256。
func NewCTR(block Block, iv []byte) Stream
返回一个计数器模式的、底层采用block生成key流的Stream接口,初始向量iv的长度必须等于block的块尺寸。
stream接口的方法
XORKeyStream(dst, src []byte)
从加密器的key流和src中依次取出字节二者xor后写入dst,src和dst可指向同一内存地址
// plainText:明文
// iv: 初始化向量
// key:密钥
// 返回密文/明文,以及错误
func AesEncrypt(plainText, iv,key []byte) ([]byte,error) {
block, err :=aes.NewCipher(key)
if err != nil{
_, file, line, _ := runtime.Caller(0)
return nil,util.Error(file,line+1,errors.AesKeyError)
}
if len(iv) != block.BlockSize(){
_, file, line, _ := runtime.Caller(0)
return nil,util.Error(file,line+1,errors.AesIvError)
}
// create a CTR interface
stream := cipher.NewCTR(block,iv)
cipherText := make([]byte,len(plainText))
// encrypt or decrypt
stream.XORKeyStream(cipherText,plainText)
return cipherText,nil
}
代码我放到了gitee上:https://gitee.com/frankyu365/gocrypto
您可以查看仓库Readme文档或Go-包管理(管理工具对比及go mod的使用)来进行安装
测试代码
iv := []byte("12345678qwertyui")
key:= []byte("12345678abcdefgh09876543alnkdjfh")
plainText := []byte("Hi,I'm lady_killer9")
cipherText,_ := aes.AesEncrypt(plainText,iv,key)
fmt.Printf("加密后:%s\n",cipherText)
decryptText,_ := aes.AesDecrypt(cipherText,iv,key)
fmt.Printf("解密后:%s\n",decryptText)
《现代密码学教程 谷利泽 杨义先等》
AES的发展史
Go标准库-crypto/aes
Go标准库-crypto/cipher
更多Go相关内容:Go-Golang学习总结笔记
有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。如果您感觉有所收获,自愿打赏,可选择支付宝18833895206(小于),您的支持是我不断更新的动力。