〇、简介

1、DES 简介

DES 全称为 Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977 年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。

在很长时间内,许多人心目中“密码生成”与 DES 一直是个同义词。直到 1997 年 NIST(美国国家标准与技术研究院)开始公开征集更安全的加密算法以替代 DES,并在 2001 年推出了更加安全的 AES(Advanced Encryption Standard)高级加密标准。

优点:

  • Feistel 网络的轮数可以任意增加;
  • 解密与轮函数 f 无关,轮函数f也不需要有逆函数;
  • 轮函数可以设计得足够复杂;
  • 加密和解密可以使用完全相同的结构来实现。

缺点:

  • 分组比较短;
  • 密钥太短;
  • 密码生命周期短;
  • 运算速度较慢。

2、3DES 简介

其实并不是直接由 DES 过渡到 AES,还有一个 3DES 统治时期。3DES 也称 Triple DES,它使用 3 条 56 位的密钥对数据进行三次加密。

3DES 算法通过对 DES 算法进行改进,增加 DES 的密钥长度来避免类似的攻击,针对每个数据块进行三次 DES 加密;因此,3DES 加密算法并非什么新的加密算法,是 DES 的一个更安全的变形,它以 DES 为基本模块,通过组合分组方法设计出分组加密算法。

相比 DES,3DES 因密钥长度变长,安全性有所提高,但其处理速度不高。因此又出现了 AES 加密算法,AES 较于 3DES 速度更快、安全性也更高。

加密:

  • 为了兼容普通的 DES,3DES 并没有直接使用 加密->加密->加密 的方式,而是采用了 加密->解密->加密 的方式。
  • 当三重密钥均相同时,前两步相互抵消,相当于仅实现了一次加密,因此可实现对普通 DES 加密算法的兼容。

解密:

  • 3DES 解密过程,与加密过程相反,即逆序使用密钥。是以密钥 3、密钥 2、密钥 1的顺序执行 解密->加密->解密

一、C# 代码实现

1、DES

