Die RSA-Toolklasse umfasst optionale Parameter wie den Füllmodus OAEP

<Abhängigkeit>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.11</version>
</Abhängigkeit>

import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSAUtil {

    public static void main(String[] args) throws Exception {
        String[] KeyArray = generateRSAKeyPair();
        String data="你好";
        String encryptStr = encryptByPublicKeyStr(KeyArray[0], data);
        //公
        System.out.println(KeyArray[0]);
        //私
        System.out.println(KeyArray[1]);
        //加密后
        System.out.println(encryptStr);
        String decryptStr = decryptByPrivateKeyStr(KeyArray[1], encryptStr);
        //解密后
        System.out.println(decryptStr);
    }
    /**
     * RSA 算法
     **/
    private static final String ALGORITHM_RSA = "RSA";

    /**
     * 签名算法
     **/
    private static final String ALGORITHM_SIGNATURE = "SHA1WithRSA";

    /**
     * Cipher类提供了加密和解密的功能
     * <p>
     * Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING");
     * RSA是算法,ECB是分块模式,PKCS1Padding是填充模式,整个构成一个完整的加密算法
     *
     * <pre>
     * 有以下的参数:
     * * AES/CBC/NoPadding (128)
     * * AES/CBC/PKCS5Padding (128)
     * * AES/ECB/NoPadding (128)
     * * AES/ECB/PKCS5Padding (128)
     * * DES/CBC/NoPadding (56)
     * * DES/CBC/PKCS5Padding (56)
     * * DES/ECB/NoPadding (56)
     * * DES/ECB/PKCS5Padding (56)
     * * DESede/CBC/NoPadding (168)
     * * DESede/CBC/PKCS5Padding (168)
     * * DESede/ECB/NoPadding (168)
     * * DESede/ECB/PKCS5Padding (168)
     * * RSA/ECB/PKCS1Padding (1024, 2048)
     * * RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
     * * RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)
     * </pre>
     */
    private static final String PADDING = "RSA/ECB/OAEPWithSHA-256AndMGF1Padding";

    /**
     * 生成非对称密钥对,默认使用RSA
     *
     * @return
     * @throws Exception
     */
    public static String[] generateRSAKeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM_RSA);
        keyPairGenerator.initialize(3072);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        String publicKeyStr = Base64.encodeBase64String(publicKey.getEncoded());
        String privateKeyStr = Base64.encodeBase64String(privateKey.getEncoded());
        return new String[]{publicKeyStr, privateKeyStr};
    }



    /**
     * 使用数据接收方的公钥加密
     *
     * @param publicKeyStr BASE64编码格式的公钥
     * @param data         待加密数据
     * @return
     * @throws Exception
     */
    public static String encryptByPublicKeyStr(String publicKeyStr, String data) throws Exception {
        PublicKey publicKey = getPublicKeyFromString(publicKeyStr);
        byte[] bytes = doCipher(Cipher.ENCRYPT_MODE, publicKey, data.getBytes());
        return Base64.encodeBase64String(bytes);
    }

    /**
     * 数据接收方使用自己的私钥解密
     *
     * @param privateKeyStr BASE64编码格式的私钥
     * @param encryptedData 待解密数据
     * @return
     * @throws Exception
     */
    public static String decryptByPrivateKeyStr(String privateKeyStr, String encryptedData) throws Exception {
        PrivateKey privateKey = getPrivateKeyFromString(privateKeyStr);
        byte[] bytes = doCipher(Cipher.DECRYPT_MODE, privateKey, Base64.decodeBase64(encryptedData));
        return new String(bytes);
    }

    /**
     * 使用数据接收方的公钥加密
     *
     * @param publicKeyPath 公钥文件路径
     * @param data          待加密数据
     * @return
     * @throws Exception
     */
    public static String encryptByPublicKeyFile(String publicKeyPath, String data) throws Exception {
        PublicKey publicKey = getPublicKeyFromFile(publicKeyPath);
        byte[] bytes = doCipher(Cipher.ENCRYPT_MODE, publicKey, data.getBytes());
        return Base64.encodeBase64String(bytes);
    }

    /**
     * 数据接收方使用自己的私钥解密
     *
     * @param privateKeyPath 私钥文件路径
     * @param encryptedData  待解密数据
     * @return
     * @throws Exception
     */
    public static String decryptByPrivateKeyFile(String privateKeyPath, String encryptedData) throws Exception {
        PrivateKey privateKey = getPrivateKeyFromFile(privateKeyPath);
        byte[] bytes = doCipher(Cipher.DECRYPT_MODE, privateKey, Base64.decodeBase64(encryptedData));
        return new String(bytes);
    }

    /**
     * 数据发送方使用自己的私钥对数据签名
     *
     * @param privateKeyStr BASE64编码格式的私钥
     * @param data          待签名数据
     * @return 签名数据,一般进行BASE64编码后发送给对方
     * @throws Exception
     */
    public static String signByPrivateKeyStr(String privateKeyStr, String data) throws Exception {
        PrivateKey privateKey = getPrivateKeyFromString(privateKeyStr);
        byte[] bytes = sign(privateKey, data.getBytes());
        return Base64.encodeBase64String(bytes);
    }

    /**
     * 数据接收方使用对方公钥验证签名
     *
     * @param publicKeyStr BASE64编码格式的私钥
     * @param data         待验签数据
     * @param sign         签名数据,进行BASE64解码后验证签名
     * @return
     * @throws Exception
     */
    public static boolean verifyByPublicKeyStr(String publicKeyStr, String data, String sign) throws Exception {
        PublicKey publicKey = getPublicKeyFromString(publicKeyStr);
        return verify(publicKey, data.getBytes(), Base64.decodeBase64(sign));
    }

    private static PublicKey getPublicKeyFromString(String publicKeyStr) throws Exception {
        byte[] encodedKey = Base64.decodeBase64(publicKeyStr);
        return generatePublic(encodedKey);
    }

    private static PublicKey getPublicKeyFromFile(String publicKeyPath) throws Exception {
        byte[] encodedKey = Files.readAllBytes(Paths.get(publicKeyPath));
        return generatePublic(encodedKey);
    }

    private static PublicKey generatePublic(byte[] encodedKey) throws Exception {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encodedKey);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
        PublicKey publicKey = keyFactory.generatePublic(keySpec);
        return publicKey;
    }

    private static PrivateKey getPrivateKeyFromString(String privateKeyStr) throws Exception {
        byte[] encodedKey = Base64.decodeBase64(privateKeyStr);
        return generatePrivate(encodedKey);
    }

    private static PrivateKey getPrivateKeyFromFile(String privateKeyPath) throws Exception {
        byte[] encodedKey = Files.readAllBytes(Paths.get(privateKeyPath));
        return generatePrivate(encodedKey);
    }

    private static PrivateKey generatePrivate(byte[] encodedKey) throws Exception {
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encodedKey);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
        return privateKey;
    }

    private static byte[] doCipher(int mode, Key key, byte[] bytes) throws Exception {
        Cipher cipher = Cipher.getInstance(PADDING);
        cipher.init(mode, key);
        return cipher.doFinal(bytes);
    }

    private static byte[] sign(PrivateKey privateKey, byte[] data) throws Exception {
        Signature signature = Signature.getInstance(ALGORITHM_SIGNATURE);
        signature.initSign(privateKey);
        signature.update(data);
        return signature.sign();
    }

    private static boolean verify(PublicKey publicKey, byte[] data, byte[] sign) throws Exception {
        Signature signature = Signature.getInstance(ALGORITHM_SIGNATURE);
        signature.initVerify(publicKey);
        signature.update(data);
        return signature.verify(sign);
    }
}

Guess you like

Origin blog.csdn.net/qq_35387940/article/details/134646349