密码学【一】
前言
在区块链的整个体系中大量使用了密码学算法,比如用于 PoW 的哈希算法,用于完整性验证的 Merkle Tree,用于交易签名与验证的数字签名算法,用于隐私保护的零知识证明等等。
可以说密码学是保证区块链安全的基石,而区块链的广泛应用也推进了密码学的发展。在区块链内核 CITA 的 v0.18 中,新增了「基于 Rust 语言的国密算法库」新特性。这次更新,使用户在尊重版权的前提下,即可自由调用 Rust 实现的国密算法库,来匹配业务场景所需的国密签名算法,大幅降低企业用户及开发者获得高性能区块链底层设计服务的成本,方便用户打造最贴近业务需求的区块链。
现代信息安全的基本要求:
- 信息的保密性 Confidentiality:防止信息泄漏给未经授权的人(加密解密技术)
- 信息的完整性 Integrity:防止信息被未经授权的篡改(消息认证码,数字签名)
- 认证性 Authentication:保证信息来自正确的发送者(消息认证码,数字签名)
- 不可否认性 Non-repudiation:保证发送者不能否认他们已发送的消息(数字签名)
目录
前言
一、什么是密码学
二、古典密码学
古典密码学中最经典的两种算法
置换密码
代换密码
位移密码
代换密码的破解和发展
古典密码学的特点
三、古典密码的代码案例
置换密码案例
代换密码案例
位移密码案例
凯撒密码案例
一、什么是密码学
密码学的英语单词是 Cryptograghy,是由希腊单词 Kryptos(隐藏)和 Graphin(写)派生出来的,最初代表的意思是用来隐秘的传递信息。隐藏和写就是隐写,在古典密码学的发展中就有一门称为隐写术的技术,比如说藏头诗就是一种隐写术。在《巨人的陨落》中,艾瑟尔和弟弟比利就是通过每隔两个单词就会加一个单词来作为加密后的密文,这也是隐写术的一个例子。隐写术发展到今天演变为数字水印技术,一般在文件中加一个标识信息(即数字水印),可以起到追踪溯源,防伪和版权保护的作用。
密码学是网络安全、信息安全、区块链等产品的基础,常见的非对称加密、对称加密、散列函数等,都属于密码学范畴。
密码学一开始的功能是在有恶意攻击者存在的环境下,保护双方通信安全,现在是用来保护信息安全的核心技术。
所以密码学旨在保护协议免受攻击者攻击的一种安全措施,使之成为安全协议
二、古典密码学
以时间划分,1976 年以前的密码算法都属于古典密码学,基本使用在军事机密和外交领域,它的特点就是加解密过程简单,一般用手工或机械就可以完成。古典密码学现在已经很少采用了,然而,研究古典密码的原理对于理解构造和分析现代密码都是十分有益的。尤其是对称加密技术,它就是从古典密码学中演化进来的。
密码学术语
- 明文:没有经过加密,任何人都能看得懂的文字
- 密文:经过加密后的文字
- 密钥:明文与密文转换的参数
古典密码学中最经典的两种算法
置换密码
又称换位密码,加密过程中明文的字母保持相同,但是顺序被打乱。只要把位置恢复,就能得到明文。
一个典型置换密码的例子:公元前 500 年的古希腊斯巴达邦城,存在一种叫做「棍子加密」的加密方法。找一个腰带,将信息横着写在腰带上,但是这个信息是完全打乱的,需要一个可以解密的棍子,将腰带缠绕在棍子上,就可以恢复出明文。这也是最简单的置换密码的方式。后来随着抽象代数的出现,有了矩阵之后,就可以做一个复杂的置换加密,对运算做一个置换,用置换矩阵来解密,恢复出明文。
代换密码
又称替换密码,明文中的每一个字符被替换成密文中的另一个字符。接收者对密文做反向替换就可以恢复明文。
位移密码
位移密码是代换密码其中的一种,最简单最典型的就是凯撒密码
凯撒密码:它是一种单表代换密码,加密方式就是通过对字母的位移进行加密,比如把字母表右移三位,上面是明文表,下面是对应的密文表。如下图所示:
代换密码的破解和发展
像凯撒密码一样,每一个都有相应代表的位置,像 A 代表着 D,B 代表这 E。单表代换密码就很容易被破解,只要用频率分析表就可以破解,这是根据人类自然语言中,字母出现的频率不同来进行破解的。比如英文 E 是使用最频繁的,其次是 T/R/N/I/O/A/S 等;有些字母使用的很少,例如 Z/J/K/Q/X 等,这样就可以获得英文字母使用频率分布表,这个表是根据几本书获得的频率分析来获得的,同时,统计双字母组合和三字母组合的使用频率也非常有用。
有了破解的方法后,密码学中也会相对应的出现防止破解的方法。
- 多名或同音代替密码
与简单代替密码类似,只是映射是一对多的,每个明文字母可以加密成多个密文字母。用已知明文攻击比较容易破解
- 多字母代替密码
每次对 L 个字母进行代换,隐藏或均匀化字母的自然频度,用于抵抗频率分析。比如 hill 密码,用已知明文攻击比较容易破解。
- 多表代替密码
多代替密码可以说是古典密码学的巅峰之作,是以一系列(两个以上)代换表依次对明文消息的字母进行代换的加密操作。先把明文分成多份,代换表有很多个,根据序列依次更换代换序列,对每个序列进行加密。典型的代换密码:vigenere cipher,博福特密码,enigma 密码机(这个密码机可以说是古典密码学中最厉害的一种,但是在 1940 年时,被图灵给破解了)。
古典密码学的特点
- 计算强度小
- 出现在 DES 之前
- 数据安全基于算法的保密。这和现代密码有很大的差距,只要知道加密方法,就能轻易的获取明文。现代的密码基于密钥的加密,算法都是公开的,而且公开的密码算法安全性更高,能被更多人评论和使用,加强漏洞的修补。
- 以字母表为主要加密对象。古典密码大多数是对有意义的文字进行加密,而现代密码是对比特序列进行加密。这也是现代密码和古典密码的区别,而且古典密码的分析方法也是用字母频率分析表来破解的。
- 替换和置换技术
- 密码分析方法基于字母与字母组合的频率特性以及明文的可读性
三、古典密码的代码案例
用html+js+node实现简单的置换密码、代换密码、位移密码、凯撒密码的加密以及解密
置换密码案例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><label for="plainText">明文</label><input type="text" name="" id="plainText"><button onclick="encipher()">加密</button><br>密文<input type="text" id="cipherText"> <button onclick="decrypt()">解密</button><br>原文<input type="text" name="" id="original">
</body>
<script>// 置换规则是反转function encipher() {let plainText = document.getElementById('plainText').value// 第一种:js自带反转方法/* split(""):根据空字符串拆分数组reverse():数组反转元素位置join(""):数组转回字符串,且不带分隔符*/let newPlainText = plainText.split("").reverse().join("")document.getElementById('cipherText').value = newPlainText// 第二种/* 使用遍历以及api charAt()定义新的空字符串,遍历str,charAt()是取字符串的一个字符(charAt() 方法可返回指定位置的字符。),先去最后一个字符,再取倒数第二个…以此类推。都放到新的字符串前面。这样就是倒序的了.*/let newPlainTexts = ""for(let i = 1; i<=plainTextl.length; i++){newPlainTexts = newPlainTexts + plainText.charAt(plainText.length-i)}document.getElementById('cipherText').value = newPlainTexts}function decrypt() {let cipherText = document.getElementById('cipherText').valuelet originalText = cipherText.split("").reverse().join("")document.getElementById('original').value = originalText}</script>
</html>
代换密码案例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><label for="plainText">明文:</label><input type="text" id="plainText"><button onclick="encipher()">加密</button><br><label for="cipherText">密文:</label><input type="text" id="cipherText"><button onclick="decrypt()">解密</button><br><label for="original">原文</label><input type="text" name="" id="original">
</body>
<script>//加密function encipher() {let plainText = document.getElementById("plainText").value;//替换表const key = {'a': 'w', 'b': 'v', 'c': 'q', 'd': 'k', 'e': 'i', 'f': 'g', 'g': 'c','h': 'x', 'i': 'u', 'j': 'r', 'k': 'l', 'l': 'j', 'm': 'e', 'n': 'b','o': 'y', 'p': 't', 'q': 'p', 'r': 'm', 's': 'h', 't': 'd', 'u': 'a','v': 'z', 'w': 's', 'x': 'o', 'y': 'n', 'z': 'f'};//将输入的明文统一转换为小写,便于匹配替换表/* js自带toLowerCase() 将字符串大写转换成小写js自带toUpperCase() 将字符串大写转换成小写*/plainText = plainText.toLowerCase();let cipherText = '';for (let i = 0; i < plainText.length; i++) {const char = plainText[i];cipherText += key[char];}document.getElementById("cipherText").value = cipherText;}// 解密function decrypt() {let cipherText = document.getElementById("cipherText").value;const key = {'w': 'a', 'v': 'b', 'q': 'c', 'k': 'd', 'i': 'e', 'g': 'f', 'c': 'g','x': 'h', 'u': 'i', 'r': 'j', 'l': 'k', 'j': 'l', 'e': 'm', 'b': 'n','y': 'o', 't': 'p', 'p': 'q', 'm': 'r', 'h': 's', 'd': 't', 'a': 'u','z': 'v', 's': 'w', 'o': 'x', 'n': 'y', 'f': 'z'};let original = ""for(let i = 0; i<cipherText.length; i++){let char = cipherText[i]char = key[char]original += char}document.getElementById("original").value = original;}</script>
</html>
当然不一定是用对象,也可以用数组,数组更简单一点
位移密码案例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=, initial-scale=1.0"><title>移位密码</title>
</head><body><h1>移位密码</h1><label for="plainText">明文:</label><input type="text" id="plainText"><br><label for="shift">偏移量:</label><input type="number" id="shift"><input type="checkbox" id="shiftDirection">左移位<button onclick="encipher()">加密or解密</button><br><label for="cipherText">密文:</label><input type="text" id="cipherText" >
</body>
<script>// 加密function encipher() {let plainText = document.getElementById("plainText").value;const shift = parseInt(document.getElementById("shift").value);const isLeftShift = document.getElementById("shiftDirection").checked;plainText = plainText.toLowerCase();var cipherText = "";for (var i = 0; i < plainText.length; i++) {var char = plainText[i];/* match是js自带的一个函数用于匹配字符串内的元素正则:match(/元素/可选参数) 普通:match("元素")可选参数: g全局匹配 i不区分大小写匹配 gi全局不分大小写*/if (char.match(/[a-z]/i)) {// 移位右加左减const code = plainText.charCodeAt(i);var shiftedCode;if (isLeftShift) {shiftedCode = code - shift;} else {shiftedCode = code + shift;}// 解决头尾问题if (char.match(/[a-z]/)) {if (char.match(/[a-z]/) && shiftedCode < 97) {shiftedCode += 26;} else if (char.match(/[a-z]/) && shiftedCode > 122) {shiftedCode -= 26;}}// 将unicode值转回字符 String.fromCharCode()char = String.fromCharCode(shiftedCode);}cipherText += char;}document.getElementById("cipherText").value = cipherText;}</script></html>
右移的可以使用左移恢复明文,左移的可以使用右移恢复
bug:不区分大小写
以下凯撒密码解决该bug
凯撒密码案例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=, initial-scale=1.0"><title>Document</title>
</head><body><h1>凯撒密码</h1>明文:<input type="text" id="plaintext"><br>偏移值:<input type="number" id="shift"><br><button onclick="encrypt()">加密</button><button onclick="decrypt()">解密</button><br>密文:<input type="text" id="ciphertext" readonly><br>解密后:<input type="text" id="decryptedText" readonly>
</body></html><script>// 处理加密按钮点击事件 function encrypt() {let plaintext = document.getElementById("plaintext").value;let shift = parseInt(document.getElementById("shift").value);let ciphertext = caesarCipherEncrypt(plaintext, shift);document.getElementById("ciphertext").value = ciphertext;}// 处理解密按钮点击事件 function decrypt() {let ciphertext = document.getElementById("ciphertext").value;let shift = parseInt(document.getElementById("shift").value);let decryptedText = caesarCipherDecrypt(ciphertext, shift);document.getElementById("decryptedText").value = decryptedText;} // 凯撒密码加密函数 function caesarCipherEncrypt(text, shift) {let encryptedText = "";for (let i = 0; i < text.length; i++) {let char = text[i];if (char.match(/[a-z]/i)) {let code = char.charCodeAt();if (code >= 65 && code <= 90) { char = String.fromCharCode(((code - 65 + shift) % 26) + 65);} else if (code >= 97 && code <= 122) {char = String.fromCharCode(((code - 97 + shift) % 26) + 97);}} encryptedText += char;} return encryptedText; }// 凯撒密码解密函数 function caesarCipherDecrypt(text, shift) {let decryptedText = "";for (let i = 0; i < text.length; i++) {let char = text[i];if (char.match(/[a-z]/i)) {let code = char.charCodeAt();if (code >= 65 && code <= 90) {char = String.fromCharCode(((code - 65 - shift + 26) % 26) + 65);}else if (code >= 97 && code <= 122) { // 小写字母 char = String.fromCharCode(((code - 97 - shift + 26) % 26) + 97);}} decryptedText += char;} return decryptedText;}</script>
相关文章:

密码学【一】
前言 在区块链的整个体系中大量使用了密码学算法,比如用于 PoW 的哈希算法,用于完整性验证的 Merkle Tree,用于交易签名与验证的数字签名算法,用于隐私保护的零知识证明等等。 可以说密码学是保证区块链安全的基石,而区…...
企业如何选择舆情优化处置公司?
随着互联网的发展成熟,网络上的信息量已经非常之巨大,网络上的海量信息有对企业有利的,其实也有一些企业经营不利的,让不利的信息下沉,让有利的信息排上搜索首页,这就是舆情优化的简单表述。 对于大中型企业…...

HBASE知识点
HBASE是什么? 高可靠、高性能、面向列、可伸缩、实时读写的分布式数据库。利用HDFS作为其文件存储系统,利用MapReduce来处理HBase中的海量数据。利用Zookeeper作为其分布式协同服务。用于存储非结构化和半结构化的松散数据。 HBase数据模型 RowKey: 唯…...

Python新手入门
文章目录 概要python代码运行结果小结 概要 以下内容为python各种输出语句的语法! python代码 # 标准化输出 print("这是标准化输出!")# 格式化输出 print("这是第1种%s"%"格式化输出!") print("这是第…...

vite + react + typescript + uni-app + node 开发一个生态系统
简介 使用 vite react typescript uni-app node 来开发一个简易的生态系统案例,包含 APP,H5,微信小程序,控制台,服务端 开发 admin 技术栈:vite react typescript初始化控制台项目选择自定义预设…...
python pdf文件转图片
在Python中,有很多的第三方库可以用于PDF文件的转换,比如PyPDF2和pdf2image。 其中PyPDF2可以从PDF文件中提取每一页并将其保存为图像文件,需要安装Pillow库。 pdf2image则直接将PDF文件转换为PNG或JPEG图像文件,可以使用ImageM…...