// 测试(密钥需要是八位字符)
string jiamihou = DesEncrypt("TestString", "11111222", false); // 57fe567eaa866373f851a526f07d9e26
string jiamiqian = DesDecrypt(jiamihou32, "11111222");
/// <summary>
/// DES加密字符串
/// </summary>
/// <param name="deseninstr">待加密的字符串</param>
/// <param name="deskey">加密密钥,要求为8位</param>
/// <param name="isupper">返回大写密文,false:小写</param>
/// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
public static string DesEncrypt(string deseninstr, string deskey, bool isupper = true)
{
StringBuilder stringBuilder = new StringBuilder();
try
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = Encoding.UTF8.GetBytes(deseninstr);
des.Key = Encoding.UTF8.GetBytes(deskey);
des.IV = Encoding.UTF8.GetBytes(deskey); // 当 mode 为 CBC 时,偏移量必传
des.Mode=CipherMode.ECB; // 为空默认 CBC
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, des.CreateEncryptor(), CryptoStreamMode.Write);
cryptoStream.Write(inputByteArray, 0, inputByteArray.Length);
cryptoStream.FlushFinalBlock();
foreach (byte bb in memoryStream.ToArray())
{
stringBuilder.AppendFormat(isupper ? "{0:X2}" : "{0:x2}", bb);
}
return stringBuilder.ToString();
}
catch (Exception ex)
{
return deseninstr;
}
}
/// <summary>
/// DES解密字符串
/// </summary>
/// <param name="desdeinstr">待解密的字符串</param>
/// <param name="deskey">解密密钥,要求为8位</param>
/// <returns>解密成功返回解密后的字符串,失败返源串</returns>
public static string DesDecrypt(string desdeinstr, string deskey)
{
MemoryStream memoryStream = new MemoryStream();
try
{
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = new byte[desdeinstr.Length / 2];
for (int ii = 0; ii < desdeinstr.Length / 2; ii++)
{
int intt = (Convert.ToInt32(desdeinstr.Substring(ii * 2, 2), 16));
inputByteArray[ii] = (byte)intt;
}
des.Key = Encoding.UTF8.GetBytes(deskey);
des.IV = Encoding.UTF8.GetBytes(deskey); // 当 mode 为 CBC 时,偏移量必传
des.Mode = CipherMode.ECB; // 为空默认 CBC
CryptoStream cs = new CryptoStream(memoryStream, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Encoding.UTF8.GetString(memoryStream.ToArray());
}
catch
{
return desdeinstr;
}
}

2、3DES

密文采用 Base64 格式输出。

疑问解答:三次加解密操作会运用三个不同的 Key,但是我们只传入了一个密钥,怎么回事?

  3DES 密钥必须为 24 位,为 DES 的 3 倍,经测试得出结论:

  •   TripleDESCryptoServiceProvider 内部将密钥分成 3 份,进行了加密解密三重操作。
  •   我们把 24 位字符串分成三部分,如果三部分均相等,或前两部分相等,就会报错:"Specified key is a known weak key for 'TripleDES' and cannot be used."--指定的密钥是'TripleDES'的已知弱密钥,不能使用。
// 测试
string jiamihou16 = SecurityDES.Des3Encrypt("TestString", "111112222233333444445555", "12345678"); // yJGf3qgWyoAQeaPY2S5Etg==
string jiamihou32 = SecurityDES.Des3Decrypt(jiamihou16, "111112222233333444445555", "12345678");
/// <summary>
/// 3DES 加密
/// </summary>
/// <param name="des3eninstr"></param>
/// <param name="des3key">24 位</param>
/// <param name="des3iv">8 位</param>
/// <returns></returns>
public static string Des3Encrypt(string des3eninstr, string des3key, string des3iv)
{
string encryptPassword = string.Empty;
SymmetricAlgorithm algorithm = new TripleDESCryptoServiceProvider();
algorithm.Key = Encoding.UTF8.GetBytes(des3key);// Convert.FromBase64String(des3key);
algorithm.IV = Encoding.UTF8.GetBytes(des3iv);
algorithm.Mode = CipherMode.ECB;
algorithm.Padding = PaddingMode.PKCS7;
ICryptoTransform transform = algorithm.CreateEncryptor();
byte[] data = Encoding.UTF8.GetBytes(des3eninstr);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Write);
cryptoStream.Write(data, 0, data.Length);
cryptoStream.FlushFinalBlock();
encryptPassword = Convert.ToBase64String(memoryStream.ToArray());
memoryStream.Close();
cryptoStream.Close();
return encryptPassword;
}
/// <summary>
/// 3DES 解密
/// </summary>
/// <param name="des3deinstr">密文 Base64</param>
/// <param name="des3key">24 位</param>
/// <param name="des3iv">8 位</param>
/// <returns></returns>
public static string Des3Decrypt(string des3deinstr, string des3key, string des3iv)
{
string decryptPassword = string.Empty;
SymmetricAlgorithm algorithm = new TripleDESCryptoServiceProvider();
algorithm.Key = Encoding.UTF8.GetBytes(des3key);
algorithm.IV = Encoding.UTF8.GetBytes(des3iv);
algorithm.Mode = CipherMode.ECB;
algorithm.Padding = PaddingMode.PKCS7;
ICryptoTransform transform = algorithm.CreateDecryptor(algorithm.Key, algorithm.IV);
byte[] buffer = Convert.FromBase64String(des3deinstr);
MemoryStream memoryStream = new MemoryStream(buffer);
CryptoStream cryptoStream = new CryptoStream(memoryStream, transform, CryptoStreamMode.Read);
StreamReader reader = new StreamReader(cryptoStream, System.Text.Encoding.ASCII);
decryptPassword = reader.ReadToEnd();
reader.Close();
cryptoStream.Close();
memoryStream.Close();
return decryptPassword;
}

二、js 语言实现

以下是通过 crypto-js.js 实现。

1、DES

注意:mode 为空默认 CBC,此时偏移量 iv 不可为空。

注意:密钥可用位数为 8,如果超过 8 位以后的对加密结果无影响,且不会报错。

