常用加解密

加解密

AES

package encrypt;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.Charset;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * 对称加密<br/>
 * 加密后,使用Base64编码<br/>
 * @author
 */
public class AesUtil {
    private static final String ALGORITHM_MODE = "AES";
    private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
    /**
     * 128, 192 or 256
     */
    private static final int SECRET_KEY_SIZE = 128;
    private static final int IV_KEY_SIZE = 16;

    private AesUtil() {
    }

    /**
     * 加密
     *
     * @param plaintext 明文
     * @param strKey    字符串密钥
     * @return base64编号后的密文
     */
    public static String encrypt(String plaintext, String strKey) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, getKey(strKey), getIv(strKey));
            byte[] bytes = plaintext.getBytes(Charset.defaultCharset());
            return Base64.encodeBase64String(cipher.doFinal(bytes));
        } catch (Exception e) {
            throw new RuntimeException("Encryption failed. Cause: ", e);
        }
    }

    /**
     * 解密
     *
     * @param cipherText base64编号后的密文
     * @param strKey     字符串密钥
     * @return
     */
    public static String decrypt(String cipherText, String strKey) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, getKey(strKey), getIv(strKey));
            byte[] bytes = Base64.decodeBase64(cipherText);
            return StringUtils.newStringUtf8(cipher.doFinal(bytes));
        } catch (Exception e) {
            throw new RuntimeException("Decryption failed. Cause: ", e);
        }
    }

    /**
     * 获取iv
     *
     * @param ivKey
     * @return
     */
    private static IvParameterSpec getIv(String ivKey) {
        if (ivKey == null) {
            ivKey = "";
        }
        StringBuffer stringBuffer = new StringBuffer(IV_KEY_SIZE);
        stringBuffer.append(ivKey);
        while (stringBuffer.length() < IV_KEY_SIZE) {
            stringBuffer.append("0");
        }
        if (stringBuffer.length() > IV_KEY_SIZE) {
            stringBuffer.setLength(IV_KEY_SIZE);
        }
        return new IvParameterSpec(StringUtils.getBytesUtf8(stringBuffer.toString()));
    }

    /**
     * 获取安全密钥
     *
     * @param strKey
     * @return
     */
    private static Key getKey(String strKey) {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM_MODE);
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(StringUtils.getBytesUtf8(strKey));
            keyGenerator.init(SECRET_KEY_SIZE, secureRandom);
            return keyGenerator.generateKey();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Failed to generate key. Cause: " + e);
        }
    }

    public static void main(String[] args) throws Exception {
        String plaintext = "这是一条待加密的字符串";
        String strKey = "qazc===+++,";
        String encrypt = encrypt(plaintext, strKey);
        String decrypt = decrypt(encrypt, strKey);

        System.out.println("原文:" + plaintext + "\n" + "加密后:" + encrypt + "\n" + "解密后:" + decrypt);
    }

}

DES

package encrypt;


import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.StringUtils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import java.nio.charset.Charset;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * 对称加密 <br/>
 * 加密后,使用Base64编码<br/>
 * @author
 */

public class DesUtil {

    private static final String ALGORITHM_MODE = "DES";
    /**
     * 算法/模式/是否需要填充
     */
    private static final String TRANSFORMATION = "DES/CBC/PKCS5Padding";
    private static final int SECRET_KEY_SIZE = 56;
    private static final int IV_KEY_SIZE = 8;

    private DesUtil() {
    }

