网易Ted有一节课是解释量子计算机,量子是物理的最小单位。现在的CPU的晶体是
纳米级别的,通过电流来计算0101。1纳米就是0.000001毫米,已经足够小了。
而量子可以表示更多的通电状态,不在局限于1和0, 可以是1,0,01,10,11,00,这样看,
如果计算机以这样的方式计算,效率也会呈指数上升。现代密码只给你穷举方式去破解,
md5 的长度是32位
每位出现的概率是【 a-z 0-9 】是36分之一
根据排列组合 一共是 36^32次方 约等于 6.33^49 种
苹果A13 处理器每秒运算 1万亿次 =10^13
破解所需 6.33^49 / 10^13 约等于 6.33^36 秒 = 2^29 年
如果CPU的计算能力也能像指数上升,破解一个32位的md5密码也会成为可能。
这节课提出计算密码就是X*Y = 复杂的密码。只要计算机够快穷举X,Y的值就可以得到密码。
这比喻太形象了。但是现在很多网站的js加密我都不知道怎么破解,先学习下历史。
加密方式
CTF密码学常见加密解密总结 | CSDN(CTF => Capture The Flag => 黑客夺旗赛)
1.古埃及人加密方式: 明文通过密码本转换成秘文。有了密码本就能破解
2.斯巴达人的加密方式:把一块布绑在一根特别的棍子上然后书写明文。
然后在将布解开进行传送,这时候字母成打乱状态。有那根特定的棍子在捆上去就能破解。
3.中国古代将信息写在小块丝绸上,塞进一个小球里,再用蜡给封上,然后让信使吞下这个蜡球。
抓到信使严刑拷打应该就能拿到密文。
4.16世纪,意大利科学家乔瓦尼•波塔描述了如何将信息埋藏在一个煮熟的鸡蛋里:
他把少许明矾和一点醋混在一起制成一种墨水,再用这种墨水将信息写在鸡蛋壳表面。
墨水溶液就会经蛋壳上的微孔渗透进去,在已凝固的鸡蛋白表面留下印迹,
这样只能剥去蛋壳后才能读取。只要剥开鸡蛋就能发现异常。
5.古希腊历史学家波利比奥斯基将字母转换成坐标。拿到坐标表就能破解。
6.罗马人恺撒发明了一种字母替换加密方法。明文按照26个字母顺序进行偏移。
只要观察重复的字母就能得到偏移量,然后修正就可以得到明文。
7.1542苏格兰女王玛丽, 托马斯·菲利普破解了玛丽谋反的证据。得到密码本就能破解。
8.1586维吉尼亚加密法,26*26的字母表,每一行的偏移量相差为1。秘钥和明文交叉得到密文。
使用字母表不断重复秘钥和密文便能拿到明文。凯撒和维吉尼亚不能加密特殊字符,只能加密字母。
9.二战的恩尼格码,类似增强版字母表,相当于17576*17576的字母表,只能通过机器去破解。
但是这种加密方法显然只是把A变成了别的字母, 还是1对1的关系,穷举字母排列,
在那个时代必须要有计算机才能破解这么复杂的密码,
排除不合理的单词和连句就能轻易破解。图灵居然是同性恋。
10.1942 年,美国人把29 名印第安那瓦霍族人被征召入伍。因为他们的语言没有外族人能够听懂,
所以美军将他们训练成专门的译电员,人称「风语者」,他们的语言到现在都还没有人能够破解。
这只有抓到印第安那瓦霍族人才能破解。
11.1837年的摩斯电码,只是一种电信号通信方式。每个字母由点(dit)和横(dah)组成。
字母和字母之间用空格隔开,单词和单词用\隔开。
12.栅栏密码把将要传递的信息中的字母交替排成上下两行。
就是把要加密的明文分成N个一组,然后把每组的第1个字连起来,形成一段无规律的话
培根密码就是一种替换密码,但是它只用ab来表示,难以发现。
密码的破解
在网上一查,密码的破解非常复杂,有电脑,手机键盘当密码本。多次使用不同的方法加密。
利用国际棋盘,盲文等等。破解密码需要超凡的知识,有的密码可能一辈子都破解不了。
破解的价值必须要大于>密码能提供的价值 = 才能促使人破解密码
现代加密
Base64
base64编码,过去只用到64个基础字符
ASCII256编码:base64的升级版,可以表示256个字符
base64一个字符占6个bit,而ASCII一个字母占8个bit,一个字节32个bit
如果把ASCII的A转换成base64编码
编码 | 二进制 |
---|---|
ASCII | 01000001 后面补充24个0 |
base64 | 010000 + 010000 + 8个0 + 8个0 |
010000因为计算机高字节在前面应该倒过来,000010 => 2的4次方 = 16 => Q
所以按照base64的显示应该是 (ASCII)A =>(base64)QQAA
但是base64编码有规定,结尾8个0只能为=号,所以应该是QQ==
我发现base64的0为A,意味着在ASCII编码里面敲一个空格转成base64编码就一定会出现A
base64编码的特点
只会出现大小写字母和数字及'+','/','='
MD5(Message-Digest Algorithm)
由美国罗纳德·李维斯特编写,在1992年公开,在MD5之前还有MD2,3,4。
要想看懂MD5的算法,我觉得我是不可能看懂的。
md5加密是把字符变成一个特征,每一个字母或者字符都有一个独一无二的特征,叫离散值。
像这种md5不可逆的加密,我根据描述的想象,就是历史中的字母表变成了
大小写字母52位,数字10个,算32位的长度,一共有62^32的可能性。
如果将来的计算机一次可以计算62^32次数,就可以把md5的答案给匹配出来了。
现在计算机算出来这个值是无限大。
md5密码的特征
通常固定长度为16位,32位,64位,由大小写字母和数字组成
现在网上短于8位的纯数字的md5和一些常用的密码是可以轻易破解的。
使用md5加密极度相似的数据会呈现完全不同的md5值
缺点是md5已经有20多年的历史了,现在已经有2500亿条的MD5数据库,不是很安全
如何判断函数是MD5加密函数
MD5-16进制的哈希码 | 十进制 |
---|---|
0x67452301 | 1732584193 |
0xefcdab89 | 4023233417 |
0x98badcfe | 2562383102 |
0x10325476 | 271733878 |
SHA(Secure Hash Algorithm)
这个是我在网站遇到加密用的最多的函数
有6个算法: SHA-0, SHA-1、SHA-224、SHA-256、SHA-384、和SHA-512,后4者被称为SHA-2
它和MD5的共同点就是很难逆转,逆转需要强大的计算量。但是它比MD5的复杂度提高了。
现在在推行SHA-3,强调SHA-3基于硬件特性会比SHA-2快很多。
SHA系列加密法 | 加密特征 |
---|---|
SHA-1 | 40个字符,由字母和数字组成 |
SHA-224 | 56个字符,由字母和数字组成 |
SHA-256 | 56个字符,由字母和数字组成 |
SHA-384 | 96个字符,由字母和数字组成 |
SHA-512 | 128个字符,由字母和数字组成 |
SHA-3 | 号称更快,加密字符长度不受限制,显示特征还是一样 |
HMacsSHA-1 | 相当于对普通SHA的2次加密,HMAC是一个密钥,显示特征还是一样 |
SHA-1
美国国家安全局设计,于1993年公开,加密后显示为40个十六进制数。
2017年2月23日,Google公司公告宣称他们与CWI Amsterdam合作共同创建了两个有着相同的SHA-1
值但内容不同的PDF文件,这代表SHA-1算法已被正式攻破。
sha-1的密码特征
发现SHA-1就比MD5多了一个哈希值,这么相似的
SHA-1:16进制的哈希码 | 十进制 |
---|---|
0x67452301 | 1732584193 |
0xefcdab89 | 4023233417 |
0x98badcfe | 2562383102 |
0x10325476 | 271733878 |
0xC3D2E1F0 | 3285377520 |
SHA-2
SHA-224和SHA-256基本上是相同的,
h0到h7的初始值不同,以及SHA-224输出时截掉h7的值。
SHA-224:16进制哈希码 | 十进制 |
---|---|
0xc1059ed8 | 3238371032 |
0x367cd507 | 914150663 |
0x3070dd17 | 812702999 |
0xf70e5939 | 4144912697 |
0xffc00b31 | 4290775857 |
0x68581511 | 1750603025 |
0x64f98fa7 | 1694076839 |
0xbefa4fa4 | 3204075428 |
SHA-256:16进制哈希码 | 十进制 |
---|---|
0x6a09e667 | 1779033703 |
0xbb67ae85 | 3144134277 |
0x3c6ef372 | 1013904242 |
0xa54ff53a | 2773480762 |
0x510e527f | 1359893119 |
0x9b05688c | 2600822924 |
0x1f83d9ab | 528734635 |
0x5be0cd19 | 1541459225 |
看Jeff Mott写的MSHA-256算法看的我一脸懵逼,算法里面没有直接写出这些哈希值。
直接搜索特征码是搜不出的,放在一个隐性的字符串数组里面。比较了SHA-224和SHA-256的
算法居然一模一样,只是哈希值不一样。
但是SHA-224多干了一件事去除了后4个字节(f.sigBytes -= 4)。
如何判断SHA-224和SHA-255, 在js
b[0] = b[0] + e | 0;
b[1] = b[1] + f | 0;
b[2] = b[2] + g | 0;
b[3] = b[3] + k | 0;
b[4] = b[4] + h | 0;
b[5] = b[5] + l | 0;
b[6] = b[6] + m | 0;
b[7] = b[7] + n | 0;
找这个特征,字母可以是别的单词,
SHA-255会有8个这样的等式
SHA-1会有5个这样的等式
SHA-512
SHA-512和SHA-256的结构相同,但
SHA-512所有的数字都是64位,
SHA-512运行80次加密循环而非64次,
SHA-512初始值和常量拉长成64位,以及
二者比特的偏移量和循环位移量不同。
SHA-512/SHA-384:16进制哈希码 | 十进制 |
---|---|
0xcbbb9d5dc1059ed8 | -3766243637369397544 |
0x629a292a367cd507 | 7105036623409894663 |
0x9159015a3070dd17 | -7973340178411365097 |
0x152fecd8f70e5939 | 1526699215303891257 |
0x67332667ffc00b31 | 7436329637833083697 |
0x8eb44a8768581511 | -8163818279084223215 |
0xdb0c2e0d64f98fa7 | -2662702644619276377 |
0x47b5481dbefa4fa4 | 5167115440072839076 |
SHA-384
SHA-384和SHA-512基本上是相同的,除了:
SHA-384输出时截掉h6和h7的函数值.意味着SHA-384会比SHA-512更短
SHA-384在输出时干了(a.sigBytes -= 16)
JS里面区分SHA-512和SHA-256
SHA-512的标志128
_doFinalize: function() {
var a = this._data
, c = a.words
, d = 8 * this._nDataBytes
, f = 8 * a.sigBytes;
c[f >>> 5] |= 128 << 24 - f % 32;
c[(f + 128 >>> 10 << 5) + 30] = Math.floor(d / 4294967296);
c[(f + 128 >>> 10 << 5) + 31] = d;
a.sigBytes = 4 * c.length;
this._process();
return this._hash.toX32()
},
SHA-256的标志64
_doFinalize: function() {
var a = this._data
, d = a.words
, b = 8 * this._nDataBytes
, e = 8 * a.sigBytes;
d[e >>> 5] |= 128 << 24 - e % 32;
d[(e + 64 >>> 9 << 4) + 14] = g.floor(b / 4294967296);
d[(e + 64 >>> 9 << 4) + 15] = b;
a.sigBytes = 4 * d.length;
this._process();
return this._hash
},
DES(Data Encryption Standard)
由IBM公司1975年发明的,主要用于通信,数据加密,可逆,在2001年AES成为了DES的替代品。
与MD5,SHA是不同的,经过DES加密的数据是可以通过密钥解出来的。
DES不会丢失数据本来的面目,而MD5和SHA只是记录数据的特征,通常用于密码存储。
DES的加密数据,长度也会随着数据长度而改变。
对称加密:
通信双方同时掌握一个密钥,加密解密都是由一个密钥完成的(即加密密钥等于解密密钥,
解密密钥可以相互推倒出来)。双方通信前共同拟定一个密钥,不对第三方公开
说实话每一个加密我都看不懂。但是我知道搜索特征。
57, 49, 41, 33, 25
des加密的置换规则表,一定会出现的数字
des加密的数据会出现大小写字母,+,/,数字,= ,其它字符还没有见过
des是区分大小写的
des加密一个字符的长度为32个字符
我理解的DES就是,数据就像拼图, 密钥就是如何打乱数据,
DES根据密钥把数据的二进制码重新排列数据。
破解DES要的是时间,有这样的一台PC机器,它能每秒计算一百万次,
那么256位空间它要穷举的时间为2285年.所以这种算法还是比较安全的一种算法。
3DES(或称为Triple DES)
DES的升级版,对每个数据块应用三次DES加密算法。历史查不到。
FIPS PUB 46-3(1999)定义了“三重数据加密算法”。
据说3DES是向AES过渡的算法
AES(Advanced Encryption Standard)
该算法为比利时密码学家Joan Daemen和Vincent Rijmen所设计,
结合两位作者的名字,以Rijdael之名命之。
AES又被称为Rijndael加密法。功能就是替代DES。
我感觉是因为CPU的计算步长增加才需要AES,从8-16位的CPU过渡到32-64位的CPU
AES的基本要求是,采用对称分组密码体制,密钥的长度最少支持为128、192、256,
分组长度128位,算法应易于各种硬件和软件实现。而DES的密钥是64位的。
在现在的32,64位CPU上,AES加密的数据会比DES运行更快,复杂度更高。
AES和DES的写法是完全不同的。看不懂看不懂,字节代换,行移位,列混合,轮密钥加。
AES有个特征就是4*4的矩阵,和两个16×16的S数组,称为S盒和一个逆S盒。
AES加密一个字符的长度为44个字符,区分大小写, 有大小写字母,数字,/,+
AES的特征
0x63 0x7c 0x77 0x7b 开头的数组
0x52 0x09 0x6a 0xd5 开头的数组
Rabbit加密
Rabbit流密码是由Cryptico公司设计的,密钥长度128位,最大加密消息长度为264 Bytes,
即16 TB,若消息超过该长度,则需要更换密钥对剩下的消息进行处理。
关于这个加密方式的网上能查到的很少。但是这个加密方法还是很容易找到的,看不懂。
RC4(Rivest Cipher 4)
RC4是由罗纳德·李维斯特在1987年开发出来的,这个人还设计了MD5,RSA的加密方法。
这个算法写的非常短,但我还是看不懂。
在我的想法里面就是拿到数据,然后打乱它,然后根据计算机异或的特性来设计加密。
要尽量产生很多种可能。
/*初始化函数*/
void rc4_init(unsigned char*s, unsigned char*key, unsigned long Len)
{
int i = 0, j = 0;
char k[256] = { 0 };
unsigned char tmp = 0;
for (i = 0; i<256; i++)
{
s[i] = i;
k[i] = key[i%Len];
}
for (i = 0; i<256; i++)
{
j = (j + s[i] + k[i]) % 256;
tmp = s[i];
s[i] = s[j];//交换s[i]和s[j]
s[j] = tmp;
}
}
/*加解密*/
void rc4_crypt(unsigned char*s, unsigned char*Data, unsigned long Len)
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k<Len; k++)
{
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j];//交换s[x]和s[y]
s[j] = tmp;
t = (s[i] + s[j]) % 256;
Data[k] ^= s[t];
}
}
unsigned char s[256] = { 0 }, s2[256] = { 0 };//S-box
char key[256] = { "justfortest" };
char pData[512] = "这是一个用来加密的数据Data";
unsigned long len = strlen(pData);
rc4_init(s, (unsigned char*)key, strlen(key));//初始化密钥
rc4_crypt(s, (unsigned char*)pData, len);//加密
rc4_init(s,(unsignedchar*)key,strlen(key));//初始化密钥
rc4_crypt(s2, (unsigned char*)pData, len);//解密
RSA(三个美国大学生的名)
由美国麻省理工的三个学生,罗纳德·李维斯特,阿迪·萨莫尔,伦纳德·阿德曼1977年共同设计。
现在主要用于私密信息交换上,防止他人篡改信息。
RSA属于非对称性加密:钥与私钥是一对,如果用公钥对数据进行加密,只有用对应的私钥才能解密。
(1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
(2)甲方获取乙方的公钥,然后用它对信息加密。
(3)乙方得到加密后的信息,用私钥解密。
非对称加密的缺点是加解密速度要远远慢于对称加密.
使用https,用户传过来的公钥应该是存放在内存里面,好像每一次连接都会创建公钥。
2722301142506