叮~ java最常用加密方式的实践与封装

分类

加密分为三种:

  1. 对称加密(symmetric),例如:AES、DES(已经被AES取代)等
  2. 非对称加密(asymmetric),例如:RSA、DSA等
  3. 摘要加密(digest),例如:MD5、SHA-1、SHA-256、HMAC等

以下的演示,一种是使用hutool封装好的方法,一种是使用自己封装的方法
如果是hutool封装的方法,则需要导入依赖
hutool简介:Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅

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

RSA

RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制
是非对称加密算法,所以需要公钥和私钥,而且公钥和私钥是有一定规则的,不能随意使用
然后就是使用公钥加密的话,就得用私钥加密
使用私钥加密,公钥解密

  • hutool
        //生成密钥方式
        KeyPair rsa = SecureUtil.generateKeyPair("RSA");
        String privateKey = Base64.encode(rsa.getPrivate().getEncoded());
        String publicKey = Base64.encode(rsa.getPublic().getEncoded());
        System.out.println("私钥:"+privateKey);
        System.out.println("公钥:"+publicKey);

下面是以私钥加密,然后公钥解密的情况进行
模拟场景:
用户端持有私钥,将请求进行rsa加密,然后将byte[]数组再加密为base64
然后被请求端持有公钥,先将base64进行解密,然后使用公钥进行rsa解密


        //公钥和私钥是需要成对生成的
        String publicKey="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkBbLK/MPqwZ2ZAcUmPJ88tltwYdfzTEK+/1lYfBnKczD5ZC4p5aigPkXxNCqnp/FI9g6EfDI1zKO2+yXhkuEpZqgqWuoTkWbL7oWxcDs02RH8dYtbDAogwZqpfyoC/LbzQGBdnWs+ZhEz7Gpzzo6Ou2s56U6WZmo1N9uL6sFfUUpPEUUWNCkUPuATh6YBSgllN74IJvfK5CxzmSWCea9H5l4DS+AH8fdiiSnJKKQyLSePo88iWgS5Ck0oMATbE0Q5wXvB8jTtHxUxGCPrA/nW5gxbeWR4sp8QADgU+gOuaW+TOaFblowJWHEgS/9wrc+Ds6Wk1OkFOhs36EAMBaZywIDAQAB";
        String privatekey="MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCQFssr8w+rBnZkBxSY8nzy2W3Bh1/NMQr7/WVh8GcpzMPlkLinlqKA+RfE0Kqen8Uj2DoR8MjXMo7b7JeGS4SlmqCpa6hORZsvuhbFwOzTZEfx1i1sMCiDBmql/KgL8tvNAYF2daz5mETPsanPOjo67aznpTpZmajU324vqwV9RSk8RRRY0KRQ+4BOHpgFKCWU3vggm98rkLHOZJYJ5r0fmXgNL4Afx92KJKckopDItJ4+jzyJaBLkKTSgwBNsTRDnBe8HyNO0fFTEYI+sD+dbmDFt5ZHiynxAAOBT6A65pb5M5oVuWjAlYcSBL/3Ctz4OzpaTU6QU6GzfoQAwFpnLAgMBAAECggEAETyo0XkiRrNfNlgifqmDiQm5t40aSNG1HrARkMXRkY6NYMkPTf0XM5aY4VKVFqTGUKNtTvgfDp9dt7F17vrZw3XcAmh+md550hvQ3ZdWvXMhqCyXAnpAXmxGFdVDxSooYT3s3t708mbk1HPMfJ3amXIVXSDG+jEHoW+ZHtq2rWWKs5/Vqvxk4BU0+vdnkXYuCxPsR9Ym+HxABVywquJt3+kj8UktuDEmk1NvxaQIEuIkx0VI83UOy07r8771s4p6THTKf+A2n+K6tk+aXiRSUXBneIOy+IT2E3XL8IRdji5B0xV1hIqUD+hQjM95KHU8YdHfO5RNSr8QWcBGhGttAQKBgQDDqfuHynNNEjpwX/GlnYjd+rb07i83aN7xPAbKyJXRGOXsbIU94EfeEevb8VFJjItSc42Bchw5EGbKYi4faI2aqNmQ8QFf7c542XjbExTYZ7mVHUBiUqHYoMxf1VcfnRYmIM2CzhJRs87fpkkn9fEwEOhDKvpODnCwzK646tAk1wKBgQC8hWeMM+niVOPmprfV5yxbagbboRqrdk/Gydp2Xv6ciZtjDv7tkQn29tmbXHd93clwDpi2Gn76NQJwbTv2i5QrTmYh2t7ADOeBPR1+2+Wfe54O9mtXZIlWjAJdzn2qlm2ik9PEIMzP/sDawt5H9Q3+nEI+EgeLWJx3WGljVFzgLQKBgGC/Kv0QsIRaUAUCm8SNKYDBGDfxke0u8JWNXbplBhcW3ZFSc2uN+1slt17QaqYYVUdWlZB88NGSd5D4jN/A3cusU6+kS064klAVD/oa7EK4vv2pMg2r2BT6JTP5lBOwo6QEsjlMVaiKZO8XFLMqm7Btm7qihJOV9kilXHtYt8SPAoGAKxuuQ+cTEkgrHPD+lJEaGYUzMEG0oYSaVXCO3gZ23kCxIYOqU5SY3LoxpE8Om999Unxj+zAv3PMGLcMstQHRzd1NiWxNB0lsHqdk+T87UK6pw+4hOYipxvqZB+5R2hIv279F61E8xEsSunNY9MdafeApXZwt0XVfwgKbhrUhz7kCgYBlmuj3s/ZJuz94gV7NpyONpj9kGEEzTAfrNEI2oND+SA8i2EBQjFWQb9LdfMOpVclPsXCOTPQ113i3KveTLicy0ZWQ4jVY1sc9U5EtN/9ZWTktoahIgpQ0YzUeH+7GDrM7LNQCOI55LkbV0OSK3wlGiemUYW2Aa2Cr08z7s6Y9Rg==";

        //私钥加密
        RSA rsa1 = new RSA(privatekey, null);
        byte[] encrypt1 = rsa1.encrypt("HELLO".getBytes(StandardCharsets.UTF_8), KeyType.PrivateKey);
        String base64Str = Base64.encode(encrypt1);
        System.out.println("加密后结果:"+base64Str);

        
        //公钥解密
        RSA dRsa = new RSA(null, publicKey);
        byte[] decrypt1 = dRsa.decrypt(Base64.decode(base64Str), KeyType.PublicKey);
        System.out.println(new String(decrypt1));

  • 自己封装

