记RSA非对称加密RSAUtil包分享

本类结合了网上各种资源整合而成,可以生产RSA密钥对,解析公钥私钥,公钥加解密,私钥加解密。

RSAUtil.java

import java.security.InvalidKeyException;
import java.security.InvalidParameterException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.UUID;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;


public class RSAUtil {

    public static final String ALGORITHM = "RSA";
    
    public static final int KEY_SIZE = 1024;

    public static Base64.Decoder decoder = Base64.getDecoder();
    public static Base64.Encoder encoder = Base64.getEncoder();

    /**
     * 生成密钥对
     */
    public static HashMap<String, String> generateKeyPair() throws Exception {

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        KeyPair keyPair;
        
        try {
            keyPairGenerator.initialize(KEY_SIZE,
                    new SecureRandom(UUID.randomUUID().toString().replaceAll("-", "").getBytes()));
            keyPair = keyPairGenerator.generateKeyPair();
        }
        catch (InvalidParameterException e) {
            
           throw e;
        }
        catch (NullPointerException e) {
            
           throw e;
        }
        
        RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
        RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
        
        HashMap<String, String> map = new HashMap<String, String>();
        map.put("private", encoder.encodeToString(rsaPrivateKey.getEncoded()));
        map.put("public", encoder.encodeToString(rsaPublicKey.getEncoded()));
        return map;
    }

    public static PublicKey getPublicKeyFromString(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
        
        // 取得公钥  
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(decoder.decode(key));  
  
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);  
          
        PublicKey publicKey = keyFactory.generatePublic(x509KeySpec);
        