牛客: BM7 链表中环的入口结点
牛客: BM7 链表中环的入口结点 文章目录 牛客: BM7 链表中环的入口结点题目描述题解思路题解代码 题目描述 题解思路 用一个哈希表存储链表节点,遍历链表,将节点加入哈希表,如果该节点在哈希表中出现过,意味着该节点是入口节点 题解代码 package mainfunc EntryNodeOfLoop(p…...

SpringMVC系列(七)之自定义注解
目录 一. Java注解简介 1.1 Java注解分类 1.2 JDK基本注解 Override Deprecated SuppressWarnings 1.3 JDK元注解 从 Java 7 开始,额外添加了 3 个注解: 1.4 自定义注解 如何自定义注解? 二. 自定义注解示例 枚举类: 示例一&…...

MongoDB的搭建 和crud操作
MongoDB docker 下载 docker run --restartalways -d --name mongo -v /docker/mongodb/data:/data/db -p 27017:27017 mongo:4.0.6使用navcat工具使用MongoDB Crud操作 jar包 <dependency><groupId>org.projectlombok</groupId><artifactId>lom…...

软件设计师考试学习1
前言 计算机组成原理及体系结构 数据的表示 进制的转换 原码反码补码移码 最高位是符号位,负数符号位为1 反码补码正数和原码一样,负数有区别 反码符号位不动,其他位置取反 补码在反码基础上加1 移码是将补码的符号为取反 在原码和反码中…...

【云计算】虚拟私有云 VPC
虚拟私有云 VPC 1.前言1.1 基本介绍1.2 VPC 的作用1.3 VPC 的适用人群 2.VPC 基本概念2.1 VPC 相关基本概念2.2 其他相关基本概念 3.VPC 通信场景3.1 VPC 内部互通3.2 VPC 间互通3.2.1 对等连接3.2.2 Transit Gateway 或者云联网 3.3 访问 Internet3.3.1 Internet 网关3.3.2 NA…...

@EventListener 监听事件 ,在同一个虚拟机中如何保证顺序执行
文章目录 前言EventListener 监听事件 ,在同一个虚拟机中如何保证顺序执行1. 设计原理2. 具体编码2.1. 编码事件监听器2.2. 制作一个生成序号方法2.3. 制作测试代码2.4. 测试结果 前言 如果您觉得有用的话,记得给博主点个赞,评论,…...

数据结构入门 — 树的概念与结构
本文属于数据结构专栏文章,适合数据结构入门者学习,涵盖数据结构基础的知识和内容体系,文章在介绍数据结构时会配合上动图演示,方便初学者在学习数据结构时理解和学习,了解数据结构系列专栏点击下方链接。 博客主页&am…...

linux驱动开发day6--(epoll实现IO多路复用、信号驱动IO、设备树以及节点和属性解析相关API使用)
一、IO多路复用--epoll实现 1.核心: 红黑树、一张表以及三个接口、 2.实现过程及API 1)创建epoll句柄/创建红黑树根节点 int epfdepoll_create(int size--无意义,>0即可)----------成功:返回根节点对应文件描述符…...

