加密解密篇

加密解密篇

在某些场景,加密是必须的操作,如:数据库用户信息,密码,关键业务信息等。

在我看来,加密分为两种,分别有他们对应的场景。

  1. 可解密:需要回显,处理等的数据,如:用户姓名。
  2. 不可解密:不需要回显,只需判断的,如:用户密码。

一.可解密

可解密的算法有很多种,我不是从事这个领域的专业人员,故不对概念做阐述,目前来看,会用、知道是什么加密即可。

观前警告

本篇文章加密算法,后端均依赖于Hutool工具类,POM引入即可。官网

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

1. AES加密

最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的)。

其中:密码(KEY)偏移量(THE_OFFSET)模式(Mode)补码方式(Padding),这几个字段信息,可以根据实际进行修改。

import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;


public class AESUtil {

    private static final String KEY = "123456789ABCDEFG";

    private static final String THE_OFFSET = "1234567898765432";

    private static AES getAes() {
        return new AES(Mode.CTS, Padding.PKCS5Padding, KEY.getBytes(), THE_OFFSET.getBytes());
    }

    /**
     * 加密
     * @param content 加密内容
     * @return 加密结果
     */
    public static String encrypt(String content) {
        if (StrUtil.isEmpty(content)) {
            return "";
        }
        return getAes().encryptHex(content);
    }

    /**
     * 解密
     * @param encryptHex 加密字段
     * @return 解密结果
     */
    public static String decrypt(String encryptHex) {
        if (StrUtil.isEmpty(encryptHex)) {
            return "";
        }
        String res = "";
        try {
            res = getAes().decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
        } catch (Exception e) {
           log.error("解密信息无效:{}",encryptHex);
        }
        return res;
    }

    public static void main(String[] args) {
        String encrypt = encrypt("LitongZero");
        System.out.println(encrypt);

        String decrypt = decrypt(encrypt);
        System.out.println(decrypt);

    }
}

2. RES加密

RES加密,需要两组秘钥,分别是公钥和私钥。一般,我们使用公钥进行加密,公私钥进行解密。当然,也可以私钥加密,公钥解密。实际可以根据需求而定,而私钥往往存在服务器,以防暴露。


import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.json.JSONUtil;

import java.util.Map;

/**
 * @author litong
 * @date 2020/4/27 0:11
 */
public class MyRESUtil {
    final static String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOHrv6o1clkfaHTYwbmMuVrsmANDVrkIBrXdqzZjLjIo1Z0npQ0ZRRUsCYC4aee7jJxyVXYDEKzaVRVs6gMeAeZ4QiBsZUqxhHr9q9IrE+M7nknt6fotUt8LxiVnyRAjwLmSu503s4tGP15yudzPchyMC8+ZNphUQ8FtEtGIKOwQIDAQAB";
    final static String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAM4eu/qjVyWR9odNjBuYy5WuyYA0NWuQgGtd2rNmMuMijVnSelDRlFFSwJgLhp57uMnHJVdgMQrNpVFWzqAx4B5nhCIGxlSrGEev2r0isT4zueSe3p+i1S3wvGJWfJECPAuZK7nTezi0Y/XnK53M9yHIwLz5k2mFRDwW0S0Ygo7BAgMBAAECgYApM2OH2haVX/PTX+Dds1Eefm2wvr7e3WeODpiku4z4cfOnPLdOaFYpW008FzG1hC2Px8rjCEtFSY3+EEgFJXMSxMOZPWIr/nrmHTdIue7mXHIE0cC/yDiIxfgYkw1QB4mNClg3sQj7kkMmUHhOosRw7QgPrKKTLleZ/Qs7cWzusQJBAPRtw9C1Nh6Fp14UdBAZKgeOkx1ciCtifFGHMshQOGRELEGfZxPd/0s77fPEo/sU08zlGUUUSduqBVNkQ0oVNF8CQQDX4LSlT7R2ZQrwMZJy03sN6SnhE7BEFeOZuBE+K6kdCdb65QEJ3Es/cI9EVT/MWiRepJhvbioyf41cYFGZvBDfAkEAhMVm+2SjnBq/miQEE4aHxQkWMnnD4cUigGqvFA43Q4egfpjmtez9stE/5Q0ogceDcSX0/wgRQoftUqoAvyobgwJAR61UTY8pXCYwe4/6ECYntXa1cQYYgILED0YOc5YLkJizyJpAvgVm9qlo6Edl53QGn2YHNvhdCmdPiFxyu5i2AQJAZpoVtYVEH2do6Yc3QIlRJr1SHGJ9uh43/DnGXuhbNWLKVI2nMYb695FmYl8VqixoVk9Cvsd7AnNRPFixWo8aaQ==";