    /**
     * 加密
     *
     * @param plaintext 明文
     * @param strKey    字符串密钥
     * @return base64编号后的密文
     */
    public static String encrypt(String plaintext, String strKey) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.ENCRYPT_MODE, getKey(strKey), getIv(strKey));
            byte[] bytes = plaintext.getBytes(Charset.defaultCharset());
            return Base64.encodeBase64String(cipher.doFinal(bytes));
        } catch (Exception e) {
            throw new RuntimeException("Encryption failed. Cause: ", e);
        }

    }

    /**
     * 解密
     *
     * @param cipherText base64编号后的密文
     * @param strKey     字符串密钥
     * @return
     */
    public static String decrypt(String cipherText, String strKey) {
        try {
            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, getKey(strKey), getIv(strKey));
            byte[] bytes = Base64.decodeBase64(cipherText.getBytes(Charset.defaultCharset()));
            return StringUtils.newStringUtf8(cipher.doFinal(bytes));
        } catch (Exception e) {
            throw new RuntimeException("Decryption failed. Cause: ", e);
        }
    }

    /**
     * 获取iv
     * 除ECB模式以外其他都需要IvParameterSpec,执行加密时指定IV值,并在执行解密时使用相同的值<br/>
     * 加解密模式:ECB(电码本模式),CBC(加密块链模式),OFB(输出反馈模式),CFB(加密反馈模式)
     *
     * @param ivKey 原始密钥
     * @return
     */
    private static IvParameterSpec getIv(String ivKey) {
        if (ivKey == null) {
            ivKey = "";
        }
        StringBuffer stringBuffer = new StringBuffer(IV_KEY_SIZE);
        stringBuffer.append(ivKey);
        while (stringBuffer.length() < IV_KEY_SIZE) {
            stringBuffer.append("0");
        }
        if (stringBuffer.length() > IV_KEY_SIZE) {
            stringBuffer.setLength(IV_KEY_SIZE);
        }

        return new IvParameterSpec(StringUtils.getBytesUtf8(stringBuffer.toString()));
    }

    /**
     * 获取安全密钥
     *
     * @param strKey
     * @return
     */
    private static Key getKey(String strKey) {
        try {
            KeyGenerator keyGenerator = KeyGenerator.getInstance(ALGORITHM_MODE);
            // 解决Windows和Linux生产的随机数不一致
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            secureRandom.setSeed(StringUtils.getBytesUtf8(strKey));
            keyGenerator.init(SECRET_KEY_SIZE, secureRandom);
            return keyGenerator.generateKey();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Failed to generate key. Cause: " + e);
        }
    }

    public static void main(String[] args) throws Exception {
        String plaintext = "qwert1234";
        String strKey = "okmpl,";
        String encrypt = encrypt(plaintext, strKey);
        String decrypt = decrypt(encrypt, strKey);

        System.out.println("原文:" + plaintext + "\n" + "加密后:" + encrypt + "\n" + "解密后:" + decrypt);
    }

}

RSA

package encrypt;

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

import javax.crypto.Cipher;
import java.io.*;
import java.security.*;
import java.security.interfaces.RSAKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.UUID;

/**
 * 非对称加密
 * @author
 */
public class RsaUtil {

    private static final String ALGORITHM = "RSA";
    /**
     * SHA256withRSA,MD5withRSA
     */
    private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
    /**
     * 密钥位数(模值的位长度)
     */
    private static final int KEY_SIZE = 1024;
    private static final String FILENAME_PUBLIC = "id_rsa.pub";
    private static final String FILENAME_PRIVATE = "id_rsa";


    private RsaUtil() {
    }


    /**
     * 生成密钥对
     *
     * @param filePath 生成的文件路径
     */
    public static void generateKeyPair(String filePath) {
        KeyPair keyPair = initKeyPair();
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();

        String publicKeyString = encodeBase64String(publicKey.getEncoded());
        String privateKeyString = encodeBase64String(privateKey.getEncoded());

        storeKeyByFile(publicKeyString, filePath + FILENAME_PUBLIC);
        storeKeyByFile(privateKeyString, filePath + FILENAME_PRIVATE);
    }

    /**
     * 初始化键值对
     *
     * @return
     */
    private static KeyPair initKeyPair() {
        try {
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG", "SUN");
            secureRandom.setSeed(StringUtils.getBytesUtf8(UUID.randomUUID().toString().replaceAll("-", "")));

            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
            keyPairGenerator.initialize(KEY_SIZE, secureRandom);
            return keyPairGenerator.generateKeyPair();
        } catch (Exception e) {
            throw new RuntimeException("Failed to initialize KeyPair. Cause: ", e);
        }
    }

