加解密

開發(fā)中經(jīng)常會(huì)有字符串加解密的需求,如用戶密碼加密,可以直接MD5/SHA1加密,MD5/SHA1是不可逆的,驗(yàn)證時(shí)可以對(duì)輸入做MD5/SHA1,然后比較加密后的字符串。但是如果有查詢明文密碼的需求呢?這就不能使用單向加密的方式了,需要使用雙向可逆的加解密,一般常見(jiàn)的有AES/DES/RSA,以下代碼展示了一個(gè)加解密工具類的實(shí)現(xiàn),使用了Java庫(kù)中的加密算法實(shí)現(xiàn)。
附: 常見(jiàn)加密算法以及安全性比較 https://www.cnblogs.com/davytitan/p/3850321.html

package com.cmb.ntms.extconnect.service.utils;

import javax.crypto.*;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.Security;

public class SecurityUtil {

//SecretKey 負(fù)責(zé)保存對(duì)稱密鑰
private SecretKey deskey;
//Cipher負(fù)責(zé)完成加密或解密工作
private Cipher cipher;

public SecurityUtil() throws NoSuchPaddingException, NoSuchAlgorithmException, UnsupportedEncodingException {
    KeyGenerator keygen = KeyGenerator.getInstance("AES");
    keygen.init(new SecureRandom("defaultSeed".getBytes("UTF-8")));

    /*KeyGenerator keygen = KeyGenerator.getInstance("AES");
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    random.setSeed("defaultSeed".getBytes());
    keygen.init(128, random);*/
    deskey = keygen.generateKey();
    cipher = Cipher.getInstance("AES");
}

/**
 * @param algorithm 加密算法
 * @param seed      種子
 * @throws NoSuchAlgorithmException
 * @throws NoSuchPaddingException
 */
public SecurityUtil(String algorithm, String seed) throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException {
    Security.addProvider(new com.sun.crypto.provider.SunJCE());
    //KeyGenerator 提供對(duì)稱密鑰生成器的功能,支持各種算法
    KeyGenerator keygen = KeyGenerator.getInstance(algorithm);
    keygen.init(new SecureRandom(seed.getBytes("UTF-8")));
    //生成密鑰
    deskey = keygen.generateKey();
    //生成Cipher對(duì)象,指定其支持的算法
    cipher = Cipher.getInstance(algorithm);
}

/**
 * 字符串加密
 *
 * @param str
 * @return
 * @throws InvalidKeyException
 * @throws IllegalBlockSizeException
 * @throws BadPaddingException
 */
public String encode(String str) throws InvalidKeyException,
        IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
    cipher.init(Cipher.ENCRYPT_MODE, deskey);
    byte[] src = str.getBytes("UTF-8");
    byte[] result = cipher.doFinal(src);

    //這里如果直接返回new String(result);再getBytes出來(lái),值是不一樣的,所以不直接將字節(jié)數(shù)組強(qiáng)轉(zhuǎn)成字符串,轉(zhuǎn)換為16進(jìn)制字符串返回
    //String底層是以Char(2個(gè)字節(jié))數(shù)組記錄的,Byte會(huì)轉(zhuǎn)化成Char,因?yàn)镃har和Byte的長(zhǎng)度不同,所以在轉(zhuǎn)化的過(guò)程中會(huì)對(duì)Byte進(jìn)行整合,主要是用0填充.
    return parseByte2HexStr(result);
}

/**
 * 對(duì)字符串解密
 *
 * @param str
 * @return
 * @throws InvalidKeyException
 * @throws IllegalBlockSizeException
 * @throws BadPaddingException
 */
public byte[] decode(String str) throws InvalidKeyException,
        IllegalBlockSizeException, BadPaddingException {
    cipher.init(Cipher.DECRYPT_MODE, deskey);
    //先解出字節(jié)數(shù)組
    byte[] strBytes = parseHexStr2Byte(str);
    return cipher.doFinal(strBytes);
}

/**
 * 二進(jìn)制轉(zhuǎn)16進(jìn)制字符串
 *
 * @param buf
 * @return
 */
private String parseByte2HexStr(byte buf[]) {
    StringBuilder sb = new StringBuilder();
    for (byte aBuf : buf) {
        String hex = Integer.toHexString(aBuf & 0xFF);
        if (hex.length() == 1) {
            hex = '0' + hex;
        }
        sb.append(hex.toUpperCase());
    }
    return sb.toString();
}

/**
 * 16進(jìn)制字符串轉(zhuǎn)為二進(jìn)制字節(jié)數(shù)組
 *
 * @param hexString
 * @return
 */
private byte[] parseHexStr2Byte(String hexString) {
    if (hexString == null || hexString.equals("")) {
        return null;
    }
    hexString = hexString.toUpperCase();
    int length = hexString.length() / 2;
    char[] hexChars = hexString.toCharArray();
    byte[] d = new byte[length];
    for (int i = 0; i < length; i++) {
        int pos = i * 2;
        d[i] = (byte) (toByte(hexChars[pos]) << 4 | toByte(hexChars[pos + 1]));
    }
    return d;
}

private static byte toByte(char c) {
    return (byte) "0123456789ABCDEF".indexOf(c);
}
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容