Java RSA 加解密工具类,直接用

import org.junit.Test;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import java.io.ByteArrayOutputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import java.util.Base64;

/**
 * @author EvanY
 * @since 2021/11/30
 */
public class RSAUtils {

    private static final String RSA = "RSA";
    private static final String RSA_ECB_PKCS1 = "RSA/ECB/PKCS1Padding";
    private static final String SHA1withDSA = "SHA1withDSA";
    private static final String SHA1withRSA = "SHA1withRSA";
    private static final String SHA256withRSA = "SHA256withRSA";
    private static final int BYTE_BIT_LENGTH = 8;
    private static final int PKCS1_PADDING_LENGTH = 11;

    String privateKeyStr = "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAI++rMw5U/7DFooAlSZ9V2l89l44KfjClCFFFxzfLGvhVDTduP9FI8gQyOOvNekipcw1E01XbV6/JhGoKuwHVFfmCFeZWTBBJhMdIb4qh2cNOgfR5yEIxrn0928VnA+RwLg/LEtXuo0pkSs/SQ4Ey62QTGanWP0B5bRWkhxGIHTvAgMBAAECgYBWXxkPYYcR9oFNjMoSJZBnhzm2JYM6wRgm4Y/gvky/ydZCKdQmNpIofcVn4fi/zBzZli6x8015d9vVEjowNrs7YmmiAWK6BeF50Jo9a/6b42DCmYnJd4hLSzmXtlNI6nwvJ72vzCSOqji5Bzrg6Gj5MFHmeHyLZtqUhtu8nmpD8QJBAPx4NJjgLNwdCHZ1avKcmRFAHdnkc2DDYIWyi2SqI7wX/+pk6ExwT/wOC5a/8bl+hJcwLQNTXTVybOENV4sZfmcCQQCRwUFIdY8BLzDm6joLmaXXVTGPwlNc49IsSMcCd3YyAQtB6giIZeUpxYrBQlwrnd17f68ny7BNSSnlgHs0QDA5AkEAl1+DOb3/Z6JItq3EB974r60fuMsOmo/KSZ85kIuqjVZebK0/0sTsUBYjwKkpR6yh1vxdoMbU9fy7Z1xWhuIsNQJBAIdsElbbexnzmbECsRm0EUUnz5utRr0Io28n01e0XOoK1EXSx0jLu4b7FneHS5Hu5Cjpsnj8JHs6XiXxIQekF+kCQQD0u19/Pv2aZ4q2MBAwI2X5sElSfUEr3WNRFgKzxvejjgtxcAgK/UJCqBkcab/bDE5tHL64hljCo+kdZS0829C3";
    String publicKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCPvqzMOVP+wxaKAJUmfVdpfPZeOCn4wpQhRRcc3yxr4VQ03bj/RSPIEMjjrzXpIqXMNRNNV21evyYRqCrsB1RX5ghXmVkwQSYTHSG+KodnDToH0echCMa59PdvFZwPkcC4PyxLV7qNKZErP0kOBMutkExmp1j9AeW0VpIcRiB07wIDAQAB";

    public static String encodeToString(byte[] unEncoded) {
        return new String(encode(unEncoded), StandardCharsets.UTF_8);
    }

    public static byte[] encode(byte[] unEncoded) {
        return Base64.getEncoder().encode(unEncoded);
    }

    public static byte[] decodeFromString(String encoded) {
        return Base64.getDecoder().decode(encoded.getBytes(StandardCharsets.UTF_8));
    }

