← 返回首页
常用加密算法对比
发表时间:2022-07-31 17:06:03
常用加密算法对比

1.加密与解密

数据加密 的基本过程,就是对原来为 明文 的文件或数据按某种算法 进行处理,使其成为不可读的一段代码,通常称为 “密文”。通过这样的途径,来达到保护数据不被非法人窃取、阅读的目的。

加密的逆过程为解密,即将该编码信息转化为其原始数据的过程。

2.MD5

MD5即 Message-Digest Algorithm 5(信息-摘要算法5),用于确保信息传输完整一致。严格意义上讲,MD5不是加密算法,是散列算法,或者叫做哈希算法。 加密算法一般指对称加密算法。

MD5是一种摘要算法,所谓摘要算法:又称哈希算法、散列算法,它通过一个函数,把任意长度的数据转换为一个长度固定的数据串,摘要结果是不可逆的,不能被还原为原始数据。

MD5常见的应用场景如下:

除了MD5常见的摘要算法,还有SHA算法,包括SHA-1,SHA-2(SHA-224,SHA-256,SHA-384,SHA-512)等等。

3.对称加密

对称加密算法:加密算法与解密算法的秘钥KEY一致。发送和接收双方都使用这个密钥对数据进行加密和解密。这就要求加密和解密方事先都必须知道加密的密钥。

AES:Advanced Encryption Standard。是最常用的对称加密算法,由于其密钥建立时间短、灵敏性好、内存需求低,因此被广泛使用。

4.非对称加密

加密和解密使用的是两个不同的密钥,这种算法称为非对称加密算法。

例子:甲方生成 一对密钥 并将其中的一把作为 公钥 向其它人公开,得到该公钥的 乙方 使用该密钥对机密信息 进行加密 后再发送给甲方,甲方再使用自己保存的另一把 专用密钥 (私钥),对加密后的信息 进行解密。

RSA:RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的一种加密算法。

RSA公开密钥密码体制的原理是:根据数论,寻求两个大素数比较简单,而将它们的乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

5.bcrypt加密

BCrypt加密:是一种类似MD5加盐的加密算法,但是与MD5加盐不同的是,每次会随机生成salt,salt再跟明文进行hash。

bcrypt加密有以下特点: - 对于同一个明文,每次生成的hash是不同的 - hash中包含了salt

bcrypt与md5对比如下: |选项|MD5|Bcrypt| |-|-|-| |密文长度|32位|60位| |安全性|安全性差。
密码相同时,加密后密文一样。
提升安全性的方案:加密前生成随机的盐值(字符串),将它与密码拼接,然后再使用md5加密。|安全性好。
密码相同时,生成的密文是不一样的。(因为它自动生成随机盐值)| |加密耗时|短|略长|

实例

创建maven项目,添加如下依赖:

<dependencies>
     <dependency>
         <groupId>cn.hutool</groupId>
         <artifactId>hutool-all</artifactId>
         <version>5.8.4</version>
     </dependency>

     <dependency>
         <groupId>org.mindrot</groupId>
         <artifactId>jbcrypt</artifactId>
         <version>0.4</version>
     </dependency>
</dependencies>

MD5摘要加密

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;

/*MD5摘要加密算法*/
public class MD5Demo {

    public static void main(String[] args) {

        String pass1 = "Hello,Welcome to Beijing!I am a chinese.";
        String pass2= "123456";
        String pass3 = "123456";

        Digester md5 = new Digester(DigestAlgorithm.MD5);

        String pass1_md5 = SecureUtil.md5(pass1);
        String pass2_md5 = SecureUtil.md5(pass2);
        String pass3_md5 = md5.digestHex(pass3);

        System.out.println("pass1_md5 value : " +pass1_md5);
        System.out.println("pass2_md5 length : " +pass2_md5);
        System.out.println("pass3_md5 length : " +pass3_md5);


        System.out.println("pass1_md5 length = " +  pass1_md5.length());
        System.out.println("pass2_md5 length = " +pass2_md5.length());

        System.out.println(pass1_md5.length() == pass2_md5.length());
    }
}

SHA256摘要加密

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;

/*SHA256摘要加密算法*/
public class SHADemo {

    public static void main(String[] args) {

        String pass1 = "Hello,Welcome to Beijing!I am a chinese.";
        String pass2= "123456";
        String pass3 = "123456";

        Digester sha = new Digester(DigestAlgorithm.SHA256);

        String pass1_sha = SecureUtil.sha256(pass1);
        String pass2_sha = SecureUtil.sha256(pass2);
        String pass3_sha = sha.digestHex(pass3);

        System.out.println("pass1_sha value : " +pass1_sha);
        System.out.println("pass2_sha length : " +pass2_sha);
        System.out.println("pass3_sha length : " +pass3_sha);

        System.out.println("pass1_sha length = " +  pass1_sha.length());
        System.out.println("pass2_sha length = " +pass2_sha.length());

        System.out.println(pass1_sha.length() == pass2_sha.length());
    }
}

AES对称加密算法


import cn.hutool.core.util.CharsetUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import java.nio.charset.StandardCharsets;

