正确使用AES对称加密

正确使用AES对称加密

经常我看到项目中有人使用了对称加密算法,用来加密客户或项目传输中的部分数据。但我注意到开发 人员由于不熟悉原理,或者简单复制网上的代码示例,有导致代码存在安全风险。

我经常遇到的问题,有如下:

  • 如使用了过时的加密算法(如DES)

  • 设置了不安全的加密模式(ECB)

  • 不正确地处理初始向量(IV)

对称加密算法

算法位长建议
RC440
DES56
3DES112
AES128

TL;DR:

RC4/DES/3DES都 不符合 加密/破解的安全性要求。

DES是56位加密,听起来感觉3DES应该是168位,但实际上其有效加密位长只有112位。

其它更长的加密算法,如AES 192位/AES 256位也符合要求。

加密模式

TL;DR: 不要使用ECB。

ECB不需要初始向量(IV),这个“惊人”的发现常常让开发简单粗暴地设计为ECB。ECB的问题在于输入和输出存在非常明显的关联,攻击者可以从输出轻松地猜出输入数据。
640?wx_fmt=png

C#的AES算法默认模式为CBC,该算法没有上述的安全问题,而且最为通用,可以使用该模式。

初始向量

TL;DR:
初始向量 必须 为完全随机数,完全随机数应该使用RandomNumberGenerator进行加密。

回想这个问题,数据加密完后,该发送什么给接收方?仅数据?那么初始向量(IV)怎么办?

大多数开发选择的办法是,写一个固定的初始向量(IV)用于加密,然后解密时,也使用相同的初始向量。这样就导致相同的输入会产生相同的输出

为什么相同的输入应该产生不同的输出?因为根据历史经验,攻击者可以获取一些信息,知道某个确定输入的含义。一旦再次捕获到相同的加密数据,就能轻易破解。

所以,发送数据应该包含:版本+初始向量+数据。

面向字符串

加密是面向字节还是字符串?我认为应该面向字节。如果面向字符串,那么很多问题很难受到重视。

试着回答这个问题:

  • 用户的密码是什么样子的?

  • 是长度为固定32位的HEX字符吗?如1C8F7B2C9759209C6ACC3C105D39BBAC

  • 还是用户想输入什么就输入什么?如My-Super-Str0ng-Password!!

我认为加密算法应该面向字节流/字节数据,而不是字符串。将字符串发送给客户、放在JSON中进行端对端传输,是没什么毛病的做法。但基于以下原因,我强烈建议加密/解密算法要基于字节数据:

  • 避免密码太长或太短的问题

  • 来回转换为字符串效率低下

  • 字符串转换为字节数组容易,其它数据序列化为字节数据也容易

我的加密/解密方法

// 代码按原样提供,可随意使用,但不对其安全性作任何保证。string Encrypt(string password, string purpose, byte[] plainBytes){    byte[] key = PasswordToKey(password, purpose);    using (var aes = Aes.Create())    {        aes.Key = key;        using (ICryptoTransform encryptor = aes.CreateEncryptor())        {            byte[] cipherBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);            byte[] packedBytes = Pack(                version: 1,                iv: aes.IV,                cipherBytes: cipherBytes);            return Base64UrlEncode(packedBytes);        }    }}byte[] Decrypt(string packedString, string password, string purpose){    byte[] key = PasswordToKey(password, purpose);    byte[] packedBytes = Base64UrlDecode(packedString);    (byte version, byte[] iv, byte[] cipherBytes) = Unpack(packedBytes);    using (var aes = Aes.Create())    {        using (ICryptoTransform decryptor = aes.CreateDecryptor(key, iv))        {            return decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);        }    }}

其中公共方法:

// 代码按原样提供,可随意使用,但不对其安全性作任何保证。byte[] PasswordToKey(string password, string purpose){    using (var hmac = new HMACMD5(Encoding.UTF8.GetBytes(purpose)))    {        return hmac.ComputeHash(Encoding.UTF8.GetBytes(password));    }}string Base64UrlEncode(byte[] bytes){    return Convert.ToBase64String(bytes)            .Replace("/", "_")            .Replace("+", "-")            .Replace("=", "");}byte[] Base64UrlDecode(string base64Url){    return Convert.FromBase64String(base64Url        .Replace("_", "/")        .Replace("-", "+"));}(byte version, byte[] iv, byte[] cipherBytes) Unpack(byte[] packedBytes){    if (packedBytes[0] == 1)    {        // version 1        return (1, packedBytes[1..1 + 16], packedBytes[1 + 16..]);    }    else    {        throw new NotImplementedException("unknown version");    }}byte[] Pack(byte version, byte[] iv, byte[] cipherBytes){    return new[] { version }.Concat(iv).Concat(cipherBytes).ToArray();}

