Go-AES算法详解与代码

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介: Go-AES算法详解与代码

本篇介绍分组密码AES的相关内容及Go实现,分组密码算法设计思想及其他分组模式可查看

AES

发展史文章:Go-Des和3Des算法详解与代码

RSA公司举办过破译DES的比赛(DES Challenge):


1997年的DES ChallengeI中用了96天;

1998年的DES ChallengeII-1中用了41天;

1998年的DES ChallengeII-2中用了56小时;

1999年的DES ChallengeII中用了22小时15分钟。

DES被破解,3DES过度后终于迎来了AES。


1997年4月15日,美国ANSI向全球发起征集AES(advanced encryptionstandard)的活动,并为此成立了AES工作小组。

1997年9月12日,美国联邦登记处公布了正式征集AES候选算法的通告。对AES的基本要求是:比三重DES快、至少与三重DES一样安全、数据分组长度为128比特、密钥长度为128/192/256比特。

1998年8月12日,在首届AES候选会议(first AES candidate conference)上公布了AES的15个候选算法,任由全世界各机构和个人攻击和评论。

1999年3月,在第2届AES候选会议(second AES candidate conference)上经过对全球各密码机构和个人对候选算法分析结果的讨论,从15个候选算法中选出了5个。分别是RC6、Rijndael、SERPENT、Twofish和MARS。

2000年4月13日至14日,召开了第3届AES候选会议(third AES candidateconference),继续对最后5个候选算法进行讨论。

2000年10月2日,NIST宣布Rijndael(Rijndael由比利时的Joan Daemen和Vincent Rijmen设计。算法的原型是 Square算法)作为新的AES。经过3年多的公开讨论,Riindael终于脱颖而出。

概述

  • 分组加密算法:明文和密文分组可变长度。
  • SPN(S变换和P变换组成的变换网络)结构:轮函数包含代换层一置换层一密钥混合层。
版本 密钥长度 分组长度 迭代轮数
AES-128 4 4 10
AES-192 6 4 12
AES-256 8 4 14

轮函数F

字节代换

列的每个元素作为输入用来指定S盒的地址:前4位指定S盒的后4位指定S盒的。由行和列所确定的S盒位置的元素取代了明文矩阵中相应位置的元素。

2020062310470442.png

S盒如下(反向使用S^-1盒即可)

2020062310470442.png

明文:10000111,前4位为8,后四位为7,替换为S(8,7)=17=00010001

行移位

行移位操作是作用于S盒的输出的,其中,列的4个行 螺旋 地左移,即第0行左移0字节,第1行左移1字节,第2行左移2字节,第3行左移3字节,如下图所示。从该图中可以看出, 这使得列完全进行了重排,即在移位后的每列中,都包含有 未移位前每个列的一个字节。接下来就可以进行列内混合了。 (逆向行移位变换将中间态数据的后三行执行相反方向的移位操作)

2020062310470442.png

列混淆

在列混淆变换中,将行移位后的状态阵列的每个列视为GF(20201204182323419.gif)上的多项式,再与一个固定的多项式c(x)进行模20201204182323419.gif乘法,要求c(x) 是模20201204182323419.gif可逆的多项式。 c(x)=’03’20201204182323419.gif+’01’20201204182323419.gif+’01’x+’02’。

2020062310470442.png

轮密钥加

密钥编排

密钥编排指从种子密钥得到轮密钥的过程,AES的密钥编排由密钥扩展和轮密钥选取两部分组成,其基本原则如下:


轮密钥的总比特数等于轮数加1再乘以分组长度;如128比特的明文经过10轮的加密,则总共需 要(10+1)*128=1408比特的密钥.。

种子密钥被扩展成为扩展密钥;

轮密钥从扩展密钥中取,其中第1轮轮密钥取扩展密钥的前个字,第2轮轮密钥取接下来的个字,依次类推。

密钥扩展


扩展密钥是以4字节字为元素的一维阵列,表示为W[* (Nr +1)],其中前个字取为种子密钥, 以后每个字按递归方式定义。扩展算法根据≤6和>6有所不同。

轮密钥选取


轮密钥i(即第i个轮密钥)由轮密钥缓冲字 W[* i]到W[*(i+1)]给出

2020062310470442.png

