RSA加密解密实现详情

RSA加密解密实现详情



import java.math.BigInteger;
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.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

/**
 * RSA加密解密实现详情
 * **/
public class RSA001Utils {

    public static final String RSA = "RSA";
    private static final String PUBLIC_KEY = "RSAPublicKey";
    private static final String PRIVATE_KEY = "RSAPrivateKey";

    
    //-------------------------------------01-----------------------------------//
    /*公钥和私钥可以通过KeyPairGenerator执行generateKeyPair()后生成密钥对KeyPair,
          通过KeyPair.getPublic()和KeyPair.getPrivate()来获取。
          如下代码:*/
    /**
     * 获取 密钥对KeyPair
     * RSA的公钥和私钥是由KeyPairGenerator生成的,获取KeyPairGenerator的实例后还需要设置其密钥位数。
     * 设置密钥位数越高,加密过程越安全,一般使用1024位。如下代码:
     * **/
    public static KeyPair getKeyPair(){
        KeyPair keyPair=null;
        try {
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(RSA);
            // 密钥位数//设置密钥位数越高,加密过程越安全,一般使用1024位
            keyPairGen.initialize(1024);
            
            /*//自定义securerandom 实现作为随机源
            SecureRandom secrand = new SecureRandom();
            secrand.setSeed("syj".getBytes()); // 初始化随机产生器
            keyPairGen.initialize(1024, secrand);*/
            
            // 动态生成密钥对,这是当前最耗时的操作,一般要2s以上。
            keyPair = keyPairGen.generateKeyPair();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return keyPair;
    }
    /**
     * 获取 公钥和私钥
     * 公钥和私钥可以通过KeyPairGenerator执行generateKeyPair()后生成密钥对KeyPair,
     * 通过KeyPair.getPublic()和KeyPair.getPrivate()来获取。如下代码:
     * **/
    public static Map initKey(KeyPair keyPair){
        Map keyMap = new HashMap(2);
        if(keyPair!=null){
            // 公钥
            PublicKey publicKey = keyPair.getPublic();//密钥对KeyPair获取公钥
            keyMap.put(PUBLIC_KEY, publicKey);
            byte[] publicKeyData = publicKey.getEncoded();
            PublicKey publicKey2=getPublicKey(publicKeyData);//由byte[]还原PublicKey
            try {
                String public_key=encryptBASE64(publicKeyData);//由byte[]转字符串public_key
                System.out.println("public_key:");
                System.out.println(public_key);
                byte[] privateKeyData2=decryptBASE64(public_key);//由字符串转byte[]
                int a=0;
            } catch (Exception e) {
                e.printStackTrace();
            }
            
            // 私钥
            PrivateKey privateKey = keyPair.getPrivate();//密钥对KeyPair获取私钥
            keyMap.put(PRIVATE_KEY, privateKey);
            byte[] privateKeyData = privateKey.getEncoded();
            PrivateKey privateKey2=getPrivateKey(privateKeyData);//由byte[]还原PrivateKey
            try {
                String private_key=encryptBASE64(privateKeyData);//由byte[]转字符串private_key
                System.out.println("private_key:");
                System.out.println(private_key);
                byte[] privateKeyData2=decryptBASE64(private_key);//由字符串转byte[]
                int a=0;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return keyMap;
    }
    
    //------------------------------------02------------------------------------//
    /*公钥和私钥都有它们自己独特的比特编码,可以通过getEncoded()方法获取,返回类型为byte[]。
          通过byte[]可以再度将公钥或私钥还原出来。
          具体代码如下:*/
    /**
     * 通过公钥byte[]将公钥还原,适用于RSA算法
     * **/
     public static PublicKey getPublicKey(byte[] keyBytes) {
         X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
         PublicKey publicKey=null;
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(RSA);
            publicKey = keyFactory.generatePublic(keySpec);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
         return publicKey;
     }
     /**
      * 通过私钥byte[]将公钥还原,适用于RSA算法
      * **/
     public static PrivateKey getPrivateKey(byte[] keyBytes) {
         PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
         PrivateKey privateKey=null;
        try {
             KeyFactory keyFactory = KeyFactory.getInstance(RSA);
             privateKey = keyFactory.generatePrivate(keySpec);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
         return privateKey;
     }
     
     ///
     /* 公钥和私钥都有它们自己独特的比特编码,可以通过getEncoded()方法获取,返回类型为byte[]。
         由 BASE64Encoder.encodeBuffer(key)把类型为byte[]转字符串String
      */
     public static String encryptBASE64(byte[] key) throws Exception {               

        return (new BASE64Encoder()).encodeBuffer(key);               

    }
     /*
      公钥和私钥都有它们自己独特的比特编码,可以通过getEncoded()方法获取,返回类型为byte[]。
         由 BASE64Encoder.encodeBuffer(key)把byte[]转字符串String;
         再由BASE64Encoder.decodeBuffer(key)把字符串String转byte[]
      */
    public static byte[] decryptBASE64(String key) throws Exception {               

        return (new BASE64Decoder()).decodeBuffer(key);               

    }                                 
    ///

    
    
    //-----------------------------------------03-------------------------------//
    /*在上文讲到的RSA算法实现过程中提到(N,e)是公钥,(N,d)是私钥。既然已经获取到了PublicKey和PrivateKey了,
          那如何取到N、e、d这三个值呢。要取到这三个值,首先要将PublicKey和PrivateKey强制转换成RSAPublicKey和RSAPrivateKey。
          共同的N值可以通过getModulus()获取。
          执行RSAPublicKey.getPublicExponent()可以获取到公钥中的e值,
          执行RSAPrivateKey.getPrivateExponent()可以获取私钥中的d值。
          这三者返回类型都是BigInteger。
          代码如下:*/
   /**
    * 打印公钥信息
    * N、e值
    * **/
    public static void printPublicKeyInfo(PublicKey publicKey){
        if(publicKey!=null){
            RSAPublicKey rsaPublicKey = (RSAPublicKey)publicKey;
            System.out.println("RSAPublicKey:");
            System.out.println("(N值)Modulus="+rsaPublicKey.getModulus().toString());
            System.out.println("(e值)PublicExponent="+rsaPublicKey.getPublicExponent().toString());
        }else{
            System.out.println("printPublicKeyInfo-------失败");
        }
    }
    /**
     * 打印私钥信息
     * N、d值
     * **/
    public static void printPrivateKeyInfo(PrivateKey privateKey){
        if(privateKey!=null){
            RSAPrivateKey  rsaPrivateKey = (RSAPrivateKey ) privateKey;
            System.out.println("RSAPrivateKey:");
            System.out.println("(N值)Modulus="+rsaPrivateKey.getModulus().toString());
            System.out.println("(d值)PrivateExponent="+rsaPrivateKey.getPrivateExponent().toString());
        }else{
            System.out.println("printPrivateKeyInfo-------失败");
        }
    }
    
    //-----------------------------------------04-------------------------------//
    /*由于程序中动态生成KeyPair对明文加密后生成的密文是不可测的,
         所以在实际开发中通常在生成一个KeyPair后将公钥和私钥的N、e、d这三个特征值记录下来,
         在真实的开发中使用这三个特征值再去将PublicKey和PrivateKey还原出来。
         还原方法如下:*/
     /**
      * 使用N、e值还原公钥
      * **/
     public static PublicKey getPublicKey(String modulus, String publicExponent) {
         BigInteger bigIntModulus = new BigInteger(modulus);
         BigInteger bigIntPrivateExponent = new BigInteger(publicExponent);
         RSAPublicKeySpec keySpec = new RSAPublicKeySpec(bigIntModulus,bigIntPrivateExponent);
         PublicKey publicKey=null;
        try {
            KeyFactory keyFactory = KeyFactory.getInstance(RSA);
            publicKey = keyFactory.generatePublic(keySpec);
        } catch (NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        }catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
         return publicKey;
     }
     
     /**
      * 使用N、d值还原私钥
      * **/
     public static PrivateKey getPrivateKey(String modulus, String privateExponent) {
         BigInteger bigIntModulus = new BigInteger(modulus);
         BigInteger bigIntPrivateExponent = new BigInteger(privateExponent);
         RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(bigIntModulus,bigIntPrivateExponent);
         PrivateKey privateKey=null;
        try {
             KeyFactory keyFactory = KeyFactory.getInstance(RSA);
             privateKey = keyFactory.generatePrivate(keySpec);
        } catch (NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        }catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
         return privateKey;
     }
    
    
    
    public static void main(String[] args) {

        try {
            KeyPair keyPair = RSA001Utils.getKeyPair();//获取 密钥对KeyPair
            Map keyMap=RSA001Utils.initKey(keyPair);//获取 公钥和私钥
            RSA001Utils.printPublicKeyInfo((PublicKey)keyMap.get(PUBLIC_KEY));
            System.out.println("----------------------------------");
            RSA001Utils.printPrivateKeyInfo((PrivateKey)keyMap.get(PRIVATE_KEY));
        
        } catch (Exception e) {
        
            e.printStackTrace();
        }  
    
    }


}

你可能感兴趣的:(加密)