        return publicKey;
    }
    
    public static PrivateKey getPrivateKeyFromString(String key) throws NoSuchAlgorithmException, InvalidKeySpecException {
        
        // 取得私钥 
        PKCS8EncodedKeySpec x509KeySpec = new PKCS8EncodedKeySpec(decoder.decode(key));  
  
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);  
          
        PrivateKey privateKey = keyFactory.generatePrivate(x509KeySpec);
        
        return privateKey;
    }

    /**
     * RSA公钥加密
     * 
     * @param content
     *            等待加密的数据
     * @param publicKey
     *            RSA 公钥 if null then getPublicKey()
     * @return 加密后的密文(16进制的字符串)
     */
    public static String encryptByPublic(byte[] content, PublicKey publicKey) {

        if (publicKey == null) {
        }
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            // 该密钥能够加密的最大字节长度
            int splitLength = ((RSAPublicKey) publicKey).getModulus().bitLength() / 8 - 11;
            byte[][] arrays = splitBytes(content, splitLength);
            StringBuffer stringBuffer = new StringBuffer();
            for (byte[] array : arrays) {
                stringBuffer.append(bytesToHexString(cipher.doFinal(array)));
            }
            return stringBuffer.toString();
        }
        catch (NoSuchAlgorithmException e) {
        }
        catch (NoSuchPaddingException e) {
        }
        catch (InvalidKeyException e) {
        }
        catch (BadPaddingException e) {
        }
        catch (IllegalBlockSizeException e) {
        }
        return null;
    }

    /**
     * RSA私钥加密
     * 
     * @param content
     *            等待加密的数据
     * @param privateKey
     *            RSA 私钥 if null then getPrivateKey()
     * @return 加密后的密文(16进制的字符串)
     */
    public static String encryptByPrivate(byte[] content, PrivateKey privateKey) {

        if (privateKey == null) {
            //privateKey = getPrivateKey();
        }
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            // 该密钥能够加密的最大字节长度
            int splitLength = ((RSAPrivateKey) privateKey).getModulus().bitLength() / 8 - 11;
            byte[][] arrays = splitBytes(content, splitLength);
            StringBuffer stringBuffer = new StringBuffer();
            for (byte[] array : arrays) {
                stringBuffer.append(bytesToHexString(cipher.doFinal(array)));
            }
            return stringBuffer.toString();
        }
        catch (NoSuchAlgorithmException e) {
        }
        catch (NoSuchPaddingException e) {
        }
        catch (InvalidKeyException e) {
        }
        catch (BadPaddingException e) {
        }
        catch (IllegalBlockSizeException e) {
        }
        return null;
    }

    /**
     * RSA私钥解密
     * 
     * @param content
     *            等待解密的数据
     * @param privateKey
     *            RSA 私钥 if null then getPrivateKey()
     * @return 解密后的明文
     */
    public static String decryptByPrivate(String content, PrivateKey privateKey) {

        if (privateKey == null) {
            //privateKey = getPrivateKey();
        }
        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            // 该密钥能够加密的最大字节长度
            int splitLength = ((RSAPrivateKey) privateKey).getModulus().bitLength() / 8;
            byte[] contentBytes = hexStringToBytes(content);
            byte[][] arrays = splitBytes(contentBytes, splitLength);
            StringBuffer stringBuffer = new StringBuffer();
            for (byte[] array : arrays) {
                stringBuffer.append(new String(cipher.doFinal(array)));
            }
            return stringBuffer.toString();
        }
        catch (NoSuchAlgorithmException e) {
        }
        catch (NoSuchPaddingException e) {
        }
        catch (InvalidKeyException e) {
        }
        catch (BadPaddingException e) {
        }
        catch (IllegalBlockSizeException e) {
        }
        return null;
    }

    /**
     * RSA公钥解密
     * 
     * @param content
     *            等待解密的数据
     * @param publicKey
     *            RSA 公钥 if null then getPublicKey()
     * @return 解密后的明文
     */
    public static String decryptByPublic(String content, PublicKey publicKey) {

        try {
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            // 该密钥能够加密的最大字节长度
            int splitLength = ((RSAPublicKey) publicKey).getModulus().bitLength() / 8;
            byte[] contentBytes = hexStringToBytes(content);
            byte[][] arrays = splitBytes(contentBytes, splitLength);
            StringBuffer stringBuffer = new StringBuffer();
            for (byte[] array : arrays) {
                stringBuffer.append(new String(cipher.doFinal(array)));
            }
            return stringBuffer.toString();
        }
        catch (NoSuchAlgorithmException e) {
           e.printStackTrace();
        }
        catch (NoSuchPaddingException e) {
           e.printStackTrace();
        }
        catch (InvalidKeyException e) {
           e.printStackTrace();
        }
        catch (BadPaddingException e) {
           e.printStackTrace();
        }
        catch (IllegalBlockSizeException e) {
           e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据限定的每组字节长度,将字节数组分组
     * 
     * @param bytes
     *            等待分组的字节组
     * @param splitLength
     *            每组长度
     * @return 分组后的字节组
     */
    public static byte[][] splitBytes(byte[] bytes, int splitLength) {

        // bytes与splitLength的余数
        int remainder = bytes.length % splitLength;
        // 数据拆分后的组数,余数不为0时加1
        int quotient = remainder != 0 ? bytes.length / splitLength + 1 : bytes.length / splitLength;
        byte[][] arrays = 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);
            }
            arrays[i] = array;
        }
        return arrays;
    }

    /**
     * 将字节数组转换成16进制字符串
     * 
     * @param bytes
     *            即将转换的数据
     * @return 16进制字符串
     */
    public static String bytesToHexString(byte[] bytes) {

        StringBuffer sb = new StringBuffer(bytes.length);
        String temp = null;
        for (int i = 0; i < bytes.length; i++) {
            temp = Integer.toHexString(0xFF & bytes[i]);
            if (temp.length() < 2) {
                sb.append(0);
            }
            sb.append(temp);
        }
        return sb.toString();
    }

    /**
     * 将16进制字符串转换成字节数组
     * 
     * @param hex
     *            16进制字符串
     * @return byte[]
     */
    public static byte[] hexStringToBytes(String hex) {

        int len = (hex.length() / 2);
        hex = hex.toUpperCase();
        byte[] result = new byte[len];
        char[] chars = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (toByte(chars[pos]) << 4 | toByte(chars[pos + 1]));
        }
        return result;
    }

    /**
     * 将char转换为byte
     * 
     * @param c
     *            char
     * @return byte
     */
    private static byte toByte(char c) {

        return (byte) "0123456789ABCDEF".indexOf(c);
    }
}

测试类:

import java.util.HashMap;

public class TestRSA {

    /**
     * @param args
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
      
        HashMap<String, String> map = RSAUtil.generateKeyPair();
        
        String data = "dhkldfpaoidfpaidfpxxxx";
        
        String result = RSAUtil.encryptByPrivate(data.getBytes(), RSAUtil.getPrivateKeyFromString(map.get("private")));
        
        System.out.println(result);
        
        String reResult = RSAUtil.decryptByPublic(result, RSAUtil.getPublicKeyFromString(map.get("public")));
        
        System.out.println(reResult);

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值