对称加密算法解析:DES、AES及其在`pycryptodome` 和 `crypto-js` 模块中的应用
📚 对称加密算法解析:DES、AES及其在pycryptodome 和 crypto-js 模块中的应用
🗝️ DES 算法
算法原理
数据加密标准(DES)是一种对称密钥加密算法,用于保护数据的安全。DES 使用一个 56 位的密钥进行加密和解密,将数据块分为 64 位的块进行处理。DES 是一种 Feistel 网络,每个数据块经过 16 轮的处理,其中包括置换和替换操作,以实现加密。
主要原理:
- 密钥调度:将 64 位的密钥压缩成 56 位,并通过循环左移生成 16 个子密钥。
- 初始置换(IP):对输入数据块进行初始置换。
- 轮函数:每一轮包含扩展置换、S-盒替换、P-盒置换和异或操作。
- 逆初始置换(IP-1):在所有轮处理完后,对数据进行逆初始置换得到最终的密文。
Python 实现
使用 pycryptodome 库来实现 DES 加密和解密:
from Crypto.Cipher import DES
from Crypto.Util.Padding import pad, unpaddef des_encrypt_decrypt(data, key, mode):cipher = DES.new(key, DES.MODE_ECB)if mode == 'encrypt':# 填充数据至 DES 块大小padded_data = pad(data.encode('utf-8'), DES.block_size)encrypted_data = cipher.encrypt(padded_data)return encrypted_dataelif mode == 'decrypt':decrypted_data = cipher.decrypt(data)unpadded_data = unpad(decrypted_data, DES.block_size)return unpadded_data.decode('utf-8')else:raise ValueError("Invalid mode. Choose 'encrypt' or 'decrypt'.")# 示例
key = b'8bytekey' # 8 字节的密钥
data = "Hello, DES!"
encrypted = des_encrypt_decrypt(data, key, 'encrypt')
decrypted = des_encrypt_decrypt(encrypted, key, 'decrypt')print("Encrypted:", encrypted)
print("Decrypted:", decrypted)
输入输出示例:
- 输入:
"Hello, DES!", 密钥:b'8bytekey' - 输出:
- 加密结果:
b'\x9d\xc2\xa5\x16\x19\x1c\xf3\x8f' - 解密结果:
"Hello, DES!"
- 加密结果:
JavaScript 实现(使用 crypto-js 模块)
const CryptoJS = require('crypto-js');function desEncryptDecrypt(data, key, mode) {const keyHex = CryptoJS.enc.Utf8.parse(key);if (mode === 'encrypt') {const encrypted = CryptoJS.DES.encrypt(data, keyHex, { mode: CryptoJS.mode.ECB });return encrypted.toString();} else if (mode === 'decrypt') {const decrypted = CryptoJS.DES.decrypt(data, keyHex, { mode: CryptoJS.mode.ECB });return decrypted.toString(CryptoJS.enc.Utf8);} else {throw new Error("Invalid mode. Choose 'encrypt' or 'decrypt'.");}
}// 示例
const key = '8bytekey'; // 8 字节的密钥
const data = 'Hello, DES!';
const encrypted = desEncryptDecrypt(data, key, 'encrypt');
const decrypted = desEncryptDecrypt(encrypted, key, 'decrypt');console.log("Encrypted:", encrypted);
console.log("Decrypted:", decrypted);
输入输出示例:
- 输入:
"Hello, DES!", 密钥:"8bytekey" - 输出:
- 加密结果:
"3B3d4a...bcd5"(加密的密文) - 解密结果:
"Hello, DES!"
- 加密结果:
🔐 AES 算法
算法原理
高级加密标准(AES)是对称密钥加密标准,用于替代 DES。AES 支持 128 位、192 位和 256 位密钥长度,并处理 128 位的块。AES 采用 10、12 或 14 轮的处理,取决于密钥的长度。
主要原理:
- 密钥扩展:从原始密钥生成多个轮密钥。
- 轮函数:每轮包含字节替换(SubBytes)、行移位(ShiftRows)、列混淆(MixColumns)和轮密钥加(AddRoundKey)操作。
- 最终轮:不包括列混淆操作。
Python 实现
使用 pycryptodome 库来实现 AES 加密和解密:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import osdef aes_encrypt_decrypt(data, key, mode):cipher = AES.new(key, AES.MODE_ECB)if mode == 'encrypt':# 填充数据至 AES 块大小padded_data = pad(data.encode('utf-8'), AES.block_size)encrypted_data = cipher.encrypt(padded_data)return encrypted_dataelif mode == 'decrypt':decrypted_data = cipher.decrypt(data)unpadded_data = unpad(decrypted_data, AES.block_size)return unpadded_data.decode('utf-8')else:raise ValueError("Invalid mode. Choose 'encrypt' or 'decrypt'.")# 示例
key = os.urandom(16) # 16 字节的密钥
data = "Hello, AES!"
encrypted = aes_encrypt_decrypt(data, key, 'encrypt')
decrypted = aes_encrypt_decrypt(encrypted, key, 'decrypt')print("Encrypted:", encrypted)
print("Decrypted:", decrypted)
输入输出示例:
- 输入:
"Hello, AES!", 密钥:b'...key...'(随机生成) - 输出:
- 加密结果:
b'\x1f\x23\xfe...78' - 解密结果:
"Hello, AES!"
- 加密结果:
JavaScript 实现(使用 crypto-js 模块)
const CryptoJS = require('crypto-js');function aesEncryptDecrypt(data, key, mode) {const keyHex = CryptoJS.enc.Hex.parse(key);if (mode === 'encrypt') {const encrypted = CryptoJS.AES.encrypt(data, keyHex, { mode: CryptoJS.mode.ECB });return encrypted.toString();} else if (mode === 'decrypt') {const decrypted = CryptoJS.AES.decrypt(data, keyHex, { mode: CryptoJS.mode.ECB });return decrypted.toString(CryptoJS.enc.Utf8);} else {throw new Error("Invalid mode. Choose 'encrypt' or 'decrypt'.");}
}// 示例
const key = CryptoJS.enc.Hex.parse('00112233445566778899aabbccddeeff'); // 16 字节密钥
const data = 'Hello, AES!';
const encrypted = aesEncryptDecrypt(data, key, 'encrypt');
const decrypted = aesEncryptDecrypt(encrypted, key, 'decrypt');console.log("Encrypted:", encrypted);
console.log("Decrypted:", decrypted);
输入输出示例:
- 输入:
"Hello, AES!", 密钥:"00112233445566778899aabbccddeeff" - 输出:
- 加密结果:
"U2FsdGVkX1+...7w=="(加密的密文) - 解密结果:
"Hello, AES!"
- 加密结果:
🛠️ 拓展用法
1. 加盐(仅适用于 DES 和 AES)
Python 实现:
from Crypto.Random import get_random_bytesdef aes_encrypt_with_salt(data, key, salt):key_with_salt = key + saltcipher = AES.new(key_with_salt[:16], AES.MODE_ECB)padded_data = pad(data.encode('utf-8'), AES.block_size)encrypted_data = cipher.encrypt(padded_data)return encrypted_data# 示例
key = get_random_bytes(16)
salt = get_random_bytes(8)
data = "Hello, AES with Salt!"
encrypted = aes_encrypt_with_salt(data, key, salt)print("Encrypted with Salt:", encrypted)
输入输出示例:
- 输入:
"Hello, AES with Salt!", 密钥:b'...'(随机生成), 盐值:b'...'(随机生成) - 输出:
- 加密结果:
b'\x12\x34\x56\x78...ef'(加密的密文)
- 加密结果:
2. 哈希化密钥(密钥衍生)
Python 实现:
from Crypto.Protocol.KDF import scryptdef derive_key(password, salt):return scrypt(password.encode('utf-8'), salt, 16, N=2**14, r=8, p=1)# 示例
password = "mysecretpassword"
salt = get_random_bytes(16)
derived_key = derive_key(password, salt)
print("Derived Key:", derived_key)
**输入
输出示例**:
- 输入: 密码:
"mysecretpassword", 盐值:b'...'(随机生成) - 输出:
- 派生密钥:
b'...'(派生的密钥)
- 派生密钥:
3. 修改加密算法参数(如填充方式)
Python 实现:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpaddef aes_encrypt_with_custom_padding(data, key, padding_length):cipher = AES.new(key, AES.MODE_ECB)padded_data = data.encode('utf-8') + bytes([padding_length] * padding_length)encrypted_data = cipher.encrypt(padded_data)return encrypted_data# 示例
key = get_random_bytes(16)
data = "Hello, Custom Padding!"
encrypted = aes_encrypt_with_custom_padding(data, key, 16)print("Encrypted with Custom Padding:", encrypted)
输入输出示例:
- 输入:
"Hello, Custom Padding!", 密钥:b'...'(随机生成), 填充长度:16 - 输出:
- 加密结果:
b'...'(加密的密文)
- 加密结果:
4. 密钥扩展(从较短密钥生成较长密钥)
Python 实现:
from Crypto.Hash import SHA256def extend_key(short_key):return SHA256.new(short_key).digest()# 示例
short_key = b'shortkey'
extended_key = extend_key(short_key)
print("Extended Key:", extended_key)
输入输出示例:
- 输入: 短密钥:
b'shortkey' - 输出:
- 扩展密钥:
b'...'(扩展后的密钥)
- 扩展密钥:
5. 加密的哈希化(加密后哈希化)
Python 实现:
from Crypto.Hash import SHA256def hash_after_encryption(encrypted_data):hash_object = SHA256.new(data=encrypted_data)return hash_object.hexdigest()# 示例
data = "Hello, Hash after Encryption!"
encrypted = aes_encrypt_decrypt(data, key, 'encrypt')
hashed = hash_after_encryption(encrypted)print("Hashed Encrypted Data:", hashed)
输入输出示例:
- 输入:
"Hello, Hash after Encryption!", 加密数据:b'...' - 输出:
- 哈希值:
"d2d2d2d2d2...d2d2"
- 哈希值:
以上示例展示了 DES 和 AES 对称加密算法的基本使用方法,以及如何在 Python 和 JavaScript 中实现这些算法。此外,还涵盖了一些拓展用法,例如加盐、密钥衍生、修改加密算法参数等。这些方法为实际应用中的加密需求提供了丰富的解决方案。
相关文章:
对称加密算法解析:DES、AES及其在`pycryptodome` 和 `crypto-js` 模块中的应用
📚 对称加密算法解析:DES、AES及其在pycryptodome 和 crypto-js 模块中的应用 🗝️ DES 算法 算法原理 数据加密标准(DES)是一种对称密钥加密算法,用于保护数据的安全。DES 使用一个 56 位的密钥进行加密…...
C++设计模式(代理模式)
1. 电话虫 在海贼中,有一种神奇的通信工具叫做电话虫(Den Den Mushi),外形如蜗牛,身上带有斑点或条纹或通体纯色,壳顶上有对讲机或按键,不接通时会睡觉,接通时会惊醒,并发…...
Linux系统驱动(十三)Linux内核定时器
文章目录 一、内核定时器原理二、定时器API三、使用定时器让LED灯闪烁四、使用定时器对按键进行消抖 一、内核定时器原理 内核当前时间通过jiffies获取,它是内核时钟节拍数,在linux内核启动的时候,jiffies开始(按照一定频率&…...
Visual Studio 调试时加载符号慢
什么是调试符号 编译程序时生成的一组特殊字符,并包含有关变量和函数在生成的二进制文件中的位置以及其他服务信息的信息。 该数据集可用于逐步调试程序或检查第三方代码。 调试符号可以添加到可执行文件或库中,但是大多数现代编译器将它们存储为单独的…...
Spring Cloud Config:动态配置的魔法师
Spring Cloud Config:动态配置的魔法师 在微服务架构的浩瀚星海中,配置管理如同一颗璀璨的星辰,而Spring Cloud Config则是那颗能够实现配置信息集中管理和动态刷新的魔法星。本文将深入探索Spring Cloud Config的奥秘,揭示如何通…...
Webpack入门基础知识及案例
webpack相信大家都已经不陌生了,应用程序的静态模块打包工具。前面我们总结了vue,react入门基础知识,也分别做了vue3的实战小案例,react的实战案例,那么我们如何使用webpack对项目进行模块化打包呢? 话不多…...
对中国人工智能与国外人工智能的思考
作为一名语文老师,我在教育的领域中见证着时代的变迁,也关注着科技的发展,尤其是人工智能这一前沿领域。当我们将目光投向中国人工智能与国外人工智能的发展时,心中不禁涌起诸多思考。 中国的人工智能近年来犹如一颗璀璨的新星&am…...
【debian系统arm架构安装docker】且换源后依旧不行就离线导入镜像
安装docker 在Debian系统上安装Docker并使用阿里云的镜像源可以通过以下步骤完成 1.更新软件包索引 前置如果需要更换源的请移步 : 初始化配置(自动连wifi,自动开启SSH)换清华源,远程桌面连接 sudo apt-get update2.安装必要的软件包以允许apt通过HTTPS使用仓库 sudo apt-get …...
Readwise 官方 Obsidian 插件使用
Readwise 官方 Obsidian 插件简介 Obsidian 中的 Readwise 注释示例 阅读已经发布了官方插件来导入你的 Readwise 数据Obsidian 。如果你还没有使用过 Readwise,那么值得一看。Readwise 是我最喜欢的 应用之一。我每天都在用它。因此,将这些数据自动导…...
A. A+B Again?
time limit per test 1 second memory limit per test 256 megabytes Given a two-digit positive integer nn, find the sum of its digits. Input The first line contains an integer tt (1≤t≤901≤t≤90) — the number of test cases. The only line of each tes…...
pr样机模板视频素材|城市户外高速路广告牌视频样机
https://prmuban.com/40369.html pr样机素材,全高清实景城市户外高速路广告牌视频样机模板,适合宣传视频制作。 主要特点: Adobe Premiere Pro 2024 全高清分辨率(19201080) 易于使用 快速渲染 无需插件 预览中使用的…...
谷歌大中华区总裁:所有企业都在问这个问题
中国开发者对于出海的热情,令Google大中华区总裁陈俊廷感慨。2024 Google I/O Connect(2024Google开发者大会)期间,他在接受第一财经记者独家采访时提到一个细节:早上7:30,他来到会场时,人们已经…...
GPT-4o:AI视觉识别的革命性飞跃
在AI的宏伟叙事中,图像识别技术始终扮演着关键角色。随着技术的不断演进,AI的视界已超越了简单的图像内容识别,它现在能够将视觉信息转化为引人入胜的文字描述。OpenAI最新力作——GPT-4o模型,以其卓越的多模态理解能力࿰…...
将电脑打造成私人网盘,支持外网访问之详细操作教程
你想过把自己电脑打造成随时随地访问的网盘吗?就是那种拥有一个属于自己的影音库,不用担心被和谐,随时可以登录访问电脑上的各种文件,相比传统网盘省心又安全。 使用Everything和节点小宝将电脑搭建成私人网盘,可以实现…...
spring同一个接口如何分页实现主表或主+联表group by查询
1 需求背景 我们的上游系统想要知道主表的记录关联子表所有记录中是否有一条满足特定的条件,如果有满足的就返回主表中的id。比如品牌brand主表中id为10的记录,在子表brand_rel中有id为1,2,3,4的这四个记录࿰…...
SpringDataJpa源码分析
我们在定义Repository的时候通常定义的时一个接口,而并没有去实现这个接口,那么Jpa是如何让开发者无需自己实现接口就可以使用Repository去操作数据库? 动态代理!!! Repository原理 试想一下JPA是如何做的…...
卷积神经网络 - 卷积神经网络与深度学习的历史篇
序言 卷积神经网络( Convolutional Neural Networks, CNN \text{Convolutional Neural Networks, CNN} Convolutional Neural Networks, CNN)与深度学习作为人工智能领域的两大重要分支,其发展历程充满了探索与突破。深度学习,作…...
初识 Floodfall 算法
文章目录 **一、Floodfall 算法的概述****二、深度优先搜索(DFS)和广度优先搜索(BFS)在 Floodfall 算法中的应用****三、算法的基本原理****四、应用场景** 一、Floodfall 算法的概述 Floodfall 算法通常用于解决与区域填充、图的…...
[Linux] LVM挂载的硬盘重启就掉的问题解决
问题:系统重启后挂在逻辑卷的盘会掉(必现) 环境:SUSE Linux 11 SP4 原因:boot.lvm是关闭的 解决:boot.lvm设置开启 参考资料: linux下lvm状态Not avaliable问题排查及处理(常见Suse操作系统…...
YOLOv8改进 | 主干网络 | 用EfficientNet卷积替换backbone【教程+代码 】
秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录 :《YOLOv8改进有效涨点》专栏介绍 & 专栏目录 | 目前已有80+篇内容,内含各种Head检测头、损失函数Loss、…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)
一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解,适合用作学习或写简历项目背景说明。 🧠 一、概念简介:Solidity 合约开发 Solidity 是一种专门为 以太坊(Ethereum)平台编写智能合约的高级编…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...
如何配置一个sql server使得其它用户可以通过excel odbc获取数据
要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据,你需要完成以下配置步骤: ✅ 一、在 SQL Server 端配置(服务器设置) 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到:SQL Server 网络配…...
