更新时间:2021年03月18日 08时58分19秒 来源:黑马程序员论坛
最近有很多同学接触到了加密相关的内容,我们的课程中也涉及到了一部分加密算法的使用。但是由于时间关系,并没有非常深入的跟大家探讨加密的相关技术。今天我们就详细的来说一说主流加密算法的分类及各自的简单实现。
众所周知,网络上传递的很多数据,我们是不希望让“别有用心”的人获取到的,所以就产生了加密的需求。而数据有的加密,就会有人想要去解密。就像武侠小说中的正邪两派一样互相纠缠。而自然而然的就催生出了一系列的加密算法。数据加密就是对原来为明文的文件或数据按某种算法进行处理,使其成为通常称为“密文”的一段信息。通过这样的途径,来达到信息保护的目的。而解密,也就是加密的逆操作,代表把刚才说的“密文”还原为之前的数据供我们使用。我们现在常见的加密算法,有对称加密算法、非对称加密算法和散列摘要算法几种,我们一个个来看一看。
对称加密
对称加密算法使用的比较早,安全性略低。加密时,把数据原文和密钥一起进行运算,得到一个谁也无法识别的密文,这样的密文经过网络传输后,得到数据的一方要使用和加密时相同的密钥对密文进行逆运算,则把数据还原。举个例子:加密就是把原文所有数据“+1”,而解密就是把密文都“-1”。 AES、DES、3DES 都是对称的块加密算法,加解密的过程是可逆的。其中,DES算法使用的密钥长度为56位,相当于如果想要穷举破解,最多需要计算2ˆ56次。所以安全性较低。而3DES,看名字就知道,是DES算法的3次迭代,就是把DES加密后的数据换一个新的密钥再用DES算法加密两次。如果不是非常敏感的数据,DES算法已经足够使用了。
AES算法是为了取代DES算法而出现的,它采用了密码学的高级加密标准,密钥最少支持128位、192位和256位。所以对比DES,更加安全,也更加灵活高效。参考代码如下:
import net.pocrd.annotation.NotThreadSafe; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.SecureRandom; public class AesHelper { private SecretKeySpec keySpec; private IvParameterSpec iv; public AesHelper(byte[] aesKey, byte[] iv) { if (aesKey == null || aesKey.length < 16 || (iv != null && iv.length < 16)) { throw new RuntimeException("初始密钥长度错误"); } if (iv == null) { iv = Md5Util.md5(aesKey); } keySpec = new SecretKeySpec(aesKey, "AES"); this.iv = new IvParameterSpec(iv); } public AesHelper(byte[] aesKey) { if (aesKey == null || aesKey.length < 16) { throw new RuntimeException("密钥长度错误"); } keySpec = new SecretKeySpec(aesKey, "AES"); this.iv = new IvParameterSpec(Md5Util.compute(aesKey)); } public byte[] encrypt(byte[] resource) { byte[] result = null; Cipher cipher = null; try { cipher = Cipher.getInstance("AES/CFB/NoPadding"); cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv); result = cipher.doFinal(resource); } catch (Exception e) { throw new RuntimeException(e); } return result; } public byte[] decrypt(byte[] secret) { byte[] result = null; Cipher cipher = null; try { cipher = Cipher.getInstance("AES/CFB/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, keySpec, iv); result = cipher.doFinal(secret); } catch (Exception e) { throw new RuntimeException(e); } return result; } public static byte[] randomKey(int size) { byte[] result = null; try { KeyGenerator gen = KeyGenerator.getInstance("AES"); gen.init(size, new SecureRandom()); result = gen.generateKey().getEncoded(); } catch (Exception e) { throw new RuntimeException(e); } return result; } }
非对称加密
非对称加密算法的机制会略复杂,它会使用两个成对的密钥进行计算。其中一个叫做“公钥”,也就是公开的密钥,相当于谁都可以获取到的一个密钥。而另一个是“私钥”,这个是私有的,并不会公开。而在数据进行加密时,公钥和私钥是配对使用的。一个公钥对应一个私钥。数据可以使用公钥加密,也可以使用私钥加密。而公钥加密的数据,只有用私钥才能解密。同样的,私钥加密的数据,只有使用公钥才能解开。这样,如果两个人A和B需要传递数据。A可以生成一堆密钥,先把公钥通过网络传输给B,这个过程即使公钥被拦截泄露也不影响。此时B用A传递过来的公钥加密数据传给A,然后A使用自己的私钥进行解密即可。由于整个过程中,A的私钥并不会传输出去,所以公钥丢失也不会被人把数据破解。 RSA加密算法大家应该都见过,特别是使用GIT提交代码时,如果你用过SSH协议传输,这个算法一定不陌生。RSA是目前最有影响力的公钥加密算法,并且被普遍认为是目前最优秀的公钥方案之一。RSA能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。
还有一种加密算法叫做ECC,它比RSA使用的密钥更小,但是它的运算比RSA消耗更多性能,对CPU的要求更高,所以在一些需要考虑性能的场景不推荐使用。
摘要算法
严格意义上来说,摘要算法并不是用于加密解密数据的,因为摘要算法的密文并不能还原为原文。例如:MD5算法,无论多长的数据,经过MD5计算之后都会输出一个128bit的数据。而相同的数据通过MD5计算出的结果是相同的,所以MD5一般用于做文件的完整性校验。在Java中,我们可以非常方便的使用MD5来进行运算。
public static final byte[] md5(byte[] source) { try { MessageDigest md5 = MessageDigest.getInstance("MD5"); return md5.digest(source); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }
public static final byte[] md5(byte[] source) { try { MessageDigest md5 = MessageDigest.getInstance("MD5"); return md5.digest(source); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }
当然,常见的摘要算法还有SHA1,只不过SHA1的安全性比MD5更强一些。同样的,在Java中我们可以很容易使用它。
public static final byte[] md5(byte[] source) { try { MessageDigest md5 = MessageDigest.getInstance("SHA1"); return md5.digest(source); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }
推荐了解热门学科
java培训 | Python人工智能 | Web前端培训 | PHP培训 |
区块链培训 | 影视制作培训 | C++培训 | 产品经理培训 |
UI设计培训 | 新媒体培训 | 产品经理培训 | Linux运维 |
大数据培训 | 智能机器人软件开发 |
推荐黑马程序员热门教程
Python入门教程完整版(懂中文就能学会) | 零起点打开Java世界的大门 |
C++| 匠心之作 从0到1入门学编程 | PHP|零基础入门开发者编程核心技术 |
Web前端入门教程_Web前端html+css+JavaScript | 软件测试入门到精通 |