加密解密篇

加密解密篇

在某些場景,加密是必須的操作,如:數據庫用戶信息,密碼,關鍵業務信息等。

在我看來,加密分爲兩種,分別有他們對應的場景。

  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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章