解释:

  • Base64UrlEncode/Decode:用于将字符串在Url上传输,将+/=转换成:-_

  • Pack/Unpack:将版本/初始向量/密文打包/解包

  • PasswordToKey:将长度不一样密码,加上purpose,转换为长度一样的key,其中改成HMACSHA256可以使用256位的AES算法。

测试代码:

// 代码按原样提供,可随意使用,但不对其安全性作任何保证。string purpose = "这个算法是用来搞SSO的";// 返回:AcfCe3AQcmNkeNThv-u09H_HyGKy_iRy-7uGiW0IZOHIEncrypt("密码here", purpose, Encoding.UTF8.GetBytes("Hello World"));// 返回:Hello WorldEncoding.UTF8.GetString(Decrypt("AcfCe3AQcmNkeNThv-u09H_HyGKy_iRy-7uGiW0IZOHI", "密码here", purpose));


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/315155.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Codeforces Round #709 (Div. 1) C. Skyline Photo dp + 单调栈优化

传送门 文章目录题意:思路:题意: 思路: 首先一个非常明显的dpdpdp式子就是f[i]max(f[j]val(j1,i))f[i]max(f[j]val(j1,i))f[i]max(f[j]val(j1,i)),其中val(j1,i)val(j1,i)val(j1,i)是[j1,i][j1,i][j1,i]中高度最小的美…

「数据分析」Sqlserver中的窗口函数的精彩应用之数据差距与数据岛(含答案)...

上一篇介绍过数据差距与数据岛的背景,这里不再赘述,请翻阅上一文。此篇在Sqlserver上给大家演示1000万条记录的计算性能。测试电脑软硬件说明一般般的笔记本电脑,2017年7月,价格:4500。电脑配置数据构造1000万行数据&a…

Codeforces Round #631 (Div. 2) C. Dreamoon Likes Coloring 构造

传送门 文章目录题意:思路:题意: 思路: 针灸思维不行,数据结构来凑呗。 一开始做的时候想简单了,一直wawawa,后来想到了hackhackhack样例,开始换思路构造,结果死活想不到…

用象棋的思维趣说IT人的职业发展和钱途

最近我花了不少功夫在学习象棋,也学习了王天一等高手的棋路,感觉IT人的职业和下棋一样,往好了讲,争主动权争实惠只争朝夕,往坏了讲,一步走错得用多步来弥补,如果错误太大未必能弥补回来。在本文…

Codeforces Round #631 (Div. 2) D. Dreamoon Likes Sequences 思维 + 组合数学

传送门 文章目录题意:思路:题意: 给你d,modd,modd,mod,让你求能构造出如下序列aaa的个数模modmodmod: 思路: 首先可以发现aaa的长度不能超过log2dlog_2dlog2​d,因为如果存在两个aaa的二进制…

基于 Roslyn 实现动态编译

基于 Roslyn 实现动态编译Intro之前做的一个数据库小工具可以支持根据 Model 代码文件生成创建表的 sql 语句,原来是基于 CodeDom 实现的,最近改成使用基于 Roslyn 去做了。实现的原理在于编译选择的Model 文件生成一个程序集,再从这个程序集…

Codeforces Round #212 (Div. 2) C. Insertion Sort 思维

传送门 文章目录题意:思路:题意: n≤5000n\le5000n≤5000 思路: 从dpdpdp题集中看到的,一看n≤5000n\le5000n≤5000,这不就乱搞就行了,哪有什么dpdpdp🦆。 看到冒泡排序&#xff0…

[Abp vNext 源码分析] - 4. 工作单元

一、简要说明统一工作单元是一个比较重要的基础设施组件,它负责管理整个业务流程当中涉及到的数据库事务,一旦某个环节出现异常自动进行回滚处理。在 ABP vNext 框架当中,工作单元被独立出来作为一个单独的模块(Volo.Abp.Uow)。你可以根据自己…

