文档章节

古典密码算法的实现

o
 osc_isezqdgg
发布于 2019/09/18 11:47
字数 1853
阅读 19
收藏 0

精选30+云产品,助力企业轻松上云!>>>

1、古典密码可以分为代替密码和置换密码两种,这里实现了代替密码中的仿射变换和置换密码中的换位变换。

 

2、仿射变换:

加密过程:e(x) = ax + b (mod m)

解密过程:d(e(x)) = a^(-1)*(e(x) - b) mod m

参数要求:a,m互质;a,b互质;m是集合中元素的个数。(例如当前取1~9和a~z中的所有元素作为集合,m为36)

加密实现:

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String []args) {
 5         int m = 36, thisNum, index = 0; // m是集合中元素的个数(例如当前取1~9和a~z中的所有元素作为集合,m为36)
 6         Scanner s = new Scanner(System.in);
 7         // 将输入的字符串转化为字符数组
 8         char[] buff = s.nextLine().toCharArray();
 9         // 参数a、b手动输入
10         int a = s.nextInt();
11         int b = s.nextInt();
12         // 参数要求:a,m互质;a,b互质
13         while (fun1(m, a) != 1 || fun1(Math.max(a, b), Math.min(a, b)) != 1) {
14             System.out.println("参数不符合要求,请重新输入");
15             a = s.nextInt();
16             b = s.nextInt();
17         }
18         for (char i : buff) {
19             // 由字符转换为数字
20             if (i > '9') thisNum = (int)i - 87;
21             else thisNum = (int)i - 48;
22             // 对该数字加密
23             thisNum = (thisNum*a+b)%m;
24             // 加密后再将数字转换为字符
25             if (thisNum < 10) buff[index++] = (char)(thisNum+48);
26             else buff[index++] = (char)(thisNum+87);
27         }
28         System.out.println(buff);
29         s.close();
30     }
31 
32     // 欧几里得算法求两个数的最大公因数
33     public static int fun1(int a, int b) {
34         return b == 0 ? a : fun1(b, a%b);
35     }
36 }

解密实现:

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String []args) {
 5         int m = 36, thisNum, index = 0, k;
 6         Scanner s = new Scanner(System.in);
 7         char[] buff = s.nextLine().toCharArray();
 8         int a = s.nextInt();
 9         int b = s.nextInt();
10         while (fun1(m, a) != 1 || fun1(Math.max(a, b), Math.min(a, b)) != 1) {
11             System.out.println("参数不符合要求,请重新输入");
12             a = s.nextInt();
13             b = s.nextInt();
14         }
15         // k为a模m的逆元
16         k = fun2(a, m);
17         for (char i : buff) {
18             // 将加密后的字符转换为数字
19             if (i > '9') thisNum = (int)i - 87;
20             else thisNum = (int)i - 48;
21             // 解密过程 D(E(x)) = a^(-1)*(E(x)-b) mod m
22             thisNum = ((thisNum-b)*k)%m;
23             // 如果结果是负数,则转换为正数,原理为 a % b = (a % b + b) % b
24             if(thisNum < 0) thisNum += m;
25             // 最后将解密后的数字转换为字符
26             if (thisNum < 10) buff[index++] = (char)(thisNum+48);
27             else buff[index++] = (char)(thisNum+87);
28         }
29         System.out.println(buff);
30     }
31 
32     public static int fun1(int a, int b) {
33         return b == 0 ? a : fun1(b, a%b);
34     }
35 
36     // 循环求a模m的逆元
37     public static int fun2(int a, int m) {
38         for (int i = 0; i < m; i++) {
39             if (a*i%m == 1) {
40                 a = i;
41                 break;
42             }
43         }
44         return a;
45     }
46 }

 

3、换位密码

加密过程:保持明文的所有字符不变,根据一定的规则重新排列明文。

解密过程:加密过程的逆过程。

注解:加密过程和解密过程都是创建索引的过程,即用数组存储哪个位置放哪个字符,最后再通过索引重新组合成密文或明文。

示例:

明文矩阵:
a s d f g
h j k l m
n b v c

密文矩阵:
d a g s f
k h m j l
v n b c

(计算结果中n和b之间有一个空格,但输出时将空格去掉了)

明文:asdfghjklmnbvc
密钥:31524

