java对称加密

DES

简介

DES(Data Encryption Standard)是一种对称加密算法。DES 算法已经被证明不够安全,因此已经被 AES 算法所取代。

注意:默认情况下DES加密算法的key字符串长度必须是8(使用一下的buildSecretKey方法生成key不受该限制)

使用示例

public class DESTest {

    public static final String ALGORITHM_NAME= "DES"; // 算法名称
    public static final String DEMO_STR= "法律";
    // 加密算法的key 注意,此处的key字符串长度必须是8
    public static final String ALGORITHM_KEY = "abcdefgh";

    @Test
    public void test1() {
        String encryption = EnDencryptionUtil.encryption(DEMO_STR, ALGORITHM_NAME, ALGORITHM_KEY);
        System.out.println(ALGORITHM_NAME + "加密之后的16进制字符串数据是:" + encryption);

        String decryption = EnDencryptionUtil.decryption(encryption, ALGORITHM_NAME, ALGORITHM_KEY);
        System.out.println(ALGORITHM_NAME + "解密之后的原始字符串是:" + decryption);
    }
}

AES

简介

Advanced Encryption Standard)是一种对称加密算法,AES 算法比 DES 算法更安全,加密和解密速度也更快

注意:默认情况下AES加密算法的key的长度必须是:16、24、32(使用一下的buildSecretKey方法生成key不受该限制)

使用示例

public class AESTest {

    public static final String ALGORITHM_NAME= "AES"; // 算法名称
    public static final String DEMO_STR= "法律";
    // 加密算法的key 注意,此处的key字符串长度必须是8
    public static final String ALGORITHM_KEY = "abcdefgh12345678";

    @Test
    public void test1() {
        String encryption = EnDencryptionUtil.encryption(DEMO_STR, ALGORITHM_NAME, ALGORITHM_KEY);
        System.out.println(ALGORITHM_NAME + "加密之后的16进制字符串数据是:" + encryption);

        String decryption = EnDencryptionUtil.decryption(encryption, ALGORITHM_NAME, ALGORITHM_KEY);
        System.out.println(ALGORITHM_NAME + "解密之后的原始字符串是:" + decryption);
    }
}

工具类:

import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * AES的默认分组模式是:ECB(electronic code book) 填充模式是:PKCS5Padding,所以:AES、AES/ECB/PKCS5Padding等价的
 *
 * ECB每次计算的结果一样  分组并行加密
 * CBC 串行处理,同样的原文每次生成的密文不一致(在实现上,当调用cipher.init时需要加入一个IvParameterSpec)
 */
public class EnDencryptionUtil {

    public static final String UTF8= StandardCharsets.UTF_8.name();

    /**
     * 加密
     *
     * @param sourceStr 原始字符串
     * @param algorithm 加解密算法
     * @param key 秘钥 注意不同算法对key字符串的长度有限制
     *  DES  key长度是8
     *  AES  key的长度可以是:16、24、32
     * @return 16进制字符串
     */
    public static String encryption(String sourceStr,String algorithm,String key) {
        try {
            Cipher cipher = Cipher.getInstance(algorithm);
            SecretKey secretKey = new SecretKeySpec(key.getBytes(UTF8), algorithm);
            cipher.init(Cipher.ENCRYPT_MODE,secretKey);
            byte[] bytes = cipher.doFinal(sourceStr.getBytes(UTF8));
            /**
             * 加密之后的字节数组转字符串有2个方向
             *
             * 1 把字节转16进制的字符串
             * 2 使用org.apache.kerby.util.Base64#encodeBase64String(byte[])
             */
            return Hex.encodeHexString(bytes);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String decryption(String hexStr,String algorithm,String key) {
        // 16进制字符串转字节数组(加密之后的原始字节数组)
        try {
            byte[] bytes = Hex.decodeHex(hexStr);
            Cipher cipher = Cipher.getInstance(algorithm);
            SecretKey secretKey = new SecretKeySpec(key.getBytes(UTF8), algorithm);
            cipher.init(Cipher.DECRYPT_MODE,secretKey);
            byte[] originalBytes = cipher.doFinal(bytes);
            return new String(originalBytes,StandardCharsets.UTF_8);
        } catch (DecoderException | NoSuchAlgorithmException | NoSuchPaddingException | UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException | InvalidKeyException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 采用该方式生成SecretKey时,秘钥字符的长度不受限制
     *
     * @param algorithm 算法
     * @param seed 秘钥串
     * @return javax.crypto.SecretKey
     * @throws NoSuchAlgorithmException 算法异常
     * @throws UnsupportedEncodingException 编码异常
     */
    public static SecretKey buildSecretKey(String algorithm,String seed) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(algorithm);
        SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
        secureRandom.setSeed(seed.getBytes(UTF8));
        keyGenerator.init(128,secureRandom);
        SecretKey secretKey = keyGenerator.generateKey();
        return new SecretKeySpec(secretKey.getEncoded(), algorithm);
    }


    public static void main(String[] args) throws NoSuchAlgorithmException {
        String demoStr = "法律";
        String key = "abcdefgh";
        String algorithm = "AES";
        String des = encryption(demoStr, algorithm, key);
        System.out.println(algorithm + "加密之后的16进制数据是:" + des);

        String decryption = decryption(des, algorithm, key);
        System.out.println(algorithm + "解密之后的数据是:" + decryption);
    }
}

  • 7
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值