    /**
     * 加密
     *
     * @param str 待加密信息
     * @return 加密后内容
     */
    public static String decrypt(String str) {
        try {
            RSA rsa = new RSA(PRIVATE_KEY, PUBLIC_KEY);
            byte[] encrypt = rsa.encrypt(StrUtil.bytes(str, CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);
            return Base64.encode(encrypt);
        } catch (Exception e) {
            return "";
        }
    }


    /**
     * 解密
     *
     * @param str
     * @return 解密后信息
     */
    public static String encrypt(String str) {
        RSA rsa = new RSA(PRIVATE_KEY, PUBLIC_KEY);
        try {
            byte[] decrypt = rsa.decrypt(str, KeyType.PrivateKey);
            return StrUtil.str(decrypt, CharsetUtil.CHARSET_UTF_8);
        } catch (Exception e) {
            return "";
        }
    }

    public static void main(String[] args) {
        // 使用hutool随机获取一对公私钥
        RSA rsa = new RSA();
        //获得私钥
        System.out.println(rsa.getPrivateKey());
        System.out.println(rsa.getPrivateKeyBase64());
        //获得公钥
        System.out.println(rsa.getPublicKey());
        System.out.println(rsa.getPublicKeyBase64());

        String a = decrypt("{\"idCardNumber\":\"123456789\",\"name\":\"Litong\"}");
        System.out.println(a);
        System.out.println(encrypt(a));
    }

}

二.不可解密

摘要加密,顾名思义,无法还原数据本身内容,故无法解密。

当然,有一种解密,叫爆破解密,据说,量子计算机,可以分分钟暴力破解MD5,而这不是现在要考虑的(笑)。

1. MD5

SecureUtil.md5("idCardNumber:123456789");

2. SHA-256

SecureUtil.sha256("idCardNumber:123456789");

3…

等等,Hutool实现的摘要加密算法有很多种,基本都是直接使用的,如上述。官网

MD2
MD5
SHA-1
SHA-256
SHA-384
SHA-512
HmacMD5
HmacSHA1
HmacSHA256
HmacSHA384
HmacSHA512

三. 前端

某些场景,需要我们跟前端一起进行加解密操作,如:防篡改。

1. AES加密

// 密码
const key = '123456789ABCDEFG'
// 偏移量
const iv = '1234567898765432'
// 待解密内容
const text = '8e65a9a7a00503b1c1becb8d2922f77e'

// 解密
let decrypted = CryptoJS.AES.decrypt(
CryptoJS.enc.Base64.stringify(CryptoJS.enc.Hex.parse(text))
, CryptoJS.enc.Utf8.parse(key), {
iv: CryptoJS.enc.Utf8.parse(iv),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
console.log(decrypted.toString(CryptoJS.enc.Utf8).toString())
console.log(decrypted.toString(CryptoJS.enc.Utf8).toString(CryptoJS.format.Hex))

2. RES加密

需要一个js加密工具类,下载地址。h5等端的可以直接使用。

微信小程序,需要加一下东西,适配。地址,密uehp

//公钥
var PUBLIC_KEY = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOHrv6o1clkfaHTYwbmMuVrsmANDVrkIBrXdqzZjLjIo1Z0npQ0ZRRUsCYC4aee7jJxyVXYDEKzaVRVs6gMeAeZ4QiBsZUqxhHr9q9IrE+M7nknt6fotUt8LxiVnyRAjwLmSu503s4tGP15yudzPchyMC8+ZNphUQ8FtEtGIKOwQIDAQAB';
//使用公钥加密
var encrypt = new JSEncrypt();
encrypt.setPublicKey('-----BEGIN PUBLIC KEY-----' + PUBLIC_KEY + '-----END PUBLIC KEY-----');
var str = {
"uid":"1223334",
"pwd":"asd"
}
var encrypted = encrypt.encrypt(JSON.stringify(str));
console.log('加密前数据:%o', str);
console.log('加密后数据:%o', encrypted);

3.摘要加密

大同小异,基本操作如下。

引入https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.js

md5(pwd)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章