// 先引入 js 文件
<script src="http://cdn.bootcdn.net/ajax/libs/crypto-js/4.0.0/crypto-js.js"></script>
// npm(Node.js package manager)方式
> npm install crypto-js // 调用方法 message() 查看测试结果
function message(){
var outdata_value = encryptByDES("TestString", "11111222");
alert(outdata_value) // 57fe567eaa866373f851a526f07d9e26
console.log("outdata_value-aes_encrypt:", outdata_value);
outdata_value = decryptByDES(outdata_value, "11111222");
alert(outdata_value)
console.log("outdata_value-aes_decrypt:", outdata_value);
}
//DES 加密
function encryptByDES(deseninstr, keystr, ivstr = keystr) {
var keybyte = CryptoJS.enc.Utf8.parse(keystr);
var ivbyte = CryptoJS.enc.Utf8.parse(ivstr);
let afterEncrypt = CryptoJS.DES.encrypt(deseninstr, keybyte, {
iv: ivbyte, // 当 mode 为 CBC 时,偏移量必传
mode: CryptoJS.mode.ECB, // 为空默认 CBC
padding: CryptoJS.pad.Pkcs7
}).ciphertext.toString()
console.log(afterEncrypt)
return afterEncrypt
}
//DES 解密
function decryptByDES(desdeinstr, keystr, ivstr = keystr) {
var keybyte = CryptoJS.enc.Utf8.parse(keystr);
var ivbyte = CryptoJS.enc.Utf8.parse(ivstr);
var decrypted = CryptoJS.DES.decrypt(
{ ciphertext: CryptoJS.enc.Hex.parse(desdeinstr) },
keybyte,
{
iv: ivbyte, // 当 mode 为 CBC 时,偏移量必传
mode: CryptoJS.mode.ECB, // 为空默认 CBC
padding: CryptoJS.pad.Pkcs7
}
);
console.log(decrypted);
var result_value = decrypted.toString(CryptoJS.enc.Utf8);
return result_value;
}

2、3DES

