java非对称加解密

简介

非对称加密:加密和解密使用不同的秘钥的加解密方法。一般的,用公钥做加密,私钥做解密使用

常用的加解密有:RSA、ECC、DSA,在java中使用最多的是RSA

工具类

/**
 * 非对称加解密工具类(RSA)
 *
 * RSA加密(一次)有最大字节数组限制 177、解密的最大字符限制128
 *
 *
 */
public class AsymmetricEncryptDecryptionUtil {

    public static final String UTF8= StandardCharsets.UTF_8.name();
    public static final String ALGORITHM = "RSA";
    public static final int MAX_ENC_LENGTH = 117;
    public static final int MAX_DEN_LENGTH = 128;

    /**
     * 创建公钥和私钥对的16进制字符串
     *
     * @throws NoSuchAlgorithmException 算法异常
     * @throws IOException io异常
     */
    public static void createKeyPair() throws NoSuchAlgorithmException, IOException {
        KeyPairGenerator pairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        pairGenerator.initialize(1024);

        KeyPair keyPair = pairGenerator.genKeyPair();
        // 公钥
        PublicKey publicKey = keyPair.getPublic();
        // 私钥
        PrivateKey privateKey = keyPair.getPrivate();
        // 公钥秘钥字节数组
        byte[] publicKeyPairEncoded = publicKey.getEncoded();
        // 私钥秘钥字节数组
        byte[] privateKeyEncoded = privateKey.getEncoded();
        String pubHexStr = Hex.encodeHexString(publicKeyPairEncoded);
        String priHexStr = Hex.encodeHexString(privateKeyEncoded);
        System.out.println("公钥是:" + pubHexStr);
        System.out.println("私钥是:" + priHexStr);
    }

    private static PublicKey getPublicKey() throws Exception {
        String pubCfFile = AsymmetricEncryptDecryptionUtil.class.getClassLoader().getResource("rsa.pub").getPath();
        String pubKeyHexStr = FileUtils.readFileToString(new File(pubCfFile), UTF8);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Hex.decodeHex(pubKeyHexStr));
        return keyFactory.generatePublic(x509EncodedKeySpec);
    }

    private static PrivateKey getPrivateKey() throws Exception {
        String priCfFile = AsymmetricEncryptDecryptionUtil.class.getClassLoader().getResource("rsa.pri").getPath();
        String priKeyHexStr = FileUtils.readFileToString(new File(priCfFile), UTF8);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Hex.decodeHex(priKeyHexStr));
        return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
    }


    public static String encodeStr(String originalStr,Key key) throws Exception {
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE,key);
        byte[] bytes = doCodec(cipher, originalStr.getBytes(UTF8), MAX_ENC_LENGTH);
        return Hex.encodeHexString(bytes);
    }

    public static String deCodeStr(String hexStr,Key key) throws Exception {
        byte[] bytes = Hex.decodeHex(hexStr);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE,key);
        byte[] originalBytes = doCodec(cipher,bytes,MAX_DEN_LENGTH);
        return new String(originalBytes,UTF8);
    }

    /**
     * 由于RSA加密、解密都有最大字节数组长度限制(加密是177长度,解密是128长度)
     *
     * 所以需要循环处理
     *
     * @param cipher cipher
     * @param bytes 待加解密的字节数组
     * @param maxLength 处理的最大长度
     * @return 加解密的字节数组
     * @throws BadPaddingException BadPaddingException
     * @throws IllegalBlockSizeException IllegalBlockSizeException
     */
    private static byte[] doCodec(Cipher cipher,byte[] bytes,int maxLength) throws BadPaddingException, IllegalBlockSizeException {
        int length = bytes.length;
        int offset = 0;
        byte[] cache;
        int i = 0;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((length - offset) > 0) {
            if(length - offset > maxLength) {
                cache = cipher.doFinal(bytes,offset,maxLength);
            } else {
                cache = cipher.doFinal(bytes,offset,length - offset);
            }
            i++;
            offset = i * maxLength;
            bos.write(cache,0,cache.length);
        }
        return bos.toByteArray();
    }



    public static void main(String[] args) throws Exception {
        String str = "法律";
        PublicKey publicKey = getPublicKey();
        String s = encodeStr(str, publicKey);
        System.out.println("RSA encode result:" + s);

        PrivateKey privateKey = getPrivateKey();
        String s1 = deCodeStr(s,privateKey);
        System.out.println("RSA decode result:" + s1);

    }
}

注意:RSA加解密有限制,一次加密的最大字节数组不能超过177长度,解密的最大数组长度不能超过128个字节长度

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值