9月15日作业
Qt代码 #include "mywnd.h"//构造函数的定义 mywnd::mywnd(QWidget *parent): QWidget(parent) //显性调用父类的有参构造完成对子类从父类继承下来成员的初始化工作 {//窗口设置this->resize(QSize(500, 433));this->setWindowTitle("Widget&quo…...
关于Java多线程的那些事
多线程 多线程1. 关于多线程的理解1.1 进程和线程1.2 并行和并发1.3 线程调度 2. 创建多线程的方式创建线程有哪几种方式?2.1 通过继承Thread类来创建并启动线程的步骤如下:2.2 通过实现Runnable接口来创建并启动线程的步骤如下:2.3 通过实现…...

信息化项目验收的依据、内容和验收测评报告
随着信息系统业务覆盖率的提高和深度整合创新的逐步提高,信息系统运行阶段的复杂性和资源比例逐渐增加。一方面,信息已成为业务创新、技术应用和运营服务的综合体,而不仅仅是技术平台建设。另一方面,信息采购是技术平台建设。另一…...

解决IntelliJ IDEA执行maven打包,执行java -jar命令提示jar中没有主清单属性
问题场景 IDEA执行mvn clean package -DskipTesttrue命令或者借助工具的Maven菜单进行打包操作,然后执行java -jar app.jar命令后,提示jar中没有主清单属性 D:\WorkSpace\demo\target>java -jar demo-SNAPSHOT.jar demo-SNAPSHOT.jar中没有主清单属性…...
Python--文件和异常
目录 1、读取文件 1.1 读取文件的全部内容 1.2 相对路径和绝对路径 1.3 访问文件中的各行 1.4 使用文件中的内容 1.5 包含100万位的大型文件 1.6 圆周率中的生日 2、写入文件 2.1 写入一行 2.2 写入多行 3、异常 3.1 处理ZeroDivisionError 异常 3.2 使用try-exce…...