    /**
     * 根据公钥字符串生成公钥对象
     */
    public static PublicKey getPublicKey(String publicKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] keyByte = decodeFromString(publicKeyStr);
        return KeyFactory.getInstance(RSA).generatePublic(new X509EncodedKeySpec(keyByte));
    }

    /**
     * 根据私钥字符串生成私钥对象
     */
    public static PrivateKey getPrivateKey(String privateKeyStr) throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] keyByte = decodeFromString(privateKeyStr);
        return KeyFactory.getInstance(RSA).generatePrivate(new PKCS8EncodedKeySpec(keyByte));
    }

    /**
     * 用公钥加密字符串
     */
    public static String encrypt(String algorithm, String publicKeyStr, String unencryptedStr) throws Exception {
        return encrypt(algorithm, publicKeyStr, null, StandardCharsets.UTF_8, unencryptedStr);
    }

    public static String encrypt(String algorithm, String publicKeyStr, AlgorithmParameterSpec param, Charset charset, String unencryptedStr) throws Exception {
        PublicKey publicKey = getPublicKey(publicKeyStr);
        Cipher cipher = initCipher(algorithm, Cipher.ENCRYPT_MODE, publicKey, param);
        byte[] bytes = unencryptedStr.getBytes(charset);
        //单次加密最大长度
        int maxEncryptByteLength = ((RSAKey) publicKey).getModulus().bitLength() / BYTE_BIT_LENGTH;
        int excludePaddingMaxLength = maxEncryptByteLength - PKCS1_PADDING_LENGTH;
        int encryptCount = bytes.length / excludePaddingMaxLength;
        //可能有剩余字符串,不足一次加密长度,
        int outSize = maxEncryptByteLength * (encryptCount + 1);
        byte[] encryptedBytes = getBytes(cipher, bytes, excludePaddingMaxLength, outSize);
        return encodeToString(encryptedBytes);
    }

    private static byte[] getBytes(Cipher cipher, byte[] bytes, int step, int outSize) throws Exception {
        ByteArrayOutputStream out = new ByteArrayOutputStream(outSize);
        int offset = 0;
        byte[] outBytes;
        while (offset + step <= bytes.length) {
            outBytes = cipher.doFinal(bytes, offset, step);
            out.write(outBytes);
            offset += step;
        }
        if (offset < bytes.length) {
            outBytes = cipher.doFinal(bytes, offset, bytes.length - offset);
            out.write(outBytes);
        }
        return out.toByteArray();
    }

    /**
     * 用私钥解密字符串
     */
    public static String decrypt(String algorithm, String privateKeyStr, String encryptedStr) throws Exception {
        return decrypt(algorithm, privateKeyStr, null, StandardCharsets.UTF_8, encryptedStr);
    }

    public static String decrypt(String algorithm, String privateKeyStr, AlgorithmParameterSpec param, Charset charset, String encryptedStr) throws Exception {
        PrivateKey privateKey = getPrivateKey(privateKeyStr);
        Cipher cipher = initCipher(algorithm, Cipher.DECRYPT_MODE, privateKey, param);
        byte[] bytes = decodeFromString(encryptedStr);
        //单次解密最大长度
        int maxDecryptByteLength = ((RSAKey) privateKey).getModulus().bitLength() / BYTE_BIT_LENGTH;
        int excludePaddingMaxLength = maxDecryptByteLength - PKCS1_PADDING_LENGTH;
        int decryptCount = bytes.length / maxDecryptByteLength;
        int outSize = decryptCount * excludePaddingMaxLength;
        byte[] decryptedBytes = getBytes(cipher, bytes, maxDecryptByteLength, outSize);
        return new String(decryptedBytes, charset);
    }

    /**
     * 初始化密码
     */
    public static Cipher initCipher(String algorithm, int cipherMode, Key key, AlgorithmParameterSpec param)
            throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, InvalidAlgorithmParameterException {
        Cipher cipher = Cipher.getInstance(algorithm);
        if (param == null) {
            cipher.init(cipherMode, key);
        } else {
            cipher.init(cipherMode, key, param);
        }
        return cipher;
    }

    //签名
    public static String sign(String algorithm, String privateKeyStr, Charset charset, String encryptedStr) throws Exception {
        PrivateKey privateKey = getPrivateKey(privateKeyStr);
        Signature signature = Signature.getInstance(algorithm);
        signature.initSign(privateKey);
        signature.update(encryptedStr.getBytes(charset));
        byte[] signByte = signature.sign();
        return encodeToString(signByte);
    }

    public static boolean verifySign(String algorithm, String publicKeyStr, Charset charset, String encryptedStr, String signStr) throws Exception {
        PublicKey publicKey = getPublicKey(publicKeyStr);
        Signature signature = Signature.getInstance(algorithm);
        signature.initVerify(publicKey);
        signature.update(encryptedStr.getBytes(charset));
        byte[] signByte = decodeFromString(signStr);
        return signature.verify(signByte);
    }

    public static String[] generateKeys(String algorithm, int keySize) throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(algorithm);
        keyPairGenerator.initialize(keySize);
        KeyPair keyPair = keyPairGenerator.genKeyPair();
        byte[] privateKeyByte = keyPair.getPrivate().getEncoded();
        byte[] publicKeyByte = keyPair.getPublic().getEncoded();
        return new String[]{new String(encode(privateKeyByte)), new String(encode(publicKeyByte))};
    }

    @Test
    public void test() throws NoSuchAlgorithmException {
        String[] keys = generateKeys(RSA, 512);
        System.out.println(keys[0]);
        System.out.println(keys[1]);
    }

    @Test
    public void testEncrypt() throws Exception {
        String[] keys = generateKeys(RSA, 1024);
        System.out.println("PrivateKeyStr:" + keys[0]);
        System.out.println("PublicKeyStr:" + keys[1]);

        String unencryptedStr = "{\"serialNo\":\"中国China😀🚀\"}";
        String encryptedStr = encrypt(RSA_ECB_PKCS1, publicKeyStr, unencryptedStr);
        System.out.println("encryptedStr:" + encryptedStr);
        String signStr = sign(SHA256withRSA, privateKeyStr, StandardCharsets.UTF_8, encryptedStr);
        System.out.println("signStr:" + signStr);

        boolean b = verifySign(SHA256withRSA, publicKeyStr, StandardCharsets.UTF_8, encryptedStr, signStr);
        System.out.println(b);
        String decryptedStr = decrypt(RSA_ECB_PKCS1, privateKeyStr, encryptedStr);
        System.out.println(decryptedStr);
    }
}

posted @ 2024-02-24 16:15  yy299  阅读(226)  评论(0)    收藏  举报