加密实现:

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String []args) {
 5         Scanner s = new Scanner(System.in);
 6         char[] mingwen = s.nextLine().toCharArray();
 7         char[] miyao = s.nextLine().toCharArray();
 8         StringBuffer miwen = new StringBuffer();
 9         int[] poi = new int[miyao.length];
10         int index = 0, thisRow = 0, realPoi;
11 
12         // 计算出明文矩阵的列数和行数
13         int col = miyao.length;
14         int row = (mingwen.length / col) + (mingwen.length % col == 0? 0 : 1);  // 处理明文矩阵最后一行可能不满的情况
15         
16         // 密钥位置格式化(密钥中的所有字符都大于等于'1'所以最后减1方便后续计算)
17         for (int i = 0; i < poi.length; i++) poi[i] = miyao[i] - 48 - 1;
18 
19 
20         for (int i = 0; i < row * col; i++) {
21             // 计算出当前位置i的真正字符(例如加密后第0位为2,即字符d),如果该字符在明文中存在,则将其添加到密文中
22             if ((realPoi = poi[index++] + thisRow * col) < mingwen.length) miwen.append(mingwen[realPoi]);
23             // 如果当前位置无字符则用空格代替
24             else miwen.append(' ');
25             
26             if (index >= col) {
27                 index = index % col;
28                 thisRow++;
29             }
30         }
31 
32         // 密文去空格(解密时密文中的空格需要保留)
33         for (int i = 0; i < miwen.length(); i++) {
34             if (miwen.charAt(i) == ' ') miwen.deleteCharAt(i);
35         }
36 
37         // 输出加密后的密文
38         System.out.println(miwen);
39     }
40 }

解密实现:

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String []args) {
 5         Scanner s = new Scanner(System.in);
 6         char[] miwen = s.nextLine().toCharArray();
 7         char[] miyao = s.nextLine().toCharArray();
 8         StringBuffer mingwen = new StringBuffer();
 9         int []poi = new int[miyao.length];
10         int index = 0, thisRow = 0, realPoi;
11 
12         // 获取解密密钥并将密钥的位置格式化(最后减一),即加密的逆过程
13         for (char c : miyao) {
14             poi[(int)c - 48 - 1] = index++;
15         }
16         index = 0;
17 
18         // 密文矩阵的列数和行数
19         int col = miyao.length;
20         int row = (miwen.length / col) + (miwen.length % col == 0? 0 : 1);
21 
22         for (int i = 0; i < row * col; i++) {
23             // 计算出当前位置i的真正字符并将该字符添加到明文字符串中
24             if ((realPoi = poi[index++] + thisRow * col) < miwen.length) mingwen.append(miwen[realPoi]);
25             
26             if (index >= col) {
27                 index = index % col;
28                 thisRow++;
29             }
30         }
31 
32         // 输出解密后的明文
33         System.out.println(mingwen);
34     }
35 }

 

4、希尔密码(Hill密码)- 属于古典密码中的多表代换密码,运用了基本的矩阵论原理

注解:

1)每个字母当作 26 进制数字:a=0, b=1, c=2... 一串字母当成n维向量,跟一个n×n的矩阵相乘,再将得出的结果模 26。用作加密的矩阵(即密匙)必须是可逆的,否则就不可能译码。只有矩阵的行列式和 26 互质,才是可逆的。

2)明文和密文的长度必须是给定的矩阵的列数的整数倍。(矩阵相乘的前提)

加密过程:将明文转化为n维向量(字符转数字)与n×n的矩阵相乘,再将得出的结果模 26 后转化为字符。

解密过程:将明文转化为n维向量(字符转数字)与n×n的矩阵相乘,再将得出的结果模 26 后转化为字符。

加密实现:

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5         // 三阶可逆矩阵A
 6         int[][] A = { { 1, 2, 3 }, { 1, 1, 2 }, { 0, 1, 2 } };
 7 
 8         Scanner s = new Scanner(System.in);
 9         char[] mingwen = s.nextLine().toCharArray();
10         char[] miwen = new char[mingwen.length];
11         int row = 3, col = mingwen.length / 3, index = 0;
12 
13         while (index < col) {
14             int sum;
15             for (int i = 0; i < row; i++) {
16                 sum = 0;
17                 for (int j = 0; j < row; j++) {
18                     sum += A[i][j] * (int) (mingwen[j+index*row] - 97);
19                 }
20                 sum %= 26;
21                 if (sum < 0) sum += 26;
22                 miwen[i + index*row] = (char) (sum + 97);
23             }
24             index++;
25         }
26 
27         for (char c : miwen) {
28             System.out.print(c);
29         }
30     }
31 }