/*AES对称加密算法*/
public class AESDemo {

    public static void main(String[] args) {

        String pass1 = "123456";
        String pass2 = "123456";

        //如果使用相同的私钥
        byte[] secret_key = "assistant7654321".getBytes(StandardCharsets.UTF_8);

        //随机生成密钥
        byte[] key1 = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
        //随机生成密钥
        byte[] key2 = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();

        //构建
        SymmetricCrypto aes1 = new SymmetricCrypto(SymmetricAlgorithm.AES, key1);
        //构建
        SymmetricCrypto aes2 = new SymmetricCrypto(SymmetricAlgorithm.AES, key2);

        //密码加密
        byte[] encrypt1 = aes1.encrypt(pass1);
        byte[] encrypt2 = aes2.encrypt(pass2);

        System.out.println("pass1 的密文:" +new String(encrypt1));
        System.out.println("pass2 的密文:" +new String(encrypt2));
        //密码解密
        byte[] decrypt1 = aes1.decrypt(encrypt1);
        byte[] decrypt2 = aes2.decrypt(encrypt2);

        System.out.println("pass1 的明文:" +new String(decrypt1));
        System.out.println("pass2 的明文:" +new String(decrypt2));

        //加密为16进制表示
        String encryptHex1 = aes1.encryptHex(pass1);
        String encryptHex2 = aes2.encryptHex(pass2);

        System.out.println("pass1 的密码16进制:" + encryptHex1);
        System.out.println("pass2 的密码16进制:" + encryptHex2);

        //解密为字符串
        String decryptStr1 = aes1.decryptStr(encryptHex1, CharsetUtil.CHARSET_UTF_8);
        System.out.println("pass1 的明文:" +decryptStr1);
        String decryptStr2 = aes2.decryptStr(encryptHex2, CharsetUtil.CHARSET_UTF_8);
        System.out.println("pass2 的明文:" +decryptStr2);

    }
}

RSA非对称加密算法

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import java.security.PrivateKey;
import java.security.PublicKey;


/*RSA非对称加密算法*/
public class RSADemo {

    public static void main(String[] args) {
        RSA rsa = new RSA();

        //获得私钥
        PrivateKey privateKey= rsa.getPrivateKey();

        String privateKeyStr = rsa.getPrivateKeyBase64();
        System.out.println("私钥字符串:" + privateKeyStr);
        //获得公钥
        PublicKey publicKey = rsa.getPublicKey();
        String publicKeyStr = rsa.getPublicKeyBase64();
        System.out.println("公钥字符串:" + publicKeyStr);

        //公钥加密,私钥解密
        byte[] encrypt = rsa.encrypt(StrUtil.bytes("123456", CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
        byte[] decrypt = rsa.decrypt(encrypt, KeyType.PrivateKey);
        System.out.println("公钥加密,私钥解密=>解密后密码:"+ new String(decrypt));


        //私钥加密,公钥解密
        byte[] encrypt2 = rsa.encrypt(StrUtil.bytes("123456", CharsetUtil.CHARSET_UTF_8), KeyType.PrivateKey);
        byte[] decrypt2 = rsa.decrypt(encrypt2, KeyType.PublicKey);
        System.out.println("私钥加密,公钥解密=>解密后密码:"+ new String(decrypt2));

    }
}

Bcrypt加密算法


import org.mindrot.jbcrypt.BCrypt;


/*Bcrypt加密算法*/
public class BcryptDemo {
    public static void main(String[] args) {
        String password = "123456";
        // 加密
        String encodedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
        System.out.println("password 的密文:" +encodedPassword);

        // 使用正确密码验证密码是否正确
        boolean flag = BCrypt.checkpw(password, encodedPassword);
        System.out.println(flag);

        // 使用错误密码验证密码是否正确
        flag = BCrypt.checkpw("111222", encodedPassword);
        System.out.println(flag);

        System.out.println("-------------------对相同密码再次加密------------------------");

        //相同密文再次加密
        encodedPassword = BCrypt.hashpw(password, BCrypt.gensalt());
        System.out.println("password 再次加密的密文:" +encodedPassword);

    }
}

Bcrypt加密算法(基于Hutool工具类)

我们发现Hutool工具类内部就是使用了org.mindrot.jbcrypt.BCrypt,因此用法完全相同。


        String password1 = "123456";
        String password2 = "123456";
        String encodePass1 = BCrypt.hashpw(password1);
        String encodePass2 = BCrypt.hashpw(password2);

        System.out.println(encodePass1);
        System.out.println(encodePass2);

        if(BCrypt.checkpw(password1,encodePass1)){
            System.out.println("密码相同");
        }else{
            System.out.println("密码不同");
        }

        System.out.println("----------------------------");
        if(BCrypt.checkpw(password1,encodePass2)){
            System.out.println("密码相同");
        }else{
            System.out.println("密码不同");
        }
        System.out.println("----------------------------");
        if(BCrypt.checkpw("12345",encodePass2)){
            System.out.println("密码相同");
        }else{
            System.out.println("密码不同");
        }
    }