参考连接:https://blog.csdn.net/piaoranyuji/article/details/126140261

package com.walker.encrypt.util;

import lombok.extern.slf4j.Slf4j;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class RSAUtil {

    public static final String KEY_ALGORITHM = "RSA";

    private static final String PUBLIC_KEY = "RSAPublicKey";

    private static final String PRIVATE_KEY = "RSAPrivateKey";

    // 1024 bits 的 RSA 密钥对,最大加密明文大小
    private static final int MAX_ENCRYPT_BLOCK = 117;

    // 1024 bits 的 RSA 密钥对,最大解密密文大小
    private static final int MAX_DECRYPT_BLOCK = 128;

    // 生成密钥对
    public static Map<String, Object> initKey(int keysize) throws Exception {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        // 设置密钥对的 bit 数,越大越安全
        keyPairGen.initialize(keysize);
        KeyPair keyPair = keyPairGen.generateKeyPair();

        // 获取公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        // 获取私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        Map<String, Object> keyMap = new HashMap<>(2);
        keyMap.put(PUBLIC_KEY, publicKey);
        keyMap.put(PRIVATE_KEY, privateKey);
        return keyMap;
    }

    // 获取公钥字符串
    public static String getPublicKeyStr(Map<String, Object> keyMap) {
        // 获得 map 中的公钥对象,转为 key 对象
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        // 编码返回字符串
        return encryptBASE64(key.getEncoded());
    }

    // 获取私钥字符串
    public static String getPrivateKeyStr(Map<String, Object> keyMap) {
        // 获得 map 中的私钥对象,转为 key 对象
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        // 编码返回字符串
        return encryptBASE64(key.getEncoded());
    }

    // 获取公钥
    public static PublicKey getPublicKey(String publicKeyString) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] publicKeyByte = Base64.getDecoder().decode(publicKeyString);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyByte);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        return keyFactory.generatePublic(keySpec);
    }

    // 获取私钥
    public static PrivateKey getPrivateKey(String privateKeyString) throws Exception {
        byte[] privateKeyByte = Base64.getDecoder().decode(privateKeyString);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyByte);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        return keyFactory.generatePrivate(keySpec);
    }

    /**
     * BASE64 编码返回加密字符串
     *
     * @param key 需要编码的字节数组
     * @return 编码后的字符串
     */
    public static String encryptBASE64(byte[] key) {
        return new String(Base64.getEncoder().encode(key));
    }

    /**
     * BASE64 解码,返回字节数组
     *
     * @param key 待解码的字符串
     * @return 解码后的字节数组
     */
    public static byte[] decryptBASE64(String key) {
        return Base64.getDecoder().decode(key);
    }

    /**
     * 公钥加密
     *
     * @param text         待加密的明文字符串
     * @param publicKeyStr 公钥
     * @return 加密后的密文
     */
    public static String encrypt1(String text, String publicKeyStr) {
        try {
            Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, getPublicKey(publicKeyStr));
            byte[] tempBytes = cipher.doFinal(text.getBytes("UTF-8"));
            return Base64.getEncoder().encodeToString(tempBytes);
        } catch (Exception e) {
            throw new RuntimeException("加密字符串[" + text + "]时遇到异常", e);
        }
    }

    /**
     * 私钥解密
     *
     * @param secretText    待解密的密文字符串
     * @param privateKeyStr 私钥
     * @return 解密后的明文
     */
    public static String decrypt1(String secretText, String privateKeyStr) {
        try {
            // 生成私钥
            Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, getPrivateKey(privateKeyStr));
            // 密文解码
            byte[] secretTextDecoded = Base64.getDecoder().decode(secretText.getBytes("UTF-8"));
            byte[] tempBytes = cipher.doFinal(secretTextDecoded);
            return new String(tempBytes);
        } catch (Exception e) {
            throw new RuntimeException("解密字符串[" + secretText + "]时遇到异常", e);
        }
    }

    public static void main(String[] args) throws Exception {
        Map<String, Object> keyMap;
        String cipherText;
        // 原始明文
        String content = "你好你好";

        // 生成密钥对
        keyMap = initKey(1024);
        String publicKey = getPublicKeyStr(keyMap);
        System.out.println("公钥:"+publicKey);
        String privateKey = getPrivateKeyStr(keyMap);
        System.out.println("私钥:"+privateKey);

        // 加密
        cipherText = encrypt1(content, publicKey);
        System.out.println("加密后的密文:"+cipherText);

        // 解密
        String plainText = decrypt1(cipherText, privateKey);
        System.out.println("解密后明文:"+plainText);
    }
}


