|
1 | | -# Java加密与解密 |
| 1 | +# Java密码学相关知识梳理 |
2 | 2 | ##ASCII编码 |
3 | | -* ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是现今最通用的单字节编码系统,并等同于国际标准ISO/IEC 646。 |
4 | | -*  |
| 3 | +* ASCII(American Standard Code for Information Interchange,美国信息交换标准代码)是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。。 |
| 4 | +*  |
| 5 | +* 实例代码: |
| 6 | +```$java |
| 7 | +public static void main(String[] args) { |
| 8 | + char a = 'A'; |
| 9 | + int code = a; |
| 10 | + System.out.println(code); |
| 11 | +
|
| 12 | + String s = "frank"; |
| 13 | + char[] chars = s.toCharArray(); |
| 14 | + for (char c : chars) { |
| 15 | + int num = c; |
| 16 | + System.out.println(num); |
| 17 | + } |
| 18 | +} |
| 19 | +``` |
| 20 | +##凯撒加密 |
| 21 | +* 恺撒密码(Caesar cipher)是一种相传尤利乌斯·恺撒曾使用过的密码。恺撒于公元前100年左右诞生于古罗马,是一位著名的军事统帅。 |
| 22 | +* 恺撤密码是通过将明文中所使用的字母表按照一定的字数“平移”来进行加密的 |
| 23 | +*  |
| 24 | +* 凯撒密码加解密公式 |
| 25 | + |
| 26 | + - 加密 |
| 27 | + |
| 28 | +  |
| 29 | + |
| 30 | + - 解密 |
| 31 | + |
| 32 | +  |
| 33 | + |
| 34 | + |
| 35 | + - 凯撒密码中的加密三要素 |
| 36 | + - 明文/密文 |
| 37 | + - 明文: 图表上部分的数据 |
| 38 | + - 密文: 图表下部分的数据 |
| 39 | + - 秘钥 |
| 40 | + - 按照上图秘钥为3 |
| 41 | + - 算法 |
| 42 | + - 加密: +3 |
| 43 | + - 解密: -3 |
| 44 | +* 示例代码如下: |
| 45 | +```$java |
| 46 | +public static void main(String[] args) { |
| 47 | + String s = "frank"; |
| 48 | + int key = 3; |
| 49 | + String encriptData = KaiserEncrypt(s, key); |
| 50 | + System.out.println("encriptData="+encriptData); |
| 51 | + String decriptData = KaiserDecrypt(encriptData, key); |
| 52 | + System.out.println("decriptData="+decriptData); |
| 53 | + /** |
| 54 | + * result as below: |
| 55 | + * encriptData=iudqn |
| 56 | + * decriptData=frank |
| 57 | + */ |
| 58 | + } |
| 59 | +
|
| 60 | + /** |
| 61 | + * |
| 62 | + * @param orignal:原文 |
| 63 | + * @param key:秘钥 |
| 64 | + * @return:返回值 |
| 65 | + */ |
| 66 | + private static String KaiserEncrypt(String orignal, int key) { |
| 67 | + char[] chars = orignal.toCharArray(); |
| 68 | + StringBuilder sb = new StringBuilder(); |
| 69 | + for (char aChar : chars) { |
| 70 | + // 获取字符的ASCII编码 |
| 71 | + int asciiCode = aChar; |
| 72 | + // 偏移数据 |
| 73 | + asciiCode += key; |
| 74 | + // 将偏移后的数据转为字符 |
| 75 | + char result = (char) asciiCode; |
| 76 | + // 拼接数据 |
| 77 | + sb.append(result); |
| 78 | + } |
| 79 | + return sb.toString(); |
| 80 | + } |
| 81 | +
|
| 82 | + /** |
| 83 | + * |
| 84 | + * @param encryptedData 密文 |
| 85 | + * @param key 秘钥 |
| 86 | + * @return |
| 87 | + */ |
| 88 | + private static String KaiserDecrypt(String encryptedData, int key) { |
| 89 | + char[] chars = encryptedData.toCharArray(); |
| 90 | + StringBuilder sb = new StringBuilder(); |
| 91 | + for (char aChar : chars) { |
| 92 | + int asciiCode = aChar; |
| 93 | + asciiCode -= key; |
| 94 | + char result = (char) asciiCode; |
| 95 | + sb.append(result); |
| 96 | + } |
| 97 | + return sb.toString(); |
| 98 | + } |
| 99 | +``` |
| 100 | +## 频度分析法破解恺撒加密 |
| 101 | +- 将明文字母的出现频率与密文字母的频率相比较的过程 |
| 102 | +- 通过分析每个符号出现的频率而轻易地破译代换式密码 |
| 103 | +- 在每种语言中,冗长的文章中的字母表现出一种可对之进行分辨的频率。 |
| 104 | +- e是英语中最常用的字母,其出现频率为八分之一 |
| 105 | +- 由于破解太简单,在此不贴代码了,有兴趣的自己试试 |
| 106 | + |
| 107 | +##常见加密方式 |
| 108 | + |
| 109 | +##对称加密 |
| 110 | +> 以分组为单位进行处理的密码算法称为**分组密码(blockcipher)** |
| 111 | +- 采用单钥密码系统的加密方法,同一个密钥可以同时用作信息的加密和解密,这种加密方法称为对称加密,也称为单密钥加密。 |
| 112 | +- 示例 |
| 113 | + - 我们现在有一个原文3要发送给B |
| 114 | + - 设置密钥为108, 3 * 108 = 324, 将324作为密文发送给B |
| 115 | + - B拿到密文324后, 使用324/108 = 3 得到原文 |
| 116 | +- 常见对称加密算法 |
| 117 | + - DES : Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1977年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),并授权在非密级政府通信中使用,随后该算法在国际上广泛流传开来。 |
| 118 | + - AES : Advanced Encryption Standard, 高级加密标准 .在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。 |
| 119 | +- 特点 |
| 120 | + - 加密速度快, 可以加密大文件 |
| 121 | + - 密文可逆, 一旦密钥文件泄漏, 就会导致数据暴露 |
| 122 | + - 加密后编码表找不到对应字符, 出现乱码 |
| 123 | + - 一般结合Base64使用 |
| 124 | + |
| 125 | +## 分组密码的模式 |
| 126 | +1. 按位异或 |
| 127 | + |
| 128 | + - 第一步需要将数据转换为二进制 |
| 129 | + |
| 130 | + - 按位异或操作符: ^ |
| 131 | + |
| 132 | + - 两个标志位进行按位异或操作: |
| 133 | + |
| 134 | + - 相同为0, 不同为1 |
| 135 | + |
| 136 | + - 举例: |
| 137 | + |
| 138 | + ```go |
| 139 | + 1 0 0 0 ----> 8 |
| 140 | + 1 0 1 1 ----> 11 |
| 141 | + -----------------------按位异或一次 |
| 142 | + 0 0 1 1 ----> 3 |
| 143 | + 1 0 1 1 ----> 11 |
| 144 | + -----------------------按位异或两侧 |
| 145 | + 1 0 0 0 -----> 8 |
| 146 | + ================================= |
| 147 | + a = 8 |
| 148 | + b = 11 |
| 149 | + a 和 b按位异或1次 ==> 加密 |
| 150 | + 得到的结果再次和 b 按位异或 ===> 解密 |
| 151 | + ``` |
| 152 | + |
| 153 | +2. ECB - Electronic Code Book, 电子密码本模式 |
| 154 | + |
| 155 | + - 特点: 简单, 效率高, 密文有规律, 容易被破解 |
| 156 | + - 最后一个明文分组必须要填充 |
| 157 | + - des/3des -> 最后一个分组填充满8字节 |
| 158 | + - aes -> 最后一个分组填充满16字节 |
| 159 | + - 不需要初始化向量 |
| 160 | + |
| 161 | +3. CBC - Cipher Block Chaining, 密码块链模式 |
| 162 | + |
| 163 | + - 特点: 密文没有规律, 经常使用的加密方式 |
| 164 | + - 最后一个明文分组需要填充 |
| 165 | + - des/3des -> 最后一个分组填充满8字节 |
| 166 | + - aes -> 最后一个分组填充满16字节 |
| 167 | + - 需要一个初始化向量 - 一个数组 |
| 168 | + - 数组的长度: 与明文分组相等 |
| 169 | + - 数据来源: 负责加密的人的提供的 |
| 170 | + - 加解密使用的初始化向量值必须相同 |
| 171 | + |
| 172 | +4. CFB - Cipher FeedBack, 密文反馈模式 |
| 173 | + |
| 174 | + - 特点: 密文没有规律, 明文分组是和一个数据流进行的按位异或操作, 最终生成了密文 |
| 175 | + - 需要一个初始化向量 - 一个数组 |
| 176 | + - 数组的长度: 与明文分组相等 |
| 177 | + - 数据来源: 负责加密的人的提供的 |
| 178 | + - 加解密使用的初始化向量值必须相同 |
| 179 | + - 不需要填充 |
| 180 | + |
| 181 | +5. OFB - Output-Feedback, 输出反馈模式 |
| 182 | + |
| 183 | + - 特点: 密文没有规律, 明文分组是和一个数据流进行的按位异或操作, 最终生成了密文 |
| 184 | + - 需要一个初始化向量 - 一个数组 |
| 185 | + - 数组的长度: 与明文分组相等 |
| 186 | + - 数据来源: 负责加密的人的提供的 |
| 187 | + - 加解密使用的初始化向量值必须相同 |
| 188 | + - 不需要填充 |
| 189 | + |
| 190 | +6. CTR - CounTeR, 计数器模式 |
| 191 | + |
| 192 | + - 特点: 密文没有规律, 明文分组是和一个数据流进行的按位异或操作, 最终生成了密文 |
| 193 | + - 不需要初始化向量 |
| 194 | + - 不需要填充 |
| 195 | + |
| 196 | +7. 最后一个明文分组的填充 |
| 197 | + |
| 198 | + - 使用cbc, ecb需要填充 |
| 199 | + - 要求: |
| 200 | + - 明文分组中进行了填充, 然后加密 |
| 201 | + - 解密密文得到明文, 需要把填充的字节删除 |
| 202 | + - 使用 ofb, cfb, ctr不需要填充 |
| 203 | + |
| 204 | +8. 初始化向量 - IV |
| 205 | + |
| 206 | + - ecb, ctr模式不需要初始化向量 |
| 207 | + - cbc, ofc, cfb需要初始化向量 |
| 208 | + - 初始化向量的长度 |
| 209 | + - des/3des -> 8字节 |
| 210 | + - aes -> 16字节 |
| 211 | + - 加解密使用的初始化向量相同 |
0 commit comments