非对称加密算法——RSA

  RSA是唯一被广泛接受并实现的通用算法。

java rsa 问题 rsa算法java实现_密钥对

RSA有两种模式公钥加密私钥解密和私钥加密公钥解密两种模式,其序列图如下:

java rsa 问题 rsa算法java实现_java_02

  在RSA算法中公钥的长度远远小于私钥的长度。以下是其java实现:

============================================================================RSA加解密工具类:

import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;

public class SecurityRSA {
    //公钥
    private static final String PUBLIC_KEY = "RSAPublicKey";
    //私钥
    private static final String PRIVATE_KEY = "RSAPrivateKey";
 
    /** 初始化密钥对
     * @return Map 密钥对Map
     * @throws Exception
     */
    public static Map<String, Object> initKey() {
        try {
            //实例化密钥对生成器
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            // 初始化密钥对生成器,密钥大小为96-1024位
            keyPairGenerator.initialize(1024, new SecureRandom());
            //生成密钥对
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            //公钥
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            //私钥
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            //将密钥对存储在Map中
            Map<String, Object> keyMap = new HashMap<String, Object>(2);
            keyMap.put(PUBLIC_KEY, publicKey);
            keyMap.put(PRIVATE_KEY, privateKey);
            return keyMap;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /** 加密【公钥加密,私钥解密】
     * @param data 待加密数据
     * @param key  公钥
     * @return byte[] 加密数据
     * @throws Exception
     */
    public static byte[] encrypt(byte[] data, byte[] key) {
        try {
            RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA")
                    .generatePublic(new X509EncodedKeySpec(key));
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            byte[] result = cipher.doFinal(data);
            return result;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }
 
    /**  解密【公钥加密,私钥解密】
     * @param data 待解密数据
     * @param key  私钥
     * @return byte[] 解密数据
     * @throws Exception
     */
    public static byte[] decrypt(byte[] data, byte[] key) {
        try {
            RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA")
                    .generatePrivate(new PKCS8EncodedKeySpec(key));
            //实例化
            Cipher cipher = Cipher.getInstance("RSA");
            //使用密钥初始化,设置为解密模式
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            //执行操作
            byte[] result = cipher.doFinal(data);
            return result;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }
 
    /** 取得私钥
     * @param keyMap 密钥Map
     * @return byte[] 私钥
     * @throws Exception
     */
    public static byte[] getPrivateKey(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PRIVATE_KEY);
        return key.getEncoded();
    }
 
    /** 取得公钥
     * @param keyMap 密钥Map
     * @return byte[] 公钥
     * @throws Exception
     */
    public static byte[] getPublicKey(Map<String, Object> keyMap) {
        Key key = (Key) keyMap.get(PUBLIC_KEY);
        return key.getEncoded();
    }
}

============================================================================RSA加解密工具测试类:

@Test
    public void test_RSA() {
        //公钥
        byte[] publicKey;
        //私钥
        byte[] privateKey;
 
        //初始化密钥
        //生成甲方密钥对
        Map<String, Object> keyMap = SecurityRSA.initKey();
        publicKey = SecurityRSA.getPublicKey(keyMap);
        privateKey = SecurityRSA.getPrivateKey(keyMap);
        System.out.println("RSA公钥:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(publicKey));
        System.out.println("RSA私钥:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(privateKey));
 
        System.out.println();
        System.out.println("===甲方向乙方发送加密数据===");
        String msgA2B = "求知若饥,虚心若愚。";
        System.out.println("原文:\n" + msgA2B);
        System.out.println("---甲方使用公钥对数据进行加密---");
        //使用公钥对数据加密
        byte[] encodeMsgA2B = SecurityRSA.encrypt(msgA2B.getBytes(), publicKey);
        System.out.println("RSA加密:\n" + org.apache.commons.codec.binary.Base64.encodeBase64String(encodeMsgA2B));
        System.out.println("---乙方使用私钥对数据库进行解密---");
        //使用私钥对数据进行解密
        byte[] msgB2A = SecurityRSA.decrypt(encodeMsgA2B, privateKey);
        String output1 = new String(msgB2A);
        System.out.println("RSA解密:\n" + output1);
    }