// 调用方法 message() 查看测试结果
function message() {
var outdata_value = encryptByDES("TestString", "111112222233333444445555");
alert(outdata_value) // yJGf3qgWyoAQeaPY2S5Etg==
console.log("outdata_value-3des_encrypt:", outdata_value);
outdata_value = decryptByDES(outdata_value, "111112222233333444445555");
alert(outdata_value)
console.log("outdata_value-3des_decrypt:", outdata_value);
}
// 加密 密钥需为 24 位,偏移量需为 8 位
function encryptByDES(deseninstr, keystr) {
var keybyte = CryptoJS.enc.Utf8.parse(keystr);
//var ivbyte = CryptoJS.enc.Utf8.parse(ivstr);
var encrypted = CryptoJS.TripleDES.encrypt(deseninstr, keybyte, {
// iv: ivbyte, // 当 mode 为 CBC 时,偏移量必传
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString();
}
// 解密 密钥需为 24 位,偏移量需为 8 位
function decryptByDES(desdeinstr, keystr) {
var keybyte = CryptoJS.enc.Utf8.parse(keystr);
//var ivbyte = CryptoJS.enc.Utf8.parse(ivstr);
var decrypted = CryptoJS.TripleDES.decrypt(desdeinstr, keybyte, {
// iv: ivbyte, // 当 mode 为 CBC 时,偏移量必传
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return decrypted.toString(CryptoJS.enc.Utf8);
}

DES & 3DES 简介 以及 C# 和 js 实现【加密知多少系列】的更多相关文章

  1. Java利用DES/3DES/AES这三种算法分别实现对称加密

    转载地址:http://blog.csdn.net/smartbetter/article/details/54017759 有两句话是这么说的: 1)算法和数据结构就是编程的一个重要部分,你若失掉了 ...

  2. 加密算法 DES 3DES RSA AES 简介

    数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为[密文],使其只能在输入相应的[密钥]之后才能显示出本来内容,通过这样的途径来达到保护数据不被非法人 ...

  3. DES & 3DES 加密算法

    JAVA坑 跟其他公司java的对接口,一个细节对到吐血,具体: DesUtil.java(别人的反例) //package base_class; import java.io.IOExceptio ...

  4. 使用openssl库实现des,3des加密

    原文地址: 使用openssl库实现des,3des加密 主要是调整了一下格式,以及一些变量的类型,以解决在VC2008下无法编译通过的问题. #include <stdio.h> #in ...

  5. DES加密解密 与 Cookie的封装(C#与js互相加密解密)

    2D JS框架 - DES加密解密 与 Cookie的封装(C#与js互相加密解密)   这次实现了JS端的DES加密与解密,并且C#端也能正确解析DES的密文(反之也实现了) 使用的代码如下,非常方 ...

  6. java和c++中的DES\3DES\Base64

    首先来看一段java中对字符串加解密的代码: //密钥 private String key = "123456789012345678901234"; //解密过程,先用Base ...

  7. Java Base64、HMAC、SHA1、MD5、AES DES 3DES加密算法

    ●  BASE64 严格地说,属于编码格式,而非加密算法    ●  MD5(Message Digest algorithm 5,信息摘要算法)    ●  SHA(Secure Hash Algo ...

  8. DES/3DES/AES 三种对称加密算法实现

    1. 简单介绍 3DES(或称为Triple DES)是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称.它相当于是对每个数据块应用三次DES ...

  9. 37.前台js登陆加密分析

    开篇 由于现在的登陆接口如果明文传输的话,容易被暴力破解,越来越多的网站选择了前台js加密的方式,像这样: 或者这样: 枯了,对渗透造成一定的影响 本篇文章将系统的讲述使用Python对前台js加密爆 ...

  10. node.js入门必知

    目录: 一.node.js简介 1.1特点 1.2适合开发什么 1.3Node.js无法挑战老牌后台语言 二.http模块 一.node.js简介 Node.js开发服务器,数据.路由.本地关心的效果 ...

随机推荐

  1. 【RTOS】《基于嵌入式实时操作系统的程序设计技术》——任务的划分与封装

    任务的划分与封装 关键任务的划分处理 对于某些对于系统的正常运作至关重要,少执行一次会对系统产生较大影响的功能,我们倾向于将它从原有任务中剥离出来,称为关键任务,用一个独立任务或者ISR(如外部中断) ...

  2. iOS开发--APP性能检测方案汇总

    1 . CPU 占用率 CPU作为手机的中央处理器,可以说是手机最关键的组成部分,所有应用程序都需要它来调度运行,资源有限.所以当我们的APP因设计不当,使 CPU 持续以高负载运行,将会出现APP卡 ...

  3. Git配置新学

    Git中的AutoCRLF与SafeCRLF换行符问题 https://zhuanlan.zhihu.com/p/380574688 https://xiaozhuanlan.com/topic/40 ...

  4. 学习&资源分享

    零 方法 1 学校图书馆官网(注意查看学校购买的数据库以及校外访问方法) 2 各省市图书馆官网(注册各地图书馆账号,注册方法见视频01:28)   一 论文 1 知网(图书馆进入) 2 Web of ...

  5. vc++生成随机数

    在VC++提供的函数为rand(),返回一个0至65535之间的随机数,若想产生0至MAX_NUM之间的随机数,可用rand()%MAX_NUM,即产生小于MAX_NUM的随机数 for (int i ...

  6. windows10安装ubuntu18.04(64位)双系统教程

    系统安装教程链接:https://www.cnblogs.com/masbay/p/11627727.html 系统安装完成后安装显卡驱动:https://ywnz.com/linux/4573.ht ...

  7. 使用@Param注解时注意org.springframework.data.repository.query.Param与org.apache.ibatis.annotations.Param的区别

    注解@Param有以下两种: 1.Spring org.springframework.data.repository.query.Param 2.mybatis org.apache.ibatis. ...

  8. axios使用总结

    一.请求配置 // 引入import axios from 'axios';import qs from 'qs';this.$axios({ method:"get", // g ...

  9. asm 理解

    stm32中有3条总线:地址总线,数据总线,系统总线:地址总线上是地址值,数据总线上是数据值,cpu读写时会先在地址总线上传输地址值,如果是写操作之后数据总线上会放往前面地址处写入的数据值,如果是读操 ...

  10. C#下解析、生成JAVA的RSA密钥、公钥

    1.从 https://www.nuget.org/packages/BouncyCastle/下载对应的nupkg包,放到本地一个文件夹中 2.打开VS2010,工具->NuGet程序包管理器 ...