(点击
上方公众号
,可快速关注)
来源:GoogleDev
链接:blog.csdn.net/axi295309066/article/details/52491077
对称加密、非对称加密、消息摘要、数字签名等知识都是为了理解数字证书工作原理而作为一个预备知识。数字证书是密码学里的终极武器,是人类几千年历史总结的智慧的结晶,只有在明白了数字证书工作原理后,才能理解Https 协议的安全通讯机制。最终才能在SSL 开发过程中得心应手。
另外,对称加密和消息摘要这两个知识点是可以单独拿来使用的。
数字证书使用到了以上学习的所有知识
-
对称加密与非对称加密结合使用实现了秘钥交换,之后通信双方使用该秘钥进行对称加密通信。
-
消息摘要与非对称加密实现了数字签名,根证书机构对目标证书进行签名,在校验的时候,根证书用公钥对其进行校验。若校验成功,则说明该证书是受信任的。
-
Keytool 工具可以创建证书,之后交给根证书机构认证后直接使用自签名证书,还可以输出证书的RFC格式信息等。
-
数字签名技术实现了身份认证与数据完整性保证。
-
加密技术保证了数据的保密性,消息摘要算法保证了数据的完整性,对称加密的高效保证了数据处理的可靠性,数字签名技术保证了操作的不可否认性。
通过以上内容的学习,我们要能掌握以下知识点:
凯撒密码
1. 介绍
凯撒密码作为一种最为古老的对称加密体制,在古罗马的时候都已经很流行,他的基本思想是:通过把字母移动一定的位数来实现加密和解密。明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。例如,当偏移量是3 的时候,所有的字母A 将被替换成D,B 变成E,由此可见,位数就是凯撒密码加密和解密的密钥。
例如:字符串”ABC”的每个字符都右移3 位则变成”DEF”,解密的时候”DEF”的每个字符左移3 位即能还原,如下图所示:
2. 准备知识
//字符转换成ASCII 码数值
char
charA
=
'a'
;
int
intA
=
charA
;
//char 强转为int 即得到对应的ASCII 码值,’a’的值为97
//ASCII 码值转成char
int
intA
=
97
;
//97 对应的ASCII 码’a’
char
charA
=
(
char
)
intA
;
//int 值强转为char 即得到对应的ASCII 字符,即'a'
3. 凯撒密码的简单代码实现
/**
* 加密
* @param input 数据源(需要加密的数据)
* @param key 秘钥,即偏移量
* @return 返回加密后的数据
*/
public
static
String
encrypt
(
String
input
,
int
key
)
{
//得到字符串里的每一个字符
char
[]
array
=
input
.
toCharArray
();
for
(
int
i
=
0
;
i
array
.
length
;
++
i
)
{
//字符转换成ASCII 码值
int
ascii
=
array
[
i
];
//字符偏移,例如a->b
ascii
=
ascii
+
key
;
//ASCII 码值转换为char
char
newChar
=
(
char
)
ascii
;
//替换原有字符
array
[
i
]
=
newChar
;
//以上4 行代码可以简写为一行
//array[i] = (char) (array[i] + key);
}
//字符数组转换成String
return
new
String
(
array
);
}
/**
* 解密
* @param input 数据源(被加密后的数据)
* @param key 秘钥,即偏移量
* @return 返回解密后的数据
*/
public
static
String
decrypt
(
String
input
,
int
key
)
{
//得到字符串里的每一个字符
char
[]
array
=
input
.
toCharArray
();
for
(
int
i
=
0
;
i
array
.
length
;
++
i
)
{
//字符转换成ASCII 码值
int
ascii
=
array
[
i
];
//恢复字符偏移,例如b->a
ascii
=
ascii
-
key
;
//ASCII 码值转换为char
char
newChar
=
(
char
)
ascii
;
//替换原有字符
array
[
i
]
=
newChar
;
//以上4 行代码可以简写为一行
//array[i] = (char) (array[i] - key);
}
//字符数组转换成String
return
new
String
(
array
);
}
代码输出结果:
4. 破解凯撒密码:频率分析法
凯撒密码加密强度太低,只需要用频度分析法即可破解。
在任何一种书面语言中,不同的字母或字母组合出现的频率各不相同。而且,对于以这种语言书写的任意一段文本,都具有大致相同的特征字母分布。比如,在英语中,字母E 出现的频率很高,而X 则出现得较少。
英语文本中典型的字母分布情况如下图所示:
5. 破解流程
注意点:统计密文里出现次数最多的字符时,需多统计几个备选,因为最多的可能是空格或者其他字符,例如下图出现次数最多的字符’#’是空格加密后的字符,’h’才是’e’偏移后的值。
解密时要多几次尝试,因为不一定出现次数最多的字符就是我们想要的目标字符,如下图,第二次解密的结果才是正确的。
/**
* 频率分析法破解凯撒密码
*/
public
class
FrequencyAnalysis
{
//英文里出现次数最多的字符
private
static
final
char
MAGIC_CHAR
=
'e'
;
//破解生成的最大文件数
private
static
final
int
DE_MAX_FILE
=
4
;
public
static
void
main
(
String
[]
args
)
throws
Exception
{
//测试1,统计字符个数
//printCharCount("article1_en.txt");
//加密文件
//int key = 3;
//encryptFile("article1.txt", "article1_en.txt", key);
//读取加密后的文件
String
artile
=
file2String
(
"article1_en.txt"
);
//解密(会生成多个备选文件)
decryptCaesarCode
(
artile
,
"article1_de.txt"
);
}
public
static
void
printCharCount
(
String
path
)
throws
IOException
{
String
data
=
file2String
(
path
);
List
Entry
Character
,
Integer
>>
mapList
=
getMaxCountChar
(
data
);
for
(
Entry
Character
,
Integer
>
entry
:
mapList
)
{
//输出前几位的统计信息
System
.
out
.
println
(
"字符'"
+
entry
.
getKey
()
+
"'出现"
+
entry
.
getValue
()
+
"次"
);
}
}
public
static
void
encryptFile
(
String
srcFile
,
String
destFile
,
int
key
)
throws
IOException
{
String
artile
=
file2String
(
srcFile
);
//加密文件
String
encryptData
=
MyEncrypt
.
encrypt
(
artile
,
key
);
//保存加密后的文件
string2File
(
encryptData
,
destFile
);
}
/**
* 破解凯撒密码
* @param input 数据源
* @return 返回解密后的数据
*/
public
static
void
decryptCaesarCode
(
String
input
,
String
destPath
)
{
int
deCount
=
0
;
//当前解密生成的备选文件数
//获取出现频率最高的字符信息(出现次数越多越靠前)
List
Entry
Character
,
Integer
>>
mapList
=
getMaxCountChar
(
input
);
for
(
Entry
Character
,
Integer
>
entry
:
mapList
)
{
//限制解密文件备选数
if
(
deCount
>=
DE_MAX_FILE
)
{
break
;
}
//输出前几位的统计信息
System
.
out
.
println
(
"字符'"
+
entry
.
getKey
()
+
"'出现"
+
entry
.
getValue
()
+
"次"
);
++
deCount
;
//出现次数最高的字符跟MAGIC_CHAR的偏移量即为秘钥
int
key
=
entry
.
getKey
()
-
MAGIC_CHAR
;
System
.
out
.
println
(
"猜测key = "
+
key
+
", 解密生成第"
+
deCount
+
"个备选文件"
+
"\n"
);
String
decrypt
=
MyEncrypt
.
decrypt
(
input
,
key
);
String
fileName
=
"de_"
+
deCount
+
destPath
;
string2File
(
decrypt
,
fileName
);
}
}
//统计String里出现最多的字符
public
static
List
Entry
Character
,
Integer
>>
getMaxCountChar
(
String
data
)
{
Map
Character
,
Integer
>
map
=
new
HashMap
Character
,
Integer
>
();
char
[]
array
=
data
.
toCharArray
();
for
(
char
c
:
array
)
{
if
(
!
map
.
containsKey
(
c
))
{
map
.
put
(
c
,
1
);
}
else
{
Integer
count
=
map
.
get
(
c
);
map
.
put
(
c
,
count
+
1
);
}
}
//输出统计信息
/*for (Entry
entry : map.entrySet()) {
System.out.println(entry.getKey() + "出现" + entry.getValue() + "次");
}*/
//获取获取最大值
int
maxCount
=
0
;
for
(
Entry
Character
,
Integer
>
entry
:
map
.
entrySet
())
{
//不统计空格
if
(
/*entry.getKey() != ' ' && */
entry
.
getValue
()
>
maxCount
)
{
maxCount
=
entry
.
getValue
();
}
}
//map转换成list便于排序
List
Entry
Character
,
Integer
>>
mapList
=
new
ArrayList
Map
.
Entry
Character
,
Integer
>>
(
map
.
entrySet
());
//根据字符出现次数排序
Collections
.
sort
(
mapList
,
new
Comparator
Entry
Character
,
Integer
>>
(){
@Override
public
int
compare
(
Entry
Character
,
Integer
>
o1
,
Entry
Character
,
Integer
>
o2
)
{
return
o2
.
getValue
().
compareTo
(
o1
.
getValue
());
}
});
return
mapList
;
}
public
static
String
file2String
(
String
path
)
throws
IOException
{
FileReader
reader
=
new
FileReader
(
new
File
(
path
));
char
[]
buffer
=
new
char
[
1024
];
int
len
= -
1
;
StringBuffer
sb
=
new
StringBuffer
();
while
((
len
=
reader
.
read
(
buffer
))
!= -
1
)
{
sb
.
append
(
buffer
,
0
,
len
);
}
return
sb
.
toString
();
}
public
static
void
string2File
(
String
data
,
String
path
){
FileWriter
writer
=
null
;
try
{
writer
=
new
FileWriter
(
new
File
(
path
));
writer
.
write
(
data
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
finally
{
if
(
writer
!=
null
)
{
try
{
writer
.
close
();
}
catch
(
IOException
e
)
{
e
.
printStackTrace
();
}
}
}
}
}
对称加密
介绍
加密和解密都使用同一把秘钥,这种加密方法称为对称加密,也称为单密钥加密。
简单理解为:加密解密都是同一把钥匙。
凯撒密码就属于对称加密,他的字符偏移量即为秘钥。
对称加密常用算法
AES、DES、3DES、TDEA、Blowfish、RC2、RC4、RC5、IDEA、SKIPJACK 等。
DES:
全称为Data Encryption Standard,即数据加密标准,是一种使用密钥加密的块算法,1976 年被美国联邦政府的国家标准局确定为联邦资料处理标准(FIPS),随后在国际上广泛流传开来。
3DES:
也叫Triple DES,是三重数据加密算法(TDEA,Triple Data Encryption Algorithm)块密码的通称。
它相当于是对每个数据块应用三次DES 加密算法。由于计算机运算能力的增强,原版DES 密码的密钥长度变得容易被暴力破解;3DES 即是设计用来提供一种相对简单的方法,即通过增加DES 的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。
AES:
高级加密标准(英语:Advanced Encryption Standard,缩写:AES),在密码学中又称Rijndael 加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES,已经被多方分析且广为全世界所使用。经过五年的甄选流程,高级加密标准由美国国家标准与技术研究院(NIST)于2001 年11 月26 日发布于FIPS PUB 197,并在2002 年5 月26 日成为有效的标准。2006 年,高级加密标准已然成为对称密钥加密中最流行的算法之一。
DES 算法简介
DES 加密原理(对比特位进行操作,交换位置,异或等等,无需详细了解)
准备知识
Bit 是计算机最小的传输单位。以0 或1 来表示比特位的值
例如数字3 对应的二进制数据为:00000011
代码示例
int
i
=
97
;
String
bit
=
Integer
.
toBinaryString
(
i
);
//输出:97 对应的二进制数据为: 1100001
System
.
out
.
println
(
i
+
"对应的二进制数据为: "