编解码

Base64

建议使用org.apache.commons.codec.binary.Base64类库。
注意标准和url safe的base64。

DES

    /**
     * DES 加密
     * @param password
     * @param data
     * @return
     */
    @SneakyThrows
    public static byte[] encrypt(String password, String data) {
        if (password == null || password.length() < 8) {
            throw new RuntimeException("加密失败,key不能小于8位");
        }
        if (data == null) {
            return null;
        }
        // 生成一个可信任的随机数源
        SecureRandom sr = new SecureRandom();
        
        // 从原始密钥数据创建DESKeySpec对象
        DESKeySpec dks = new DESKeySpec(password.getBytes(StandardCharsets.UTF_8));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey =  keyFactory.generateSecret(dks);

        // Cipher对象实际完成解密操作
        Cipher cipher = Cipher.getInstance("DES");
        // 用密钥初始化Cipher对象
        cipher.init(Cipher.ENCRYPT_MODE, secretKey, sr);
        byte[] bytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return bytes;
    }
    /**
     * DES 解密
     * @param password
     * @param data
     * @return
     */
    @SneakyThrows
    public static String decrypt(String password, byte[] data){
        if (data == null) {
            return null;
        }

        SecureRandom sr = new SecureRandom();
        DESKeySpec dks = new DESKeySpec(password.getBytes(StandardCharsets.UTF_8));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey =  keyFactory.generateSecret(dks);

        Cipher cipher = Cipher.getInstance("DES");

        cipher.init(Cipher.DECRYPT_MODE, secretKey, sr);
        return new String(cipher.doFinal(data),StandardCharsets.UTF_8);
    }

RAS

import lombok.SneakyThrows;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;

import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSAUtils {

    /**
     * 生成密钥
     * @param seed 种子
     * @return 密钥对象
     * @throws Exception
     */
    public static void generateKey(String seed) throws Exception {
        KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
        SecureRandom secureRandom = new SecureRandom();
        // 如果指定seed,那么secureRandom结果是一样的,所以生成的公私钥也永远不会变
        // secureRandom.setSeed(seed.getBytes());
        // Modulus size must range from 512 to 1024 and be a multiple of 64
        keygen.initialize(2048, secureRandom);

        KeyPair keys = keygen.genKeyPair();
        PrivateKey privateKey = keys.getPrivate();
        PublicKey publicKey = keys.getPublic();
    }


    /**
     * 用私钥对信息进行数字签名
     * @param data 加密数据
     * @param privateKey 私钥 - base64加密后的
     */
    @SneakyThrows
    public static byte[] signByPrivateKey(byte[] data, String privateKey) {
        // base64 解密私钥
        byte[] keyBytes = Base64.decodeBase64(privateKey);

        KeyFactory factory = KeyFactory.getInstance("RSA");
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
        // 生成私钥
        PrivateKey priKey = factory.generatePrivate(keySpec);

        // 用私钥对信息进行数字签名
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(priKey);
        signature.update(data);
        return signature.sign();
    }

    /**
     * 使用 公钥 校验签名
     * @param data
     * @param publicKey
     * @param signByte
     */
    @SneakyThrows
    public static boolean verifyByPublicKey(byte[] data, String publicKey, byte[] signByte) {
        byte[] keyBytes = Base64.decodeBase64(publicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey pubKey = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(pubKey);
        signature.update(data);
        // 验证签名
        return signature.verify(signByte);
    }

    /**
     * RSA公钥加密
     * @param str 加密字符串
     * @param publicKey 公钥
     */
    @SneakyThrows
    public static byte[] encodeWithPublicKey(String str, String publicKey) {
        // base64解码的公钥
        byte[] keyBytes = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
            .generatePublic(new X509EncodedKeySpec(keyBytes));

        //该密钥能够加密的最大字节长度
        int maxBitLength = pubKey.getModulus().bitLength() / 8 - 11;

        // RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);

        byte[] data = str.getBytes(StandardCharsets.UTF_8);
        byte[] encodeBytes = null;
        for (int i = 0; i < data.length; i += maxBitLength) {
            // 注意要使用2的倍数,否则会出现加密后的内容再解密时为乱码
            byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + maxBitLength));
            encodeBytes = ArrayUtils.addAll(encodeBytes, doFinal);
        }
        return encodeBytes;
    }

    /**
     * RSA私钥解密
     * @param data
     * @param privateKey
     * @return
     */
    @SneakyThrows
    public static String decodeWithPrivateKey(byte[] data, String privateKey) {
        // base64解码的私钥
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
            .generatePrivate(new PKCS8EncodedKeySpec(decoded));

        // 该密钥能够解密的最大字节长度
        int maxBitLength = priKey.getModulus().bitLength() / 8;

        // RSA解密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.length; i += maxBitLength) {
            byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + maxBitLength));
            sb.append(new String(doFinal, StandardCharsets.UTF_8));
        }
        return sb.toString();
    }

    /**
     * RSA私钥加密
     * @param str 加密字符串
     * @param privateKey 私钥
     */
    @SneakyThrows
    public static byte[] encodeWithPrivateKey(String str, String privateKey) {
        // base64编码的公钥
        byte[] keyBytes = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
            .generatePrivate(new PKCS8EncodedKeySpec(keyBytes));

        //该密钥能够加密的最大字节长度
        int maxBitLength = priKey.getModulus().bitLength() / 8 - 11;

        // RSA加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, priKey);

        byte[] data = str.getBytes(StandardCharsets.UTF_8);
        byte[] encodeBytes = null;
        for (int i = 0; i < data.length; i += maxBitLength) {
            byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + maxBitLength));
            encodeBytes = ArrayUtils.addAll(encodeBytes, doFinal);
        }
        return encodeBytes;
    }

    @SneakyThrows
    public static String decodeWithPublicKey(byte[] data, String publicKey){
        // base64编码的私钥
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey priKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
            .generatePublic(new X509EncodedKeySpec(decoded));
        // 该密钥能够解密的最大字节长度
        int maxBitLength = priKey.getModulus().bitLength() / 8;

        // RSA解密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, priKey);

        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.length; i += maxBitLength) {
            byte[] doFinal = cipher.doFinal(ArrayUtils.subarray(data, i, i + maxBitLength));
            sb.append(new String(doFinal));
        }

        return sb.toString();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值