AES

密码学中的高级加密标准(Advanced Encryption Standard,AES),又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。

  • hutool
//随机生成密钥
        byte[] key = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();
        AES aes = SecureUtil.aes(key);

        //加密
        byte[] encrypt = aes.encrypt("hello");
        System.out.println(new String(encrypt));
        //解密
        System.out.println(aes.decryptStr(encrypt));
  • 封装
package com.walker.encrypt.util;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class AESUtil {
    private final static String AES = "AES";
    private static final String AES_ALGORITHM = "AES/ECB/PKCS5Padding";


    /**
     * 获取cipher
     */
    private static Cipher getCipher(byte[] key, int model) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException {
        SecretKeySpec aes = new SecretKeySpec(key, AES);
        Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
        cipher.init(model, aes);
        return cipher;
    }

    /**
     * 加密
     */
    public static String encrypt(byte[] data, byte[] key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = getCipher(key, Cipher.ENCRYPT_MODE);
        return Base64.getEncoder().encodeToString(cipher.doFinal(data));
    }

    /**
     * 解密
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = getCipher(key, Cipher.DECRYPT_MODE);
        return cipher.doFinal(Base64.getDecoder().decode(data));
    }


}

MD5

MD5的全称是Message-Digest Algorithm 5(信息-摘要算法),是不可逆的
作用:
是让大容量信息在用数字签名软件签署私人密匙前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的大整数)。它需要获得一个随机长度的信息并产生一个128位的信息摘要。

虽然md5是哈希加密,属于不可逆的,但是其他还是可以逆的,只是稍微复杂一下,所以密码加密还是不推荐使用md5,可以用使用security的BCryptPasswordEncoder

使用:
方式一: hutool

  • 使用
String HELLO="hello";
SecureUtil.md5(HELLO)

方式二:自己封装

package com.walker.encrypt.util;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Util {

    public static final String KEY_MD5 = "MD5";

    /***
     * MD5加密(生成唯一的MD5值)
     */
    public static String encrypt(String str) {
        byte[] digest = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
            digest  = md5.digest(str.getBytes(StandardCharsets.UTF_8));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        //16是表示转换为16进制数
        String md5Str = new BigInteger(1, digest).toString(16);
        return md5Str;
    }

}


base64

  • hutool
String encode = Base64.encode(HELLO);
System.out.println("加密后"+encode);
byte[] decode = Base64.decode(encode);
System.out.println("解密后:"+new String(decode));
  • 封装
package com.walker.encrypt.util;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import java.nio.charset.StandardCharsets;

public class Base64Util {

	/***
	 * BASE64解密
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String decryBASE64(String key) throws Exception{
		byte[] bytes = (new BASE64Decoder()).decodeBuffer(key);
		return new String(bytes);
	}

	/***
	 * BASE64加密
	 * @param key
	 * @return
	 * @throws Exception
	 */
	public static String encryptBASE64(String key) throws Exception{
		return (new BASE64Encoder()).encode(key.getBytes(StandardCharsets.UTF_8));
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WalkerShen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值