IDEFICS 简介: 最先进视觉语言模型的开源复现
我们很高兴发布 IDEFICS ( Image-aware Decoder Enhanced la Flamingo with Ininterleaved Cross-attention S ) 这一开放视觉语言模型。IDEFICS 基于 Flamingo,Flamingo 作为最先进的视觉语言模型,最初由 DeepMind 开发,但目前尚未公开发布…...

React第五十七节 Router中RouterProvider使用详解及注意事项
前言 在 React Router v6.4 中,RouterProvider 是一个核心组件,用于提供基于数据路由(data routers)的新型路由方案。 它替代了传统的 <BrowserRouter>,支持更强大的数据加载和操作功能(如 loader 和…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官
。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量:setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...

java高级——高阶函数、如何定义一个函数式接口类似stream流的filter
java高级——高阶函数、stream流 前情提要文章介绍一、函数伊始1.1 合格的函数1.2 有形的函数2. 函数对象2.1 函数对象——行为参数化2.2 函数对象——延迟执行 二、 函数编程语法1. 函数对象表现形式1.1 Lambda表达式1.2 方法引用(Math::max) 2 函数接口…...

yaml读取写入常见错误 (‘cannot represent an object‘, 117)
错误一:yaml.representer.RepresenterError: (‘cannot represent an object’, 117) 出现这个问题一直没找到原因,后面把yaml.safe_dump直接替换成yaml.dump,确实能保存,但出现乱码: 放弃yaml.dump,又切…...