使用 Cake 推送 NuGet 包到 AzureDevops 的 Artifacts 上

大家好,我最近在想如何提交代码的时候自动的打包 NuGet 然后发布到 AzureDevOps 中的 Artifacts,在这个过程中踩了很多坑,也走了很多弯路,所以这次篇文章就是将我探索的结果和我遇到的一些问题整理分享给大家。我的上一篇关于 CI/…

了解Kubernetes主体架构(二十八)

前言 Kubernetes的教程一直在编写,目前已经初步完成了以下内容:1)基础理论2)使用Minikube部署本地Kubernetes集群3)使用Kubeadm创建集群接下来还会逐步完善本教程,比如Helm、ELK、Windows Serv…

Codeforces Round #632 (Div. 2) F. Kate and imperfection 数论 + 贪心

传送门 文章目录题意:思路:题意: n≤5e5n\le5e5n≤5e5 思路: 首先有个显然的结论:当往集合中加入一个数xxx的时候,如果存在d∣xd|xd∣x且ddd不在集合中,那么加入ddd一定比加入xxx更优。 也就是…

.NET开发框架(二)-框架功能简述

本框架为响应式SPA框架,支持PC与手机端的屏幕自适应。手机展示效果视频在文章末尾查看。框架入口地址:http://letyouknow.net/1、框架登录界面,输入账号与密码,点击立即登录2、框架主界面,左-右结构,左边为…

Codeforces Round #632 (Div. 2) E. Road to 1600 构造好题

传送门 文章目录题意:思路题意: 直接白嫖 思路 首先不难发现,n≤2n\le2n≤2的时候是无解的。 现在我们来构造n3n3n3的情况,通过打表可以发现如下矩阵是符合题目要求的: 179325486\begin{array}{ccc} 1&7&9…

SiteServer CMS 新版本 V6.11(2019年7月1日发布)

欢迎来到 SiteServer CMS V6.11版本(.NET CORE V7.0预览版本将推迟至2019年9月1日发布),经过两个月的连续迭代开发,V6.11 版本新增了采集插件以及多项BUG修复:SS.Gather 页面采集插件页面采集插件将在V6.11版本中正式提…

P1020 [NOIP1999 普及组] 导弹拦截 Dilworth定理 + dp

传送门 文章目录题意:思路:题意: 思路: 对于第一问直接输出最长不严格下降子序列即可,第二问是Dilworth定理,变形比较多,之前也写过类似的,这里贴个证明。 //#pragma GCC optimiz…

参数传递机制之JWT

1. 什么是 JWTJWT 其全称为:JSON Web Token,简单地说就是 JSON 在 Web 上的一种带签名的标记形式。官方的定义如下:JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.…

Codeforces Round #709 (Div. 1) B. Playlist 链表维护 + bfs

传送门 文章目录题意:思路:题意: 思路: 紧跟刘爷脚步补题。 不难想到用链表维护下一个数是什么,这样就跟以前做过的一个题差不多了,首先将初始的时候删掉的点的前一个点即为题目中的AAA入队,让…

浅谈ASP.NET Core中IOC与DI的理解和使用

说起IOC和DI,使用过ASP.NET Core的人对这两个概念一定不陌生,早前,自己也有尝试过去了解这两个东西,但是一直觉得有点很难去理解,总觉得对其还是模糊不清,所以,趁着今天有空,就去把两个概念捋清…

一个通用数据库操作组件DBUtil(c#)、支持SqlServer、Oracle、Mysql、postgres、SQLITE

这是一个.net下操作数据库(结构数据库)的工具类,支持sqlserver、oracle、mysql、postgres、sqlite、access等常见数据库。注意:它并不是一个orm工具(常见的orm框架如:EF、Dapper等)。2.1 引入DBUtil依赖1. 首先打开vs(推荐vs2019)&#xff0c…

Educational Codeforces Round 37 (Rated for Div. 2) E. Connected Components? 暴力 + 补图的遍历

传送门 文章目录题意:思路:题意: n≤2e5,m≤2e5n\le2e5,m\le2e5n≤2e5,m≤2e5。 思路: 这是题是我上个题的一部分,算是个小知识点,暴力能过。 直接维护一个setsetset,让后遍历所有点&#xff…