总结几种常用的安全算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
总结⼏种常⽤的安全算法
本⽂简单总结⼏种常⽤的安全算法
摘要算法
对称加密算法
⾮对称加密算法
数字签名
数字证书
web安全系列⽬录
数字摘要
实现
将任意长度的明⽂通过单向hash函数摘要成固定长度的串。
Hash(明⽂)-->固定长度的摘要
特点
⽆论明⽂多长,计算出来的摘要长度总是固定的。
hash(‘a’)和hash(‘aaaaaaaaaaa’)形成的摘要长度是⼀样的
⼀般明⽂不同,计算出来的摘要也不同。
也就是相同的明⽂,计算出来的摘要是⼀样的,不同的明⽂形成的摘要⼀般是不⼀样(好的hash函数不会发⽣碰撞)
只能进⾏正向的消息摘要。
也就是说从消息摘要中不能恢复成原来的明⽂。
数字摘要算法
md5
sha
md5
将待加密串进⾏md5计算形成128⽐特位(32位16进制)的摘要。
字符串:jiajun
md5摘要:a51c0678c060ae4c4630d930fe83102c
SHA-1
将待加密串进⾏SHA计算后形成160⽐特位(40位16进制)的摘要。
对⽐md5,摘要信息更长,运算过程更复杂,速度更慢,但相对也更加安全。
字符串:jiajun
SHA-1摘要:26352d75496932fd05e65724610ce1aaadf9259c
base64不是⼀种加密算法⽽是⼀种编码算法
将⼆进制数据编码成ascll码。
⽐如说我们将图⽚以json的形式上传到服务器,那么可以将图⽚⼆进制数据通过base64编码转化为⼆进制。
base64是可逆的,通过解码算法可以恢复成⼆进制数据,所以根本不能加密。
彩虹表破解hash算法
上⾯提到的两种数字摘要算法md5和sha-1都是不可逆算法,那么如何破解呢?彩虹表是⼀种破解的⽅式。
明⽂hash算法密⽂
xxx md5xxx
xxx sha-1xxx
彩虹表破解法通过这样的⼀张表进⾏查询,⽐如攻击者拿到了⼀个⽤户密码密⽂,是通过md5算法加密的,那么他可以在这样的⼀张表进⾏查询,从⽽查到密码的明⽂。
彩虹表是不断的积累的过程,表的内容不断丰富,从⽽破解的机率慢慢提⾼。
如果⽤户的密码是常见的密码,⽐如说⽣⽇,攻击者知道有些⽤户会⽤⽣⽇作为密码,那么攻击者可以提前将这些⽣⽇组合进⾏计算,提前记录在表⾥⾯。
那么在彩虹表查询很快可以查询的到密码明⽂。
⽽如果密码较为复杂,如果泄露了密⽂,根据⽣成的密⽂在彩虹表进⾏查询,是很难查到的(因为表⾥⾯并没有)。
这也就是为什么我们为⽤加盐的⽅法降低破解率的原因了。
对称加密
实现
发送⽅和接收⽅约定⼀个密钥,⽣成加密密⽂发送。
接收⽅接受后,使⽤相同的密钥和加密算法的逆算法进⾏解密。
通俗将,我给⼩花写⼀封情书,然后放在⼀个上锁的⼩箱⼦,经过多⼈的,最后到达⼩花,⼩花通过相同的钥匙打开箱⼦。
但是如果钥匙中途被⼈捡到,那么情书就公开了。
所谓对称指的是加密解密⽤同⼀个加密密钥。
特点
算法是公开的,加密速度快。
⼀旦泄露密钥,因为算法是公开的,所以可以轻松解密。
应⽤分析
A向B发送秘密⽂件,这个时候可以采⽤对称加密算法,没有密钥者不能解密⽂件。
如果密钥泄露那么⽂件可以被解密,⽽且随着技术的发展,如果采⽤穷举暴⼒解密也是有可能。
如果A向很多⼈发送秘密⽂件,那么需要多次约定。
对称加密算法
DES算法,密钥64位
AES算法,,密钥长度之处128,192,256三种,加密强度更⾼。
DES(Data Encryption Standard):数据加密标准,速度较快,适⽤于加密⼤量数据的场合。
3DES(Triple DES):是基于DES,对⼀块数据⽤三个不同的密钥进⾏三次加密,强度更⾼。
AES(Advanced Encryption Standard):⾼级加密标准,是下⼀代的加密算法标准,速度快,安全级别⾼;
⾮对称加密
实现
A向B发送消息,B先产⽣⼀个公钥和私钥,然后将公钥公开,A获得公钥。
然后⽤公钥进⾏加密,然后将密⽂发送给B。
B得到后⽤私钥进⾏解密。
特点
⾮对称加密更加复杂,所以加密解密速度没有对称加密快,但是也更加安全。
⾮对称加密算法
RSA算法
应⽤分析
即使中途有⼈截获⽂件,因为没有私钥,并且加密算法复杂,解密是很困难的。
如果A向多⼈发送秘密⽂件,那么他不需要多次约定的过程,从公钥库根据接收⽅的公钥分别进⾏加密就⾏。
数字签名
实现
A给B发送信息,A⽣成公钥和私钥,将公钥公开。
A对发送消息进⾏数字摘要算法,然后再通过私钥进⾏加密。
A将加密后的密⽂和原⽂发送给B
B收到后,对密⽂⽤公钥进⾏解密,获得串C,再⽤原⽂进⾏摘要算法,获得串D,然后对⽐C D。
这样就能确认A的⾝份。
数字签名:将明⽂进⾏摘要,然后再通过私钥进⾏加密的结果
数字签名算法
MD5withRSA算法
SHA1withRSA算法
应⽤分析
B收到A的⽂件,B想确认是A发送的,那么可以根据数字签名⽅式,根据A的公钥进⾏解密然后⽐较,因为A的私钥是不公开的,这样匹配成功就能确认是A发送的。
数字证书
实现
A给B发送消息,A⽣成公钥和私钥。
A将公钥,还有公钥持有者,签名算法,过期时间等信息发送给CA(数字证书认证机构)
CA认可信息之后,通过CA的私钥进⾏签名,这时候数字证书就产⽣了。
接着A将明⽂,明⽂数字签名,和数字证书⼀起发送给B
B接受到后,通过CA的公钥进⾏解密,进⾏第⼀次校验,校验数字证书。
验证成功后,进⾏第⼆次检验,提取数字证书中的公钥,对密⽂进⾏解密。
应⽤分析
在数字签名的基础上,再发送⼀个数字证书,这样的话接收⽅不需要维护⼀个公钥库,通过CA验证后在数字证书提取,获得公钥。
Suppose you encrypt two messages with the same key, and the two messages begin with the same 16 bytes of plaintext. (16 bytes is the block size for AES, regardless of the key size.) Will the first block of ciphertext be the same? If it is, you're already leaking some information to the attacker. Whether this information is sensitive or not depends on your application, but it's already a bad sign. If the encryption leaks more than the sign of the messages, it's not doing its job.
The basic idea of an IV is to prepend a bit of random content to each message, in a principled way. How this works precisely depends on the mode. (The core AES operation only works on 16-byte blocks. A mode is a way to extend this to longer messages.) For example, with , the encryption of each block is computed from the key, the plaintext block and the ciphertext of the previous block; for the very first block, the IV is used instead of the ciphertext of the non-existent previous block. The IV is normally sent in cleartext alongside the ciphertext, usually it is sent a the first 16 bytes of the encrypted message.
mode technically uses a counter and not an IV, but operationally they work very similarly: a 16-byte random value is generated at random by the sender and sent at the beginning of the encrypted message. With CTR mode, reusing that value for another message is catastrophic, because CTR works by XORing the plaintext with a pseudorandom stream deduced from the key and counter. If you have two encrypted messages that use the same counter value, their XOR is the XOR of the two plaintexts.
There are more attacks against improperly-chosen IVs than I've listed here. Generate a random IV for each message (using a cryptographic-quality random generator, the same you'd use to generate a key), and you'll be fine.
There is one exception: if you generate a fresh key for each message, you can pick a predictable IV (all-bits 0 or whatever). You still need to use a mode with an IV (ECB is not fine, for example it exposes repetitions in the plaintext since two identical input blocks will have the same encryption). That's a rare case though (it arises for storage, not for communication).
Note that encryption a priori only ensures the confidentiality of the data, not its integrity. Depending on what you do with the data, this may be a problem. In particular, if an attacker can submit tentative ciphertexts to be decrypted, or can provide additional plaintexts to be
encrypted, this can expose some information. Some modes such as and provide : a ciphertext will only be decrypted if it's genuine. Use one of these if possible.
Note also that .
If you aren't comfortable with what you're doing, try to use some high-level library rather than grappling with the crypto directly.
⼤意是说 IV 没什么特殊⽤处,就是让相同的明⽂,经过使⽤不同的 IV 再加密后,其秘⽂每次都是不⼀样的,这样防⽌模式攻击。
另外,IV 需存放在秘⽂之前,且IV采⽤明⽂存储。
⾄于⾥⾯说 AES-128和AES-256安全程度⼀样,个⼈觉得还是有点差异的,不然位数不同就没意义了,但对个⼈使⽤者来说,差异不⼤。
PKCS5Padding与PKCS7Padding的理解
在采⽤AES、DES等块加密时,有时需要对不满⾜⼀个整块(block)的部分需要进⾏填充,我们常⽤的填充的⽅式就包括ZeroPadding、PKCS5Padding与PKCS7Padding,这⾥⾯有什么区别呢。
填充⽅式的区别
ZeroPadding,数据长度不对齐时使⽤0填充,否则不填充。
使⽤0填充有个缺点,当元数据尾部也存在0时,在unpadding时可能会存在问题。
我们这⾥主要讨论PKCS7Padding与PKCS5Padding。
(1)PKCS7Padding,
假设每个区块⼤⼩为blockSize
<1>已对齐,填充⼀个长度为blockSize且每个字节均为blockSize的数据。
<2>未对齐,需要补充的字节个数为n,则填充⼀个长度为n且每个字节均为n的数据。
(2)PKCS5Padding,PKCS7Padding的⼦集,只是块⼤⼩固定为8字节。
两者的区别在于PKCS5Padding是限制块⼤⼩的PKCS7Padding
具体代码实现
按照以上的定义,我们⽤golang实现如下:
func PKCS7Padding(cipherText []byte, blockSize int) []byte {
padding := blockSize - len(cipherText)%blockSize
padText := bytes.Repeat([]byte{byte(padding)}, padding)
return append(cipherText, padText...)
}
func PKCS5Padding(cipherText []byte) []byte {
return PKCS7Padding(cipherText, 8)
}
在解密后,需要将填充的字符去掉,取最后⼀位即知道存在多少个补充位,但⼀般需要多取⼏位校验⼀下最后⼀位是否为真实数据,⼀般⾸尾和中间都取⼀下,甚⾄将全部padding进⾏对⽐。