首页
搜索 搜索

5分钟讲清楚常用加密算法-速讯

腾讯云     2023-03-25 16:22:23

为什么要加密?

当然是为了保密。

最早的密码应用,都伴随着阴谋与战争。


(相关资料图)

中国古代的“阴符”、“阴书”就是其中的代表。

到了近代,二战最著名的一个故事,就是纳粹德国的Enigma密码机

以及图灵和他发明的密码破解机。

可以说,现代战争中,信息安全极其重要

如果你的部署、命令都被对手知道

你收到的指令都是对手伪造的

这还怎么打?

在当下,加密数据和密码的应用,

从军事,到商业领域,以及科学界

乃至每个人普通的生活

如果没有数据加密,每个人的信息都是透明的

想想可怕的电话诈骗,你还觉得自己的信息安全吗?

有一句话说的是:

大数据时代,没有秘密

加密方式

最常见的计算机加密方式有三种:

对称、非对称、摘要

对称的意思是:

我有一个秘钥K,能把原文 A 加密成 A1,还能把 A1 还原成 Af(A, K) =A1f(A1, K) =A

对称加密用途最为广泛,

操作简单,速度快,

适合场合多样

但缺点很明显,秘钥K太关键了

如果你需要让密文被其他授信的人访问

必须给他发秘钥

但问题是,

只要得到秘钥,就能破解一切,包括非法用户

非对称安全性稍微高一点

有2个秘钥,一般是成对的公钥和私钥

通常是用公钥加密,私钥解密

这种情况下,解决了对称加密的发送秘钥问题

现在公钥是公开的,私钥只有我自己有

永远不发送,就不会泄密

摘要加密一般采用的是hash算法,

只加密不解密,

适合于只验证对不对,而不验证是什么。

举个朴素例子:

二中的学生,学号格式是 L220130103 格式

三中的学生,学号格式是 PLE821 格式

现在我要验证这个人是哪个学校的,

其实无需关注具体内容,

简单判断一下长度就可以了

当然真正的算法没这么简单

下面具体来谈

便于大家统一理解

我们建一个项目

统一使用hutool工具包

        cn.hutool        hutool-all        5.8.5    

对称加密

最简单的是des方法

他使用一个简单的秘钥,就可以实现加密和解密

我们写一个junit的test,或者写一个main也可以

class Test1 {@Testvoid test() {String text0 = "这是原文";String key = "xiaomian";DES des = new DES(key.getBytes());String text1=des.encryptBase64(text0);System.out.println(text1);}}

运行结果是 +iJWs7q8+dyiRBouA8lDBA==

我们使用秘钥 “xiaomian”,

把“这是原文”,加密成了一个看不懂的字符串

然后开始解密

class Test1 {@Testvoid test() {String key = "xiaomian";DES des = new DES(key.getBytes());String text2=des.decryptStr("+iJWs7q8+dyiRBouA8lDBA==");System.out.println(text2);}}

运行结果是 这是原文

还是同一个key,

用相反的方法,把原文解出来了

操作非常简单。

des就是一个最简单的对称加解密方法

类似的还有aes算法

可以使用hutool工具包,

操作差不多

非对称加密

使用非对称的主要原因

就是 安全、安全、还是安全

非对称在性能方面和对称没的比

因此,建议非对称使用短数据场合

而长数据使用对称实现。

最常用的是RSA算法

首先要生成一对秘钥,这个就没法人工创造了

我们可以借助工具

class Test2 {@Testvoid test() {        KeyPair pair = SecureUtil.generateKeyPair("RSA");        String privateKey = Base64.encode(pair.getPrivate().getEncoded());        System.out.println("privateKey:" + privateKey);        String publicKey = Base64.encode(pair.getPublic().getEncoded());        System.out.println("publicKey:" + publicKey);}}

输出结果为:

privateKey:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALBgrUOQySQB72VrGyijYZcaNM26t49oaKlNddu4SLpEdJzpUnVjXtIi9Nj/DkFBXgSB9FYdrv7MpQWzTmLw0do6pcfo2cekmBGPnFRdChtEf8Npq0pAV2LlNahwkB8fxZcbQYaaWBuBkx7aHT09JGsEpi9P3y7ae4vwYmFlWgEHAgMBAAECgYBVBnXgEWb1Zb1rLaPNBl3gQrDb0Dv29QUnQIElZ4QfzypMDipDDqFCObnA9cuAZ6uUDrWj4fFfQXX39oU+KwtuESddT9rJw1hPSy2i5ityEyYO5OZQRJaTVWPWzpph+bqFLkngaOvlr3OBG7YtywUL0P8toz2pOQKpoQOkffetuQJBAP26GKiOcs/sKhrzuM/t0S2ERXXDcu07jWxJ8gioQBuQaM7AA14tbiRzaZm3Xt+cGPjHJUGEJpDvGLQ9MavEZDMCQQCx9S+JevTGpxHMX/R3uUawlTsks1keyd0rqBtqQQx7V9Bm8htrlVU3QbhacFd/FJodWX7mGOAO6nLVGK/5qXvdAkB13zSBadvwuDg/WSZsgoEA8kgKk4gaqeXjft7QIsnVhFsMYauu3tAiYvOWE9ghbbU0LeAi9a+s+UayxRMERzJ9AkA5Y7fL32I2+kQMI9nEDnUUl1u2bzxLaJAx9wm4T3gGAwDLYkKjhEoyArjAOcCN1AgLdQQuklEXnlYgENEXc6flAkEAwDbTBfOtuP/6S5nU0gX9D5fYlF/fz4YTfBjHC2dZ/wrmWlJA0f7QFf5DysQB9AXJX6ZWL/3LkMtHPafqBMKpJw==publicKey:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCwYK1DkMkkAe9laxsoo2GXGjTNurePaGipTXXbuEi6RHSc6VJ1Y17SIvTY/w5BQV4EgfRWHa7+zKUFs05i8NHaOqXH6NnHpJgRj5xUXQobRH/DaatKQFdi5TWocJAfH8WXG0GGmlgbgZMe2h09PSRrBKYvT98u2nuL8GJhZVoBBwIDAQAB

看吧,鬼也看不懂

不过能用就行

接下来,开始使用秘钥对,进行加密和解密

class Test2 {static String privateKey;static String publicKey;@BeforeAllstatic void createKey() {        KeyPair pair = SecureUtil.generateKeyPair("RSA");        privateKey = Base64.encode(pair.getPrivate().getEncoded());        System.out.println("privateKey:" + privateKey);        publicKey = Base64.encode(pair.getPublic().getEncoded());        System.out.println("publicKey:" + publicKey);}@Testvoid test() {String text = "这是原文";RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), privateKey, publicKey);        String text1 = rsa.encryptBase64(text, KeyType.PublicKey);        System.out.println("公钥加密: " + text1);        String text2 = rsa.decryptStr(text1, KeyType.PrivateKey);        System.out.println("私钥解密: " + text2);}}

输出结果为:

公钥加密: KSifTf6tS6LGlBT9LJC33VXzkXtaQEIGJcpf1BU2ptzRXTtBzvjx83EffCqntD7/M7ZciTr4MIBFBPFCxLs9NVEeC4K9/B8fQE/3hdsMzWBTnKQzQR2vd1i5mOgFaHYwTLwrq9Dbkv1YGluCb004YtLEqdjSO/Oljs7x2YVtvGc=私钥解密: 这是原文

也可以反过来用

@Testvoid test() {String text = "这是原文";RSA rsa = new RSA(AsymmetricAlgorithm.RSA_ECB_PKCS1.getValue(), privateKey, publicKey);        String text1 = rsa.encryptBase64(text, KeyType.PrivateKey);        System.out.println("私钥加密: " + text1);        String text2 = rsa.decryptStr(text1, KeyType.PublicKey);        System.out.println("公钥解密: " + text2);}
私钥加密: Ty5YGXHUajKHtlmQ7yGYJtc39Rjb3IvSIm7WWg4+Ge6u8MDeJ3TLYZokgBbAMZRcZBZ8bIWiou12+KxoW8moRwke4PlWVipgwhC2l6qo7WtTMiwnGh+0+B8wnY3OySFK4ZeOMQFgYuiTL2uZqofLXyNzwID7GKCfWI6EL29wtbE=公钥解密: 这是原文

对称算法的特点就是

随便先用谁,然后用另一个解

一般来说,有意义的信息,加密传递

建议使用 公钥加密,私钥解密

这种方法,确保信息只能由你指定的对象收到

另一种反过来的做法,

私钥加密,公钥解密

用于数字签名场合

证明这个签名是某人做的

因为只有他有他自己的私钥

摘要加密

摘要加密是单向的

能加不能解

主要目的是生成特征码

常用算法包括 md5,sha 等等

class Test3 {@Testvoid test() {String text = "这是原文";String text1 = DigestUtil.md5Hex(text);        System.out.println(text1);}}

输出结果是:

531ffeed49bb13a6cf93049cc1e5ee53

比如系统密码,一般采用摘要加密

假设我的密码是 123456,

md5之后变成了 e10adc3949ba59abbe56e057f20f883e

如果有人能看到数据库表,

哪怕他找到了我的密码 e10adc3949ba59abbe56e057f20f883e,

也不知道我实际的密码是123456

当登陆时,会对用户输入的密码再次md5,

如果结果还等于e10adc3949ba59abbe56e057f20f883e,

就表示输对了密码。

摘要加密的特点是

输出结果位数是固定的

比如上面列出的md5,加密后永远是固定长度

他的特点主要是:

输入不同,加密结果就不同输入相同,加密结果一定相同

现在一般md5用的也少,主要是长度和复杂度

一般使用 sha256 或 sha512

他可以做简化验证

比如,我有一个文档,大小为 100M

如何验证他的内容发生串改

我们不可能拿2个100M的文件,逐个字节比较

这时,只要对2者分别做摘要运算,

得到一个短的字符串,对他们比较就可以了

这种验证的特点是:我知道你对和不对,但我不知道哪错了

总结

三种方法中,一般使用原则是

速度快,用对称安全高/数据少,用非对称用于验证对错,保留特征码,用摘要

大家可以试试,顺便安利一下hutool,

非常优秀的工具包

之后我们会专文介绍国密算法

X 关闭

华中工业网版权所有

备案号:京ICP备12018864号-26邮箱:2 913 236 @qq.com