AES和DES的不同之处

  • AES的密钥长度(128位、192位、256位)是可变的,而DES的 密钥长度固定为56位。
  • DES是面向比特的运算,AES是面向字节的运算。
  • AES的加密运算和解密运算不一致,因而加密器不能同时 用作解密器,而DES的加密器可用作解密器,只是子密钥 的顺序不同。

分组模式CTR

加密不同的明文分组所用的计数器值必须不同(模20201204182323419.gif运 算,其中d是分组长度)。

2020062310470442.png

AES的Go实现

aes包

func NewCipher(key []byte) (cipher.Block, error)

创建一个cipher.Block接口。参数key为密钥,长度只能是16、24、32字节,用以选择AES-128、AES-192、AES-256。

cipher包

func NewCTR(block Block, iv []byte) Stream

返回一个计数器模式的、底层采用block生成key流的Stream接口,初始向量iv的长度必须等于block的块尺寸。

stream接口的方法

XORKeyStream(dst, src []byte)


从加密器的key流和src中依次取出字节二者xor后写入dst,src和dst可指向同一内存地址

加密/解密

  • 使用aes.NewCipher获取块
  • 使用cipher.CTR转为CTR模式流
  • 使用stearm.XORKeyStream进行加解密
// 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)

2020062310470442.png

参考

《现代密码学教程 谷利泽 杨义先等》


AES的发展史


Go标准库-crypto/aes


Go标准库-crypto/cipher


更多Go相关内容:Go-Golang学习总结笔记


有问题请下方评论,转载请注明出处,并附有原文链接,谢谢!如有侵权,请及时联系。



相关文章
|
18天前
|
算法
分享一些提高二叉树遍历算法效率的代码示例
这只是简单的示例代码,实际应用中可能还需要根据具体需求进行更多的优化和处理。你可以根据自己的需求对代码进行修改和扩展。
|
26天前
|
安全 Go 开发者
代码之美:Go语言并发编程的优雅实现与案例分析
【10月更文挑战第28天】Go语言自2009年发布以来,凭借简洁的语法、高效的性能和原生的并发支持,赢得了众多开发者的青睐。本文通过两个案例,分别展示了如何使用goroutine和channel实现并发下载网页和构建并发Web服务器,深入探讨了Go语言并发编程的优雅实现。
34 2
|
29天前
|
算法 测试技术 开发者
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗
在Python开发中,性能优化和代码审查至关重要。性能优化通过改进代码结构和算法提高程序运行速度,减少资源消耗;代码审查通过检查源代码发现潜在问题,提高代码质量和团队协作效率。本文介绍了一些实用的技巧和工具,帮助开发者提升开发效率。
37 3
|
28天前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
2月前
|
存储 缓存 算法
如何通过优化算法和代码结构来提升易语言程序的执行效率?
如何通过优化算法和代码结构来提升易语言程序的执行效率?
|
2月前
|
搜索推荐
插入排序算法的讲解和代码
【10月更文挑战第12天】插入排序是一种基础的排序算法,理解和掌握它对于学习其他排序算法以及数据结构都具有重要意义。你可以通过实际操作和分析,进一步深入了解插入排序的特点和应用场景,以便在实际编程中更好地运用它。
|
2月前
|
缓存 分布式计算 监控
优化算法和代码需要注意什么
【10月更文挑战第20天】优化算法和代码需要注意什么
18 0
|
2月前
|
JSON 搜索推荐 Go
ZincSearch搜索引擎中文文档及在Go语言中代码实现
ZincSearch官网及开发文档均为英文,对非英语用户不够友好。GoFly全栈开发社区将官方文档翻译成中文,并增加实战经验和代码,便于新手使用。本文档涵盖ZincSearch在Go语言中的实现,包括封装工具库、操作接口、统一组件调用及业务代码示例。官方文档https://zincsearch-docs.zinc.dev;中文文档https://doc.goflys.cn/docview?id=41。
|
2月前
|
算法 安全 Go
Python与Go语言中的哈希算法实现及对比分析
Python与Go语言中的哈希算法实现及对比分析
41 0
|
2月前
|
安全 测试技术 Go
Python 和 Go 实现 AES 加密算法的技术详解
Python 和 Go 实现 AES 加密算法的技术详解
100 0