对称加密,是一种比较传统的加密方式,其加密运算、解密运算使用的是同样的密钥,信息的发送者和信息的接收者在进行信息的传输与处理时,必须共同持有该密码(称为对称密码)。因此,通信双方都必须获得这把钥匙,并保持钥匙的秘密。
单钥密码系统的安全性依赖于以下两个因素:
第一、加密算法必须是足够强的,仅仅基于密文本身去解密信息在实践上是不可能的。
第二、加密方法的安全性依赖于密钥的秘密性,而不是算法的秘密性,因此,我们没有必要确保算法的秘密性(事实上,现实中使用的很多单钥密码系统的算法都是公开的),但是我们一定要保证密钥的秘密性。
DES(Data Encryption Standard)和TripleDES是对称加密的两种实现。
DES和TripleDES基本算法一致,只是TripleDES算法提供的key位数更多,加密可靠性更高。
DES使用的密钥key为8字节,初始向量IV也是8字节。
TripleDES使用24字节的key,初始向量IV也是8字节。
两种算法都是以8字节为一个块进行加密,一个数据块一个数据块的加密,一个8字节的明文加密后的密文也是8字节。如果明文长度不为8字节的整数倍,添加值为0的字节凑满8字节整数倍。所以加密后的密文长度一定为8字节的整数倍。
本文测试源代码:/Files/chnking/TripleDESTest.rar
Figure 1. DES加密解密过程
上图是整个DES和TripleDES算法的加密解密过程,下面以TripleDES为例,结合dotnet分析加密解密的各个步骤,并给出相关实现代码。
System.Security.Cryptography. TripleDESCryptoServiceProvider类是dotnet中实现TripleDES算法的主要的类。
TripleDESCryptoServiceProvider类只有一个构造方法TripleDESCryptoServiceProvider(),这个方法把一些属性初始化:
KeySize(加密密钥长度,以位为单位)= 192(24字节)
BlockSize(加密处理的数据块大小,以位为单位)= 64(8字节)
FeedbackSize(加密数据块后返回的数据大小,以位为单位)= 64(8字节)
TripleDESCryptoServiceProvider构造方法同时会初始化一组随机的key和IV。
默认的TripleDESCryptoServiceProvider的key为24字节,IV为8字节,加密数据块为8字节。
生成key和IV的代码很简单:
TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider();
byte[] keyArray = tDESalg.Key;
byte[] IVArray = tDESalg.IV;
生成的key和IV在加密过程和解密过程都要使用。
待加密的数据可能有两种形式,一种是二进制的数据,本身就是一组字节流,这样的数据可以跳过这一步,直接进入加密步骤。还有一种情况是字符串数据,字符串中同样的字符使用不同的代码页会生成不同的字节码,所以从字符串到字节流的转换是需要指定使用何种编码的。在解密之后,要从字节流转换到字符串就要使用相同的代码页解码,否则就会出现乱码。
// 待加密的字符串
string plainTextString = "Here is some data to encrypt. 这里是一些要加密的数据。";
// 使用utf-8编码(也可以使用其它的编码)
Encoding sEncoding = Encoding.GetEncoding("utf-8");
// 把字符串明文转换成utf-8编码的字节流
byte[] plainTextArray = sEncoding.GetBytes(plainTextString);
加密的原料是明文字节流,TripleDES算法对字节流进行加密,返回的是加密后的字节流。同时要给定加密使用的key和IV。
// 把字符串明文转换成utf-8编码的字节流
byte[] plainTextArray = sEncoding.GetBytes(plainTextString);
public static byte[] EncryptString(byte[] plainTextArray, byte[] Key, byte[] IV)
{
// 建立一个MemoryStream,这里面存放加密后的数据流
MemoryStream mStream = new MemoryStream();
// 使用MemoryStream 和key、IV新建一个CryptoStream 对象
CryptoStream cStream = new CryptoStream(mStream,
new TripleDESCryptoServiceProvider().CreateEncryptor(Key, IV),
CryptoStreamMode.Write);
// 将加密后的字节流写入到MemoryStream
cStream.Write(plainTextArray, 0, plainTextArray.Length);
//把缓冲区中的最后状态更新到MemoryStream,并清除cStream的缓存区
cStream.FlushFinalBlock();
// 把解密后的数据流转成字节流
byte[] ret = mStream.ToArray();
// 关闭两个streams.
cStream.Close();
mStream.Close();
return ret;
}
解密操作解密上面步骤生成的密文byte[],需要使用到加密步骤使用的同一组Key和IV。
// 调用解密方法,返回已解密数据的byte[]
byte[] finalPlainTextArray = DecryptTextFromMemory(Data, keyArray, IVArray);
public static byte[] DecryptTextFromMemory(byte[] EncryptedDataArray, byte[] Key, byte[] IV)
{
// 建立一个MemoryStream,这里面存放加密后的数据流
MemoryStream msDecrypt = new MemoryStream(EncryptedDataArray);
// 使用MemoryStream 和key、IV新建一个CryptoStream 对象
CryptoStream csDecrypt = new CryptoStream(msDecrypt,
new TripleDESCryptoServiceProvider().CreateDecryptor(Key, IV),
CryptoStreamMode.Read);
// 根据密文byte[]的长度(可能比加密前的明文长),新建一个存放解密后明文的byte[]
byte[] DecryptDataArray = new byte[EncryptedDataArray.Length];
// 把解密后的数据读入到DecryptDataArray
csDecrypt.Read(DecryptDataArray, 0, DecryptDataArray.Length);
msDecrypt.Close();
csDecrypt.Close();
return DecryptDataArray;
}
有一点需要注意,DES加密是以数据块为单位加密的,8个字节一个数据块,如果待加密明byte[]的长度不是8字节的整数倍,算法先用值为“0”的byte补足8个字节,然后进行加密。所以加密后的密文长度一定是8的整数倍。这样的密文解密后如果补了0值的byte,则解密后这些0值的byte依然存在。比如上例中要加密的明文是:
“Here is some data to encrypt. 这里是一些要加密的数据。”
转成明文byte[]后是66个字节,DES算法就会补上6个0值的byte,补到72个字节。这样加密后再解密回来的密文byte[]解码后的字符串就是这样的:
"Here is some data to encrypt. 这里是一些要加密的数据。\0\0\0\0\0\0"
// 使用前面定义的Encoding,utf-8的编码把byte[]转成字符串
plainTextString = sEncoding.GetString(finalPlainTextArray);
原网址: 访问
创建于: 2024-12-10 09:26:45
目录: default
标签: 无
未标明原创文章均为采集,版权归作者所有,转载无需和我联系,请注明原出处,南摩阿彌陀佛,知识,不只知道,要得到
java windows火焰图_mob64ca12ec8020的技术博客_51CTO博客 - 在windows下不可行,不知道作者是怎样搞的 监听SpringBoot 服务启动成功事件并打印信息_监听springboot启动完毕-CSDN博客 SpringBoot中就绪探针和存活探针_management.endpoint.health.probes.enabled-CSDN博客 u2u转换板 - 嘉立创EDA开源硬件平台 Spring Boot 项目的轻量级 HTTP 客户端 retrofit 框架,快来试试它!_Java精选-CSDN博客 手把手教你打造一套最牛的知识笔记管理系统! - 知乎 - 想法有重合-理论可参考 安宇雨 闲鱼 机械键盘 客制化 开贴记录 文本 linux 使用find命令查找包含某字符串的文件_beijihukk的博客-CSDN博客_find 查找字符串 ---- mac 也适用 安宇雨 打字音 记录集合 B站 bilibili 自行搭建 开坑 真正的客制化 安宇雨 黑苹果开坑 查找工具包maven pom 引用地 工具网站 Dantelis 介绍的玩轴入坑攻略 --- 关于轴的一些说法 --- 非官方 ---- 心得而已 --- 长期开坑更新 [本人问题][新开坑位]关于自动化测试的工具与平台应用 机械键盘 开团 网站记录 -- 能做一个收集的程序就好了 不过现在没时间 -- 信息大多是在群里发的 - 你要让垃圾佬 都去一个地方看难度也是很大的 精神支柱 [超级前台]sprinbboot maven superdesk-app 记录 [信息有用] [环境准备] [基本完成] [sebp/elk] 给已创建的Docker容器增加新的端口映射 - qq_30599553的博客 - CSDN博客 [正在研究] Elasticsearch, Logstash, Kibana (ELK) Docker image documentation elasticsearch centos 安装记录 及 启动手记 正式服务器 39 elasticsearch 问题合集 不断更新 6.1.1 | 6.5.1 两个版本 博客程序 - 测试 - bug记录 等等问题 laravel的启动过程解析 - lpfuture - 博客园 OAuth2 Server PHP 用 Laravel 搭建带 OAuth2 验证的 RESTful 服务 | Laravel China 社区 - 高品质的 Laravel 和 PHP 开发者社区 利用Laravel 搭建oauth2 API接口 附 Unauthenticated 解决办法 - 煮茶的博客 - SegmentFault 思否 使用 OAuth2-Server-php 搭建 OAuth2 Server - 午时的海 - 博客园 基于PHP构建OAuth 2.0 服务端 认证平台 - Endv - 博客园 Laravel 的 Artisan 命令行工具 Laravel 的文件系统和云存储功能集成 浅谈Chromium中的设计模式--终--Observer模式 浅谈Chromium中的设计模式--二--pre/post和Delegate模式 浅谈Chromium中的设计模式--一--Chromium中模块分层和进程模型 DeepMind 4 Hacking Yourself README.md update 20211011
Laravel China 简书 知乎 博客园 CSDN博客 开源中国 Go Further Ryan是菜鸟 | LNMP技术栈笔记 云栖社区-阿里云 Netflix技术博客 Techie Delight Linkedin技术博客 Dropbox技术博客 Facebook技术博客 淘宝中间件团队 美团技术博客 360技术博客 古巷博客 - 一个专注于分享的不正常博客 软件测试知识传播 - 测试窝 有赞技术团队 阮一峰 语雀 静觅丨崔庆才的个人博客 软件测试从业者综合能力提升 - isTester IBM Java 开发 使用开放 Java 生态系统开发现代应用程序 pengdai 一个强大的博主 HTML5资源教程 | 分享HTML5开发资源和开发教程 蘑菇博客 - 专注于技术分享的博客平台 个人博客-leapMie 流星007 CSDN博客 - 舍其小伙伴 稀土掘金 Go 技术论坛 | Golang / Go 语言中国知识社区
最新评论