文章目录
1. 凯撒密码介绍
凯撒密码作为一种最古老的加密技术,在古罗马时期就很流行。基本思想是:通过把字母移动一定的位数来实现加密和解密。明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后替换为密文。
1.1 加密的概念
- 明文: 原始信息
- 密钥: 加密和解密算法的参数,直接影响对明文进行变换的结果
- 密文: 对明文进行变换的结果
- 加密算法: 以密钥为参数,对明文进行多种置换和转换的规则和步骤,变换结果为密文
- 解密算法: 加密算法的逆变换,以密文为输入、密钥为参数,变换结果为明文
1.2 暴力破解法
穷举法
a -> (b ~ z) key=1~25
前提: 知道密文用的算法为凯撒密码
频率分析法:
可以通过写一段程序,来检测一篇文章中每个字母出现的次数
假设频率最高为 h -> e key
注意:
- 统计密文里出现次数最多的字符时,需要多几个备选,因为最多的可能给是空格或其他字符,如a,h之类
- 短文可能严重偏离标准频率,破解较为困难。
2. 对称加密
2.1 概述
加密和解密使用同一把密钥,这种加密方法称为对称加密。也叫单密钥加密。
基于对称密钥的加密算法主要有DES算法和AES算法
2.2 对称密码常用的数学运算
- 移位和循环移位 移位就是讲一段数码按照规定的位数整体性的左移或右移。循环右移就是当右移时,把数码的最后的位移到数码的最前头
- 置换 将数码中的某一位的值根据置换表的规定,用另一位代替,看上去杂乱无章。
- 扩展 将一段数码扩展成比原来位数更长的数码,方法有多种。
- 压缩 逆操作
- 异或 真假为真,真真或假假都为假
- 迭代 多次重复相同的运算
2.3 DES算法
简介
Data Encryption Standard
数据加密标准的缩写。由IBM研制的一种对称加密算法,美国国家标准局1977年公布把它作为非机要部门的数据加密标准。主流。
是一个分组加密算法,以64位为分组对数据加密,加密和解密用同一个算法。密钥长度为56位(另外8位作为奇偶校验),保密性依赖于密钥。
算法框架:
首先生成一套加密密钥,从用户处取得一个64位的密码口令,通过等分、移位、选取和迭代形成一套16个加密密钥,分别供每轮运算使用。
DES对64位的明文分组M进行操作,M经过一个初始置换IP,置换为m0.将m0明文分成左右两部分,各32位长。
然后进行16轮完全相同的运算(迭代),每轮运算过程中数据与相应的密钥结合
最后,左右半部分合到一起经过一个末置换(数据整理),完成加密。
2.4 Base64编码
加密之后的结果是字节数组,这些被加密后的字节在码表(如GBK,UTF-8)上找不到对应字符,会出现乱码,乱码字符串再次转换为字节数组,长度会变化,导致解密失败,转换后的数据是不安全的
使用Base64对字节数组进行编码,任何字节都能映射成对应的Base64字符,之后能回复到字节数组,利于加密后数据的保存和传输,转换是安全的。
编解码原理
- 当字符串字符个数为3的整数倍时:
比如字符串"ABC",在内存中的十进制为"65",“66”,“67”;二进制位
01000001 01000010 01000011
将这三个二进制数依次取6bit,
010000/01 0100/0010 01/000011
转换为了
010000/ 010100/ 001001/ 000011
转换为16进制为10,14,9,3, 十进制为16,20,9,3 对照上面的码表,分别查找,对应字符为Q, U, J, D
- 当字符串字符个数除以3余数为2时:
比如字符串"ce",十进制表示99,101; 二进制表示
01100011 01100101
依次取6Bit,
011000/11 0110/0101
第三个字符不足6位,后面补零,也就是0101变成010100
011000/ 110110/ 010100
这三个二进制数转换为十进制为24,54,20,对照码表 Y2U,编码后不足4位,两个0用=填充,编码得到"Y2U="
- 当余数为1时
如字符串"{",内存中十进制为123,二进制位 01111011
,依次取6bit,011110/11
补0后为011110/110000
,转换为十进制为30,48,对照码表为"ew",补上=,编码得到"ew==",解码很简单,逆过程,每个字符对照码表换算为6bit的二进制数,充足,按8位进行截取,得出源码。
完整版DES+base64解码
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
// 出现乱码,需要用Base64解码
public class DESDemo {
public static void main(String[] args) throws Exception {
/**
* 1. 明文
* 2. 提供原始密钥:长度64位,8个字节
*/
String clearText = "heima";
String originKey = "12345678";
String cipherText = desEncript(clearText,originKey);
System.out.println(cipherText);
}
/**
* 用DES算法进行加密
* Cipher
* @param clearText
* @param originKey
* @return
*/
private static String desEncript(String clearText, String originKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
// 1. 获取加密算法工具类
Cipher cipher = Cipher.getInstance("DES");
// 2. 对工具类对象进行初始化
// mode: 加密/解密模式
// key: 对原始密钥处理之后的密钥
SecretKey key = getKey(originKey);
cipher.init(Cipher.ENCRYPT_MODE,key);
// 3. 用加密工具类对明文进行加密
byte[] doFinal = cipher.doFinal(clearText.getBytes());
// return new String(doFinal);
// jdk9 Base64类有个内部类Encoder,有个encode方法
// Base64的静态方法getEncoder(),得到Encoder内部类,再调用encode方法
byte[] encode = Base64.getEncoder().encode(doFinal);
return new String(encode);
}
private static SecretKey getKey(String originKey) {
// 根据给定的字节数组构造一个密钥
SecretKeySpec key = new SecretKeySpec(originKey.getBytes(),"DES");
return key;
}
}
3. 3DES和AES算法
3DES算法
DES的安全性首先取决于密钥的长度。密钥越长,破译者利用穷举法所有密钥的难度越大。DES采用64bit分组长度和56bit密钥长度。
密钥大小 | 密钥个数 | 每微秒执行一次解密所需的时间 | 每微秒执行一百万次解密所需时间 |
---|---|---|---|
56 | 2^56 | 2^56us=1142年 | 10.01小时 |
随着技术的发展,多核CPU、分布式计算、量子计算等理论的实现,DES在穷举法的暴力攻击下相当脆弱,目前两种替代方案:
- 设计一套全新的算法,如AES
- 为了保护已有软硬件的投资,仍使用DES,但是多次加密,如3-DES
3-DES算法使用3个独立密钥(密钥长度168bit)进行三重DES加密,穷举需要进行2^112次计算
AES算法
3DES缺点是算法运行相对较慢,AES(Advanced Encryption Standard)高级加密标准,是美国国家标准技术研究所2001年颁布的,2006年成为最流行的对称加密算法
分组大小为128bit,密钥长度可以为128、192、256bit,最常用最简单为128bit(16字节)的密钥
算法原理:
涉及四种操作:字节代替、行移位、列混淆、轮密钥加
代码实现:
将密码设为16byte,再将DES算法实现的java代码,DES替换为AES即可
对称加密的劣势:
加密和解密用同一套算法,一旦截获密钥和加密密文,就可以破解了。
单向散列加密
MD5
BCript,基于MD5,加盐,应用于spring security
详细参考https://www.cnblogs.com/xzwblog/p/6958056.html#_label1_3
非对称加密
一个公钥,一个私钥,常用算法如RSA算法,应用场景如GitHub的SSH,HTTPS传输中浏览器使用的数字证书。