解密实现:

 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5         // A的逆矩阵
 6         int[][] A_1 = {{0, 1, -1}, {2, -2, -1}, {-1, 1, 1}};
 7 
 8         Scanner s = new Scanner(System.in);
 9         char[] miwen = s.nextLine().toCharArray();
10         char[] mingwen = new char[miwen.length];
11         int row = 3, col = mingwen.length / 3, index = 0;
12 
13         while (index < col) {
14             int sum;
15             for (int i = 0; i < 3; i++) {
16                 sum = 0;
17                 for (int j = 0; j < 3; j++) {
18                     sum += A_1[i][j] * (int)(miwen[j+index*row] - 97);
19                 }
20                 sum %= 26;
21                 if (sum < 0) sum += 26;
22                 mingwen[i+index*row] = (char)(sum+97);
23             }
24             index++;
25         }
26 
27         for(char c : mingwen) {
28             System.out.print(c);
29         }
30     }
31 }

 

o
粉丝 0
博文 500
码字总数 0
作品 0
私信 提问
加载中
请先登录后再评论。
古典密码

密码学的阶段划分   密码学的发展按照其对算法和秘钥的保密程度大致可以分为如下三个阶段。 古典密码阶段(1949年前) 在这个阶段算法和秘钥都是保密的,秘钥空间较小,信息的安全性主要依...

抖音hzcya
06/25
1
0
Java 加密框架 00 密码学基础

密码学的分类 按时间划分:古典密码,以字符为基本加密单元;现代密码以信息块为基本加密单元。 按保密内容的算法划分: 受限制算法:算法的保密性基于保持密码的秘密。这是古典密码学的主要...

fokYaland
2015/06/04
29
0
密码学初探

在区块链的整个体系中大量使用了密码学算法,比如用于 PoW 的哈希算法,用于完整性验证的 Merkle Tree,用于交易签名与验证的数字签名算法,用于隐私保护的零知识证明等等。可以说密码学是保...

NervosNetwork
2018/11/23
64
0
Java实现Base64位加密

一 密码常用术语   明文:待加密信息   密文:经过加密后的明文   加密:明文转为密文的过程   加密算法:明文转为密文的转换算法   加密秘钥:通过加密算法进行加密操作的秘钥   解密...

osc_y8k7fox4
2018/08/04
3
0
密码学基础

学CTF的笔记忘记带了,汗...本来想将这三天来学二进制的知识记录下来的,看来只能搁置到明天了,今天就将之前I春秋学院学过的密码学基础放在上面吧,也算加深下印象 学习大纲 1.密码的基本概...

osc_0zx29dnz
2019/04/03
2
0

没有更多内容

加载失败,请刷新页面

加载更多

什么是token及怎样生成token

什么是token   Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即...

osc_zzg7fpke
44分钟前
10
0
往事不堪回首

开局一张图,内容全靠编 从12年大学毕业到如今,兜兜转转,依然在码工,码农,码代码的路上徘徊着,从最初的用asp.net写站点,写内部的CRM,内部管理系统,内部的XXX,很难想象内部的系统居然...

osc_9os5791s
45分钟前
23
0
java 事件监听器

package com.qimh.springbootfiledemo.listener;/** * 事件监听器 * 监听person 事件源的eat 和 sleep 的方法 * @author */public interface PersonListener { void doEa...

qimh
46分钟前
21
0
[原创.数据可视化系列之四]跨平台,多格式的等值线和等值面的生成

这些年做项目的时候,碰到等值面基本都是arcgis server来支撑的,通过构建GP服务,一般的都能满足做等值线和等值面的需求。可是突然有一天,我发现如果没有arcgis server 的话,我既然没法生...

osc_bvincwvq
46分钟前
16
0
个人作业——软件工程实践总结&个人技术博客

这个作业属于哪个课程 2020春|S班(福州大学) 这个作业要求在哪里 个人作业——软件工程实践总结&个人技术博客 这个作业的目标 总结软件工程课程以及实践中的收获 作业正文 其他参考文献 一...

osc_9piujk2x
47分钟前
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部