    /**
     * 生成密钥对文件
     *
     * @param keyString
     * @param pathName
     */
    private static void storeKeyByFile(String keyString, String pathName) {
        try {
            BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(new File(pathName)));
            bufferedWriter.write(keyString);
            bufferedWriter.flush();
            bufferedWriter.close();
        } catch (IOException e) {
            throw new RuntimeException("File build failed. Cause: ", e);
        }
    }

    /**
     * 从文件中读取公钥/私钥
     *
     * @param pathName 文件的绝对地址
     * @return
     */
    public static String readKeyFromFile(String pathName) {
        try {
            BufferedReader bufferedReader = new BufferedReader(new FileReader(new File(pathName)));
            String readLine = null;
            StringBuffer result = new StringBuffer();
            while ((readLine = bufferedReader.readLine()) != null) {
                result.append(readLine);
            }
            return result.toString();
        } catch (IOException e) {
            throw new RuntimeException("File read failed. Cause: ", e);
        }
    }

    /**
     * 从字符串获取公钥
     *
     * @param publicKeyString
     * @return
     */
    public static RSAPublicKey getPublicKeyFromString(String publicKeyString) {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(decodeBase64(publicKeyString));
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
            return (RSAPublicKey) keyFactory.generatePublic(x509EncodedKeySpec);
        } catch (Exception e) {
            throw new RuntimeException("Failed to get RSAPublicKey. Cause: ", e);
        }
    }

    /**
     * 从字符串获取私钥
     *
     * @param privateString
     * @return
     */
    public static RSAPrivateKey getPrivateKeyFromString(String privateString) {
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(decodeBase64(privateString));
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
            return (RSAPrivateKey) keyFactory.generatePrivate(pkcs8EncodedKeySpec);
        } catch (Exception e) {
            throw new RuntimeException("Failed to get RSAPrivateKey. Cause: ", e);
        }
    }

    /**
     * 使用Key(公钥/私钥)加密<br/>
     * 注:加密数据长度最多为117byte(128byte - 11byte padding)
     *
     * @param plaintext 明文
     * @param key       公钥/私钥
     * @return base64编码后的密文
     */
    public static String encryptByKey(String plaintext, Key key) {
        if (key == null) {
            throw new RuntimeException("Key is empty");
        }
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] bytes = cipher.doFinal(StringUtils.getBytesUtf8(plaintext));
            return encodeBase64String(bytes);
        } catch (Exception e) {
            throw new RuntimeException("Failed to encrypt. Cause: ", e);
        }
    }

    /**
     * 使用Key(公钥/私钥)解密
     *
     * @param cipherText base64编码后的密文
     * @param key        公钥/私钥
     * @return
     */
    public static String decryptByKey(String cipherText, Key key) {
        if (key == null) {
            throw new RuntimeException("Key is empty");
        }
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] bytes = cipher.doFinal(decodeBase64(cipherText));
            return StringUtils.newStringUtf8(bytes);
        } catch (Exception e) {
            throw new RuntimeException("Failed to decryption. Cause: ", e);
        }
    }


    /**
     * 使用Key(公钥/私钥)加密<br/>
     * 不限制加密数据长度
     *
     * @param plaintext 明文
     * @param key       公钥/私钥
     * @return 十六进制字符串密文
     */
    public static String encryptByKey2(String plaintext, Key key) {
        if (key == null) {
            throw new RuntimeException("Key is empty");
        }
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // 密钥能加密的最大字节长度
            int splitLength = ((RSAKey) key).getModulus().bitLength() / 8 - 11;
            byte[][] arrays = splitBytes(StringUtils.getBytesUtf8(plaintext), splitLength);
            StringBuffer result = new StringBuffer();
            for (byte[] array : arrays) {
                result.append(bytesToHexString(cipher.doFinal(array)));
            }
            return result.toString();
        } catch (Exception e) {
            throw new RuntimeException("Failed to encrypt. Cause: ", e);
        }
    }


    /**
     * 使用Key(公钥/私钥)加密<br/>
     * 不限制加密数据长度
     *
     * @param cipherText 十六进制字符串密文
     * @param key        公钥/私钥
     * @return
     */
    public static String decryptByKey2(String cipherText, Key key) {
        if (key == null) {
            throw new RuntimeException("Key is empty");
        }
        try {
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, key);

            // 能够解密的最大字节长度
            int splitLength = ((RSAKey) key).getModulus().bitLength() / 8;
            byte[][] arrays = splitBytes(hexStringToBytes(cipherText), splitLength);
            StringBuffer result = new StringBuffer();
            for (byte[] array : arrays) {
                result.append(StringUtils.newStringUtf8(cipher.doFinal(array)));
            }
            return result.toString();
        } catch (Exception e) {
            throw new RuntimeException("Failed to decryption. Cause: ", e);
        }
    }

    /**
     * 按照指定字节长度,将字节数组分组
     *
     * @param bytes
     * @param splitLength
     * @return
     */
    private static byte[][] splitBytes(byte[] bytes, int splitLength) {
        int bytesLength = bytes.length;
        // 余数
        int remainder = bytesLength % splitLength;
        // 商数(余数不为0时,商数加一)
        int quotient = remainder != 0 ? bytesLength / splitLength + 1 : bytesLength / splitLength;

        byte[][] result = new byte[quotient][];
        byte[] array = null;
        for (int i = 0; i < quotient; i++) {
            // 如果为最后一组(quotient-1),并且余数不为0,则将最后一组的长度设置为remainder的长度
            if (i == quotient - 1 && remainder != 0) {
                array = new byte[remainder];
                System.arraycopy(bytes, i * splitLength, array, 0, remainder);
            } else {
                array = new byte[splitLength];
                System.arraycopy(bytes, i * splitLength, array, 0, splitLength);
            }
            result[i] = array;
        }
        return result;
    }


    private static String encodeBase64String(byte[] bytes) {
        return Base64.encodeBase64String(bytes);
    }

    private static byte[] decodeBase64(String data) {
        return Base64.decodeBase64(data);
    }

    /**
     * 将字节数组转换成16进制字符串
     *
     * @param bytes
     * @return
     */
    private static String bytesToHexString(byte[] bytes) {
        return Hex.encodeHexString(bytes);
    }

    /**
     * 将16进制字符串转换为字节数组
     *
     * @param data
     * @return
     */
    private static byte[] hexStringToBytes(String data) {
        try {
            return Hex.decodeHex(data);
        } catch (DecoderException e) {
            throw new RuntimeException("Conversion failure. Cause: ", e);
        }
    }


    /**
     * 私钥加签
     *
     * @param content    报文
     * @param privateKey 私钥字符串
     * @return 签名值
     */
    public static String signByPrivateKey(String content, String privateKey) {
        RSAPrivateKey rsaPrivateKey = getPrivateKeyFromString(privateKey);
        try {
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initSign(rsaPrivateKey);
            signature.update(StringUtils.getBytesUtf8(content));
            return encodeBase64String(signature.sign());
        } catch (Exception e) {
            throw new RuntimeException("Failed to add signature. Cause: ", e);
        }
    }

    /**
     * 公钥验签
     *
     * @param content   报文
     * @param publicKey 公钥
     * @param sign      签名值
     * @return 验签是否通过
     */
    public static boolean verifySignByPublicKey(String content, String publicKey, String sign) {
        RSAPublicKey rsaPublicKey = getPublicKeyFromString(publicKey);
        try {
            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
            signature.initVerify(rsaPublicKey);
            signature.update(StringUtils.getBytesUtf8(content));
            return signature.verify(decodeBase64(sign));
        } catch (Exception e) {
            throw new RuntimeException("Signature verification failed. Cause: ", e);
        }
    }

    public static void main(String[] args) {
        String filepath = "E:/";

        String publicKeyString = readKeyFromFile(filepath + FILENAME_PUBLIC);
        String privateKeyString = readKeyFromFile(filepath + FILENAME_PRIVATE);

        RSAPublicKey rsaPublicKey = getPublicKeyFromString(publicKeyString);
        RSAPrivateKey rsaPrivateKey = getPrivateKeyFromString(privateKeyString);

        String plainText = "qwert12345";
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < 1; i++) {
            stringBuffer.append("123456qwertyu");
        }
        plainText = stringBuffer.toString();
        String cipherText = encryptByKey(plainText, rsaPrivateKey);
        String decryptText = decryptByKey(cipherText, rsaPublicKey);
        System.out.println("------- 私钥加密,公钥解密 --------");
        System.out.println("plainText: " + plainText + "\n" + "cipherText: " + cipherText + "\n" + "decryptText: " + decryptText);

        cipherText = encryptByKey2(plainText, rsaPublicKey);
        decryptText = decryptByKey2(cipherText, rsaPrivateKey);
        System.out.println("-------  公钥加密,私钥解密 -------");
        System.out.println("plainText: " + plainText + "\n" + "cipherText: " + cipherText + "\n" + "decryptText: " + decryptText);

        System.out.println("-------  私钥加密,公钥解密 -------");
        String signStr = signByPrivateKey(plainText, privateKeyString);
        boolean success = verifySignByPublicKey(plainText, publicKeyString, signStr);
        System.out.println("签名串: " + signStr + "\n" + "验签: " + success);

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值