我的编程空间,编程开发者的网络收藏夹
学习永远不晚

详解DES&3DES算法的原理以及C#和JS的实现

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

详解DES&3DES算法的原理以及C#和JS的实现

一、简介

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 class="lazy" data-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的实现的文章就介绍到这了,更多相关DES算法内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

详解DES&3DES算法的原理以及C#和JS的实现

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

详解DES&3DES算法的原理以及C#和JS的实现

DES 全称为 Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法。3DES 算法通过对 DES 算法进行改进,增加 DES 的密钥长度来避免类似的攻击。本文就来聊聊它们的原理与实现吧
2023-03-19

DES&3DES算法原理及C#和JS实现的方法是什么

这篇文章主要介绍“DES&3DES算法原理及C#和JS实现的方法是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“DES&3DES算法原理及C#和JS实现的方法是什么”文章能帮助大家解决问题。一、
2023-07-05

详解MD5算法的原理以及C#和JS的实现

MD5 是哈希算法(散列算法)的一种应用。这篇文章主要和大家介绍一下MD5算法的原理以及C#和JS的实现,文中的示例代码讲解详细,需要的可以参考一下
2023-03-19

详解DES加密算法的原理与Java实现

DES加密,是对称加密。对称加密,顾名思义,加密和解密的运算全都是使用的同样的秘钥。这篇文章主要为大家讲讲DES加密算法的原理与Java实现,需要的可以参考一下
2022-11-13

MD5算法原理及C#和JS实现的方法是什么

本篇内容主要讲解“MD5算法原理及C#和JS实现的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“MD5算法原理及C#和JS实现的方法是什么”吧!一、简介MD5 是哈希算法(散列算法)的
2023-07-05

SHA-256算法原理及C#和JS实现的方法是什么

本篇内容主要讲解“SHA-256算法原理及C#和JS实现的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“SHA-256算法原理及C#和JS实现的方法是什么”吧!一、简介SHA-256
2023-07-05

详解Bagging算法的原理及Python实现

目录一、什么是集成学习二、Bagging算法三、Bagging用于分类四、Bagging用于回归一、什么是集成学习 集成学习是一种技术框架,它本身不是一个单独的机器学习算法,而是通过构建并结合多个机器学习器来完成学习任务,一般结构是:先产生
2022-06-02

基数排序算法的原理与实现详解(Java/Go/Python/JS/C)

基数排序(RadixSort)是一种非比较型整数排序算法,其原理是将整数按位数切割成不同的数字,然后按每个位数分别比较。本文将利用Java/Go/Python/JS/C不同语言实现基数排序算法,感兴趣的可以了解一下
2023-03-06

SPFA算法的实现原理及其应用详解

SPFA算法,全称为Shortest Path Faster Algorithm,是求解单源最短路径问题的一种常用算法,本文就来聊聊它的实现原理与简单应用吧
2023-05-20

详解C++中vector的理解以及模拟实现

vector是表示可变大小数组的序列容器。这篇文章主要为大家详细介绍了vector的理解以及模拟实现,文中的示例代码讲解详细,感兴趣的可以了解一下
2023-03-08

t-SNE算法的原理和Python代码实现详解

T分布随机邻域嵌入(t-SNE),是一种用于可视化的无监督机器学习算法,使用非线性降维技术,根据数据点与特征的相似性,试图最小化高维和低维空间中这些条件概率(或相似性)之间的差异,以在低维空间中完美表示数据点。因此,t-SNE擅长在二维或三
t-SNE算法的原理和Python代码实现详解
2024-01-23

Java NIO多路复用的方法以及Linux epoll实现原理详解

这篇文章主要介绍“Java NIO多路复用的方法以及Linux epoll实现原理详解”,在日常操作中,相信很多人在Java NIO多路复用的方法以及Linux epoll实现原理详解问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作
2023-06-02

C++中内存池的简单原理及实现详解

内存池的思想是,在真正使用内存之前,预先申请分配一定数量、大小预设的内存块留作备用。本文主要来和大家聊聊内存池的简单原理及实现,希望对大家有所帮助
2023-03-01

详解RSA加密算法的原理与Java实现

这篇文章主要和大家分享非对称加密中的一种算法,那就是RSA加密算法。本文介绍了RSA算法的原理与Java实现,感兴趣的小伙伴可以尝试一下
2022-11-13

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录