【加密解密】常见的加解密算法

摘要算法

介绍

摘要算法是一种能产生特殊输出格式的算法,这种算法的特点是:无论用户输入什么长度的原始数据,经过计算后输出的密文都是固定长度的,这种算法的原理是根据一定的运算规则对原数据进行某种形式的提取,这种提取就是摘要,被摘要的数据内容与原数据有密切联系,只要原数据稍有改变,输出的“摘要”便完全不同,因此,基于这种原理的算法便能对数据完整性提供较为健全的保障。

但是,由于输出的密文是提取原数据经过处理的定长值,所以它已经不能还原为原数据,即消息摘要算法是不可逆的,理论上无法通过反向运算取得原数据内容,因此它通常只能被用来做数据完整性验证。

摘要算法主要用途有

  • 消息完整性验证:发送消息时,将发送数据与MD5值一起发送,然后可以从MD5值来验证接收到的消息是否完整。常见的有下载文件等场景,服务端提供一个文件的下载地址和文件的MD5值,客户端再下载完成后验证文件的MD5,如果与服务端的值不同,说明下载出问题了,需要重新下载。
  • 安全访问认证:如数据库存储登录密码的MD5值,这样就可以保证即使管理员也无法查看到常用密码;
  • 数字签名:常见的场景有对接口参数进行签名,来实现服务端对客户端的可靠性验证。客户端和服务端各自持有一个秘钥key,网络接口请求时,通过对时间戳timestamp+接口参数+秘钥key进行MD5计算,然后将MD5值作为参数传给服务端,服务端通过相同的加密算法来验证MD5值是否相同,通过这样来验证客户端的可信性,有效防止网络爬虫

常见的摘要算法

- MD2
- MD5
- SHA-1
- SHA-256
- SHA-384
- SHA-512

Java实现

使用hutool内置的安全包

    @Test
    public void t1(){
        String md5Hex1 = DigestUtil.md5Hex("1234");
        String sha1Hex = DigestUtil.sha1Hex("1234");
        String sha256Hex = DigestUtil.sha256Hex("1234");
        System.out.println(md5Hex1);
        System.out.println(sha1Hex);
        System.out.println(sha256Hex);
    }

响应数据:

81dc9bdb52d04dc20036dbd8313ed055
7110eda4d09e062aa5e4a390b0a572ac0d2c0220
03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4

对称加密

介绍

对称加密(也叫私钥加密)指加密和解密使用相同密钥的加密算法。有时又叫传统密码算法,就是加密密钥能够从解密密钥中推算出来,同时解密密钥也可以从加密密钥中推算出来。而在大多数的对称算法中,加密密钥和解密密钥是相同的,所以也称这种加密算法为秘密密钥算法或单密钥算法。它要求发送方和接收方在安全通信之前,商定一个密钥。对称算法的安全性依赖于密钥,泄漏密钥就意味着任何人都可以对他们发送或接收的消息解密,所以密钥的保密性对通信的安全性至关重要。

常见的对称加密算法

AES (默认AES/ECB/PKCS5Padding)
ARCFOUR
Blowfish
DES (默认DES/ECB/PKCS5Padding)
DESede
RC2
PBEWithMD5AndDES
PBEWithSHA1AndDESede
PBEWithSHA1AndRC2_40

Java实现

    @Test
    public void t2() {
        String content = "test中文";
        
        SymmetricCrypto aes = new SymmetricCrypto(SymmetricAlgorithm.AES, "testkey123456789".getBytes(StandardCharsets.UTF_8));
        //加密为16进制表示
        String encryptHex = aes.encryptHex(content);
        //解密为字符串
        String decryptStr = aes.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
        System.out.println(encryptHex + "," + decryptStr);
    }

响应数据

a71a8f467af464ff6da7d21b6be9196c,test中文

非对称加密

介绍

对于非对称加密,最常用的就是RSA和DSA,在Hutool中使用AsymmetricCrypto对象来负责加密解密。

非对称加密有公钥和私钥两个概念,私钥自己拥有,不能给别人,公钥公开。根据应用的不同,我们可以选择使用不同的密钥加密:

  1. 签名:使用私钥加密,公钥解密。用于让所有公钥所有者验证私钥所有者的身份并且用来防止私钥所有者发布的内容被篡改,但是不用来保证内容不被他人获得。
  2. 加密:用公钥加密,私钥解密。用于向公钥所有者发布信息,这个信息可能被他人篡改,但是无法被他人获得。

常见的非对称加密算法

RSA
RSA_ECB_PKCS1(RSA/ECB/PKCS1Padding)
RSA_None(RSA/None/NoPadding)
ECIES(需要Bouncy Castle库)

Java实现

    @Test
    public void t3() {
        //生成公私钥对
        KeyPair pair = SecureUtil.generateKeyPair("RSA");
        PrivateKey privateKey = pair.getPrivate();
        PublicKey publicKey = pair.getPublic();
        //获得私钥
        String privateKeyStr = bytesToBase64(privateKey.getEncoded());
        System.out.println("私钥:" + privateKeyStr);
        //获得公钥
        String publicKeyStr = bytesToBase64(publicKey.getEncoded());
        System.out.println("公钥:" + publicKeyStr);

//        RSA rsa = new RSA(privateKeyStr, publicKeyStr);
//        System.out.println(rsa);
        RSA rsa1 = new RSA(null, publicKeyStr);
        //公钥加密,私钥解密
        byte[] encrypt = rsa1.encrypt(StrUtil.bytes("123456", CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
        System.out.println("公钥加密:" + bytesToBase64(encrypt));

        RSA rsa2 = new RSA(privateKeyStr, null);
        byte[] decrypt = rsa2.decrypt(encrypt, KeyType.PrivateKey);
        System.out.println("私钥解密:" + new String(decrypt, StandardCharsets.UTF_8));
    }

    /**
     * 字节数组转Base64编码
     *
     * @param bytes 字节数组
     * @return Base64编码
     */
    private static String bytesToBase64(byte[] bytes) {
        byte[] encodedBytes = Base64.getEncoder().encode(bytes);
        return new String(encodedBytes, StandardCharsets.UTF_8);
    }

    /**
     * Base64编码转字节数组
     *
     * @param base64Str Base64编码
     * @return 字节数组
     */
    private static byte[] base64ToBytes(String base64Str) {
        byte[] bytes = base64Str.getBytes(StandardCharsets.UTF_8);
        return Base64.getDecoder().decode(bytes);
    }

你可能感兴趣的:(算法,java,servlet)