保护数据隐私:深入探索Golang中的SM4加密解密算法 世界快播报
最近做的项目对安全性要求比较高,特别强调:系统不能涉及MD5、SHA1、RSA1024、DES高风险算法。
(资料图)
那用什么嘞?甲方:建议用国产密码算法SM4。
擅长敏捷开发(CV大法)的我,先去GitHub找了开源项目、又去网络上找了一些教程,但是或多或少都有些问题:
比如golang.org/x/crypto/sm4无法安装编译比如C站烂大街的SM4教程,不能解决数据填充的问题,超过16位就解密失败了比如如何封装成通用的方法,供系统进行调用更多就是复制粘贴了SM4的定义,很抽象。于是我花了2天时间研究SM4的原理和应用,解决了上面这些问题,整理这篇文章分享给大家,让大家能少踩坑。
我会按照下面的顺序分享这篇文章,方便大家更好的理解,如果你就是喜欢拿来主义(敏捷开发),可以直接copy底部的示例代码,快速上手使用即可。
文章目录SM4的优势IV是什么?SM4加密的方式和原理SM4的各种工作模式对比直接可用的「代码示例」核心方法的源码解析总结回顾1. SM4的优势相比于其他加密算法,SM4加密算法具有以下几个优势:
高安全性:SM4是一种对称加密算法,采用128位密钥长度,具有较高的安全性和抗攻击性。它经过了广泛的安全性分析和评估,并通过了多个密码学标准的验证。
高效性:SM4算法的加密和解密速度较快,适用于对大量数据进行加密和解密的场景。它在硬件和软件实现上都具有高效性能。
简单性:SM4算法的实现相对简单,代码量较小,易于理解和使用。它的设计目标之一是提供一种易于实现和部署的加密算法。
标准化:SM4算法是中国国家密码管理局发布的密码算法标准,得到了广泛的应用和认可。它已成为国际上公认的密码算法之一。
广泛支持:SM4算法在各种平台和编程语言中都有支持和实现,包括Go、Java、C/C++等。它可以在不同的系统和环境中进行跨平台的应用和部署。
可扩展性:SM4算法支持不同的工作模式和填充方式,可以根据具体需求进行灵活配置。它可以与其他密码算法结合使用,提供更高级别的安全保护。
小小的总结一下:SM4加密算法在安全性、高效性、简单性、标准化和广泛支持等方面具有优势,适用于各种数据保护和加密应用场景。它是一种可靠的加密算法选择。
2.IV是什么?我在学习的时候看到IV就蒙了,所以有必要先说清楚IV的概念:
Initialization Vector(IV)是一种在密码学中使用的初始值。它是一个固定长度的随机数或者随机生成的值,用于在加密算法中初始化密码算法的状态。
在加密过程中,IV的作用是引入随机性和唯一性,以增加加密的安全性。它与密钥一起用于初始化密码算法的内部状态,确保每次加密操作都产生不同的输出,即使相同的明文使用相同的密钥进行加密。
IV的长度和使用方式取决于具体的加密算法和应用场景。在使用加密算法时,IV通常需要与密文一起传输给解密方,以便解密方能够正确还原明文。
需要注意的是:IV本身不需要保密,可以与密文一起传输。然而,为了确保加密的安全性,IV应该是随机生成的,并且每次加密操作都应该使用不同的IV。这样可以防止密码分析者通过观察加密结果的模式来破解密钥或者明文。
3. SM4加密的方式和原理SM4加密算法是一种对称加密算法,采用分组密码的方式对数据进行加密。
下面是SM4加密的方式和原理的简要说明:
密钥扩展:SM4使用128位的密钥,首先对密钥进行扩展,生成32个子密钥,用于后续的加密轮操作。
初始轮:将明文分为4个字节的分组,与第一个子密钥进行异或操作。
加密轮:SM4加密算法共进行32轮加密操作。每轮操作包括以下步骤:
字节替换:使用S盒进行字节替换。行移位:对每个分组进行行移位操作。列混淆:对每个分组进行列混淆操作。轮密钥加:将当前轮的子密钥与分组进行异或操作。最终轮:在最后一轮加密操作中,不进行列混淆操作,只进行字节替换、行移位和轮密钥加操作。
输出:经过32轮加密操作后,得到加密后的密文。
SM4加密算法的安全性和强度主要来自于其复杂的轮函数和密钥扩展过程。它具有较高的安全性和抗攻击性,并且在实际应用中得到了广泛的应用和认可。
需要注意的是:SM4加密算法的安全性还依赖于密钥的保密性和随机性。在使用SM4进行加密时,应确保使用足够强度的密钥,并采取适当的密钥管理和保护措施。
4.SM4的各种工作模式对比SM4加密算法可以使用不同的工作模式,其中包括CBC(Cipher Block Chaining)模式。
我使用的是CBC模式,下面和大家分享一下CBC模式与其他模式的对比:
CBC模式(Cipher Block Chaining):特点:每个明文块与前一个密文块进行异或操作,然后再进行加密。初始块使用初始化向量(IV)。优点:具有较好的安全性,能够隐藏明文的模式和重复性。缺点:加密过程是串行的,不适合并行处理。ECB模式(Electronic Codebook):特点:将每个明文块独立加密,相同的明文块会得到相同的密文块。优点:简单、并行处理效率高。缺点:不能隐藏明文的模式和重复性,不适合加密大量重复的数据。CFB模式(Cipher Feedback):特点:将前一个密文块作为输入来加密当前的明文块,可以实现流密码的功能。优点:能够处理不定长的数据流,适用于实时加密和流式传输。缺点:加密过程是串行的,不适合并行处理。OFB模式(Output Feedback):特点:将前一个密文块作为输入来生成密钥流,然后与明文块进行异或操作,可以实现流密码的功能。优点:能够处理不定长的数据流,适用于实时加密和流式传输。缺点:加密过程是串行的,不适合并行处理。CTR模式(Counter):特点:使用一个计数器来生成密钥流,然后与明文块进行异或操作,可以实现流密码的功能。优点:能够处理不定长的数据流,适用于实时加密和流式传输。并行处理效率高,适合硬件实现。缺点:需要保证计数器的唯一性,否则会导致密钥流的重复。对比总结:CBC模式和ECB模式相比,CBC模式具有更好的安全性,能够隐藏明文的模式和重复性,而ECB模式无法隐藏这些信息。CFB模式、OFB模式和CTR模式都是流密码模式,适用于不定长的数据流加密,能够实现实时加密和流式传输。它们的主要区别在于密钥流的生成方式和加密过程的并行性。CFB模式和OFB模式的加密过程是串行的,不适合并行处理,而CTR模式的加密过程可以并行处理,适合硬件实现。总的来说:CBC模式在安全性方面较好,能够隐藏明文的模式和重复性。而流密码模式(CFB、OFB和CTR)适用于不定长数据流的加密,能够实现实时加密和流式传输,其中CTR模式具有较好的并行处理性能。选择合适的加密模式取决于具体的应用需求和安全性要求。
5. 直接可用的「代码示例」我一直认为可以通过复制粘贴,直接跑通的示例代码才是好代码。
没错,我的代码示例就是这样,并且关键代码都写好了注释:
package mainimport ("bytes""crypto/cipher""encoding/hex""fmt""github.com/tjfoc/gmsm/sm4")// SM4加密func SM4Encrypt(data string) (result string, err error) {//字符串转byte切片plainText := []byte(data)//建议从配置文件中读取秘钥,进行统一管理SM4Key := "Uv6tkf2M3xYSRuFv"//todo 注意:iv需要是随机的,进一步保证加密的安全性,将iv的值和加密后的数据一起返回给外部SM4Iv := "04TzMuvkHm_EZnHm"iv := []byte(SM4Iv)key := []byte(SM4Key)//实例化sm4加密对象block, err := sm4.NewCipher(key)if err != nil {panic(err)}//明文数据填充paddingData := paddingLastGroup(plainText, block.BlockSize())//声明SM4的加密工作模式blockMode := cipher.NewCBCEncrypter(block, iv)//为填充后的数据进行加密处理cipherText := make([]byte, len(paddingData))//使用CryptBlocks这个核心方法,将paddingData进行加密处理,将加密处理后的值赋值到cipherText中blockMode.CryptBlocks(cipherText, paddingData)//加密结果使用hex转成字符串,方便外部调用cipherString := hex.EncodeToString(cipherText)return cipherString, nil}// SM4解密 传入string 输出stringfunc SM4Decrypt(data string) (res string, err error) {//秘钥SM4Key := "Uv6tkf2M3xYSRuFv"//iv是Initialization Vector,初始向量,SM4Iv := "04TzMuvkHm_EZnHm"iv := []byte(SM4Iv)key := []byte(SM4Key)block, err := sm4.NewCipher(key)if err != nil {panic(err)}//使用hex解码decodeString, err := hex.DecodeString(data)if err != nil {return "", err}//CBC模式 优点:具有较好的安全性,能够隐藏明文的模式和重复性。 缺点:加密过程是串行的,不适合并行处理。blockMode := cipher.NewCBCDecrypter(block, iv)//下文有详解这段代码的含义blockMode.CryptBlocks(decodeString, decodeString)//去掉明文后面的填充数据plainText := unPaddingLastGroup(decodeString)//直接返回字符串类型,方便外部调用return string(plainText), nil}// 明文数据填充func paddingLastGroup(plainText []byte, blockSize int) []byte {//1.计算最后一个分组中明文后需要填充的字节数padNum := blockSize - len(plainText)%blockSize//2.将字节数转换为byte类型char := []byte{byte(padNum)}//3.创建切片并初始化newPlain := bytes.Repeat(char, padNum)//4.将填充数据追加到原始数据后newText := append(plainText, newPlain...)return newText}// 去掉明文后面的填充数据func unPaddingLastGroup(plainText []byte) []byte {//1.拿到切片中的最后一个字节length := len(plainText)lastChar := plainText[length-1]//2.将最后一个数据转换为整数number := int(lastChar)return plainText[:length-number]}func main() {//待加密的数据 模拟18位的身份证号plainText := "131229199907097219"//SM4加密decrypt, err := SM4Encrypt(plainText)if err != nil {return}fmt.Printf("sm4加密结果:%s\n", decrypt)//cipherString := hex.EncodeToString(cipherText)//fmt.Printf("sm4加密结果转成字符串:%s\n", cipherString)//SM4解密sm4Decrypt, err := SM4Decrypt(decrypt)if err != nil {return}fmt.Printf("plainText:%s\n", sm4Decrypt)flag := plainText == sm4Decryptfmt.Println("解密是否成功:", flag)}运行结果如下:
6. 核心方法的源码解析细心的小伙伴应该又发现,(或者通过你真实的敲代码一定能发现。
在加密和解密部分有一个CryptBlocks()方法,我们来解析一下这段源码:
// CryptBlocks encrypts or decrypts a number of blocks. The length of// src must be a multiple of the block size. Dst and src must overlap// entirely or not at all.//// If len(dst) < len(src), CryptBlocks should panic. It is acceptable// to pass a dst bigger than src, and in that case, CryptBlocks will// only update dst[:len(src)] and will not touch the rest of dst.//// Multiple calls to CryptBlocks behave as if the concatenation of// the src buffers was passed in a single run. That is, BlockMode// maintains state and does not reset at each CryptBlocks call.CryptBlocks(dst, src []byte)翻译翻译CryptBlocks方法用于加密或解密多个数据块。src的长度必须是块大小的倍数。dst和src必须完全重叠或完全不重叠。
如果len(dst) < len(src),CryptBlocks方法应该引发panic。允许传递比src更大的dst,此时CryptBlocks只会更新dst[:len(src)],不会触及dst的其余部分。
在这段代码注释中,dst表示目标缓冲区,用于存储加密或解密后的结果。src表示源缓冲区,包含要加密或解密的数据。这两个缓冲区可以是相同的内存区域,也可以是不同的内存区域。CryptBlocks方法会将src中的数据进行加密或解密,并将结果存储在dst中。
需要注意的是,dst和src的长度必须是块大小的倍数,否则CryptBlocks方法可能会引发panic。如果dst的长度小于src的长度,CryptBlocks方法只会更新dst的前len(src)个字节,并不会修改dst的其余部分。
此外,CryptBlocks方法可以多次调用,多次调用的效果相当于将所有src缓冲区的数据连接在一起,然后进行加密或解密。这意味着BlockMode会保持状态,并且不会在每次CryptBlocks调用时重置。
如果你看注释翻译理解起来还是比较抽象的话,我换个方式介绍一下:
用我的话来说在SM4加密中,CryptBlocks()方法是用于加密或解密多个数据块的方法。它是SM4算法中的一个核心函数。
具体来说,CryptBlocks()方法接受一个源数据缓冲区(src)和一个目标数据缓冲区(dst),并对源数据进行加密或解密操作,将结果存储在目标数据缓冲区中。
在加密过程中,CryptBlocks()方法会将源数据分成多个数据块,然后对每个数据块进行加密操作,并将结果存储在目标数据缓冲区中。加密过程中使用的密钥和其他参数由SM4算法的实现确定。
在解密过程中,CryptBlocks()方法会对源数据缓冲区中的数据块进行解密操作,并将解密后的结果存储在目标数据缓冲区中。
需要注意的是:CryptBlocks()方法要求源数据缓冲区和目标数据缓冲区的长度必须是SM4算法的块大小的倍数。否则,可能会引发错误或产生不可预测的结果。
CryptBlocks()方法是SM4加密算法中用于加密或解密多个数据块的关键方法,它实现了SM4算法的核心功能。
7. 总结回顾我之前也写过一篇解密解密的文章,欢迎大家阅读指教:保障网络请求数据传输的安全性、一致性和防篡改:对称加密与非对称加密的结合
相信你读了这篇文章能对SM4加密有个整体理解,通过我在文章中提供的示例代码可以快速跑通加密和解密流程。我还带着你分析了CryptBlocks()源码的作用。
欢迎大家收藏、点赞、转发。你的关注,是我更文的最大动力!
欢迎关注 ❤我的微信:wangzhongyang1993
视频号:王中阳Go
公众号:程序员升职加薪之旅
标签:
保护数据隐私:深入探索Golang中的SM4加密解密算法 世界快播报
2023-06-25
每日播报!全新高端SUV英菲尼迪QX80已解密
2023-06-25
一些托育机构鲜少招收两岁以下幼儿
2023-06-25
富人思维:越富有的人越不会有这三种认知,穷人却越来越沉迷_要闻
2023-06-25
上交所半年报预约时间出炉 康缘药业率先披露
2023-06-25
速讯:2023端午假期避暑旅游热度攀升 “文化需求”更受关注
2023-06-25
Avatar跨平台兼容怎么做?这两家公司给出答案|环球热闻
2023-06-25
河北普锋科技有限公司_今日聚焦
2023-06-25
河南高招分数段统计表公布!
2023-06-25
全球速看:气象专家解读北方高温天气
2023-06-25
每日播报!全新高端SUV英菲尼迪QX80已解密
一些托育机构鲜少招收两岁以下幼儿
富人思维:越富有的人越不会有这三种认知,穷人却越来越沉迷_要闻
上交所半年报预约时间出炉 康缘药业率先披露
速讯:2023端午假期避暑旅游热度攀升 “文化需求”更受关注
Avatar跨平台兼容怎么做?这两家公司给出答案|环球热闻
河北普锋科技有限公司_今日聚焦
河南高招分数段统计表公布!
全球速看:气象专家解读北方高温天气
【热闻】犯月女破月是什么意思(破月是什么意思)
【天天聚看点】矿热炉变压器工作原理_矿热炉
当前速看:第六章 连环计
广州警方全力保障端午假期全市平安稳定_当前头条
高温闷热天气 谨防“情绪中暑”
视焦点讯!学习的好处有哪些_学习认真有什么好处 学习认真好处有哪些
六月英文缩写是什么_六月英文
端午假期两岸“小三通”客运航线日均客流创新高-最资讯
环球百事通!爱累了,才会主动说分手的星座!
世界要闻:布局大科学装置、数据中心集群……重庆自贸试验区再上“新试验”
当前速讯:2023暑期档总票房破25亿
天天信息:泰国华欣好玩吗_泰国华欣旅游攻略
今日学习成语:魑魅魍魉,魑魅魍魉四个字怎么读 ?
陕西公布高考分数线 世界聚看点
安理会举行乌克兰问题公开会 中国代表强调四点
每日聚焦:节令美味贺端阳!古人吃粽子有啥讲究?
D699篇、股市里的空仓
2023汉江赛艇大师赛在石泉开赛 126名健儿开启水上竞速-每日热门
环球热议:淘宝每日一猜答案6.24 除了首页外还能从哪里进大赢家6月24日答案[多图]
【世界播资讯】上海今日阴有阵雨或雷雨最高温24度 端午节后气温缓慢回升
- 速递!大戏看北京|创新传承国乐文化 《颂·黄钟大吕》音乐会北京首演
- 世界微资讯!宋杖子村
- index函数的使用方法入门初级篇(index函数的使用方法)
- 江苏省盐城市二手房价格_对盐城市区【二手房】价格了解的请进!!!
- 每日速看!大促销!新能源汽车下乡活动正式启动,多地补贴上万!
- 单小龙参军现在怎么样(参军报名时间)_全球热议
- 端午假期出游 小心蜱虫叮咬|天天讯息
- moto razr 40补货:折叠屏压到3999元
- 环球百事通!如何看电脑系统版本
- 全球观焦点:宋明理学与东亚儒学
- “倡节俭 扬新风”端午主题活动走进两江新区_每日速看
- 燃气阀门怎样操作,你都了解吗?收藏转发!
- 世界快看点丨国家气象中心:预计27日至30日华北、黄淮等地还将出现高温天气
- 环球资讯:平安e行销网手机版_平安行销网
- 【天天快播报】速派和迈锐宝哪个好?外观设计、性能与售后服务详细对比
- 海的成语接龙_海的成语
- 罗马诺:为留在皇马,莫德里奇拒绝了沙特一份难以置信的报价 环球头条
- 胆固醇偏高什么不能吃_胆固醇高什么东西不能吃
- 微头条丨蒲城县人民法院开展聘用制书记员考试考核活动
- 美军轰炸机降落瑞典 网友:回家去!_环球即时看
- 天天速读:研发费用加计扣除申报方式优化
- 被摔碎的古瓶_天天播报
- 每日精选:蒙迪欧1.5T或混动,入门价14万
- 学然后知不足原文_学然后知不足翻译
- 恐惧的反义词_恐惧是什么意思_快播
- 同性婚姻合法化的认定(同性婚姻合法化的国家)
- 环球热门:手机尾插坏了怎么在家里修复_手机尾插
- 分享自制苹果醋的正确方,法 酸酸甜甜好味道!-环球微资讯
- 【世界新要闻】李源一:足协杯目标顺利晋级,更看重后面两场联赛要拿更多积分
- 天天娱评|濮存昕的魅力
- 环球热议:士人善画告诉我们什么道理(一士人善画原文及翻译)
- 自己给汽车加氟教程_汽车空调加氟方法图解
- 鹤峰容美:艾草飘过端午节-世界快资讯
- 全球滚动:“水果妹超甜”爆红网络,户外直播秒杀千篇一律的“网红脸”
- 每日快播:再添千人起诉!美军这个丑闻越闹越大
- 每日关注!颊车穴位在哪个部位_颊车穴位在哪
- 顾长卫个人资料 顾长卫哪里人)|每日快报
- 3室2厅2卫装修效果图(装修三室两厅)
- 这次霍霍白羊座了,达墨白羊座4T固态硬盘测试
- 鸡蛋炒河粉图片_鸡蛋炒河粉
- 全球热文:石志康扮演者_石志康
- 小太阳点读笔官网 启明星点读笔官网
- 青少年滥用药品现象调查:药物管控存漏洞,成瘾药品轻易买到-每日焦点
- 今日热门!黄河2023年汛前调水调沙启动
- 全球热点评!流产后浮肿注意保持身体健康
- 世界观天下!未来国足中场核心自由了!如果加盟成都蓉城,将是不错的选择
- 塞尔达传说荒野之息小守护者怎么打(塞尔达传说小守护者位置)
- 丰田皇冠 SportCross 正式上市 售价 36.9 万元起
- cf穿越火线解封器 cf解封器免费版
- 宫斗人设独白_宫斗人设
