RSA公私鑰生成(一)


參考博客:https://www.cnblogs.com/taoshihan/p/6340854.html

一、確認Linux服務器是否安裝openssl

   確認指令:openssl version -a

  如果沒有安裝,可以百度參考

 

二、生成RSA公私鑰
  1、進入Linux系統,隨意一個文件夾
    demo:cd /home/RSA

package com.snowball.common.util.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.FileInputStream;  
import java.security.InvalidKeyException;
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.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

@SuppressWarnings("restriction")
public class RSAUtil {
    
    /**
     * 私鑰
     */
    private RSAPrivateKey privateKey;

    /**
     * 公鑰
     */
    private RSAPublicKey publicKey;
    
    /**
     * 獲取私鑰
     * @return 當前的私鑰對象
     */
    public RSAPrivateKey getPrivateKey() {
        return privateKey;
    }

    /**
     * 獲取公鑰
     * @return 當前的公鑰對象
     */
    public RSAPublicKey getPublicKey() {
        return publicKey;
    }

    /**
     * 隨機生成密鑰對
     */
    public void genKeyPair(){
        KeyPairGenerator keyPairGen= null;
        try {
            keyPairGen= KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        keyPairGen.initialize(1024, new SecureRandom());
        KeyPair keyPair= keyPairGen.generateKeyPair();
        this.privateKey= (RSAPrivateKey) keyPair.getPrivate();
        this.publicKey= (RSAPublicKey) keyPair.getPublic();
    }

    /**
     * 從文件中輸入流中加載公鑰
     * @param in 公鑰輸入流
     * @throws Exception 加載公鑰時產生的異常
     */
    public void loadPublicKey(InputStream in) throws Exception{
        try {
            BufferedReader br= new BufferedReader(new InputStreamReader(in));
            String readLine= null;
            StringBuilder sb= new StringBuilder();
            while((readLine= br.readLine())!=null){
                if(readLine.charAt(0)=='-'){
                    continue;
                }else{
                    sb.append(readLine);
                    sb.append('\r');
                }
            }
            loadPublicKey(sb.toString());
        } catch (IOException e) {
            throw new Exception("公鑰數據流讀取錯誤");
        } catch (NullPointerException e) {
            throw new Exception("公鑰輸入流為空");
        }
    }


    /**
     * 從字符串中加載公鑰
     * @param publicKeyStr 公鑰數據字符串
     * @throws Exception 加載公鑰時產生的異常
     */
    public void loadPublicKey(String publicKeyStr) throws Exception{
        try {
            BASE64Decoder base64Decoder= new BASE64Decoder();
            byte[] buffer= base64Decoder.decodeBuffer(publicKeyStr);
            KeyFactory keyFactory= KeyFactory.getInstance("RSA");
            X509EncodedKeySpec keySpec= new X509EncodedKeySpec(buffer);
            this.publicKey= (RSAPublicKey) keyFactory.generatePublic(keySpec);
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("無此算法");
        } catch (InvalidKeySpecException e) {
            throw new Exception("公鑰非法");
        } catch (IOException e) {
            throw new Exception("公鑰數據內容讀取錯誤");
        } catch (NullPointerException e) {
            throw new Exception("公鑰數據為空");
        }
    }

    /**
     * 從文件中加載私鑰
     * @param keyFileName 私鑰文件名
     * @return 是否成功
     * @throws Exception 
     */
    public void loadPrivateKey(InputStream in) throws Exception{
        try {
            BufferedReader br= new BufferedReader(new InputStreamReader(in));
            String readLine= null;
            StringBuilder sb= new StringBuilder();
            while((readLine= br.readLine())!=null){
                if(readLine.charAt(0)=='-'){
                    continue;
                }else{
                    sb.append(readLine);
                    sb.append('\r');
                }
            }
            loadPrivateKey(sb.toString());
        } catch (IOException e) {
            throw new Exception("私鑰數據讀取錯誤");
        } catch (NullPointerException e) {
            throw new Exception("私鑰輸入流為空");
        }
    }

    public void loadPrivateKey(String privateKeyStr) throws Exception{
        try {
            BASE64Decoder base64Decoder= new BASE64Decoder();
            byte[] buffer= base64Decoder.decodeBuffer(privateKeyStr);

            RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure((ASN1Sequence) ASN1Sequence.fromByteArray(buffer));
            RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent());
            KeyFactory keyFactory= KeyFactory.getInstance("RSA");
            RSAPrivateKey  priKey=(RSAPrivateKey) keyFactory.generatePrivate(rsaPrivKeySpec);
            this.privateKey=priKey;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("無此算法");
        } catch (InvalidKeySpecException e) {
            throw new Exception("私鑰非法");
        } catch (IOException e) {
            throw new Exception("私鑰數據內容讀取錯誤");
        } catch (NullPointerException e) {
            throw new Exception("私鑰數據為空");
        }
    }

    /**
     * 加密過程
     * @param publicKey 公鑰
     * @param plainTextData 明文數據
     * @return
     * @throws Exception 加密過程中的異常信息
     */
    public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception{
        if(publicKey== null){
            throw new Exception("加密公鑰為空, 請設置");
        }
        Cipher cipher= null;
        try {
            cipher= Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider());
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] output= cipher.doFinal(plainTextData);
            return output;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("無此加密算法");
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        }catch (InvalidKeyException e) {
            throw new Exception("加密公鑰非法,請檢查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("明文長度非法");
        } catch (BadPaddingException e) {
            throw new Exception("明文數據已損壞");
        }
    }

    /**
     * 解密過程
     * @param privateKey 私鑰
     * @param cipherData 密文數據
     * @return 明文
     * @throws Exception 解密過程中的異常信息
     */
    public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData) throws Exception{
        if (privateKey== null){
            throw new Exception("解密私鑰為空, 請設置");
        }
        Cipher cipher= null;
        try {
            cipher= Cipher.getInstance("RSA/ECB/PKCS1Padding", new BouncyCastleProvider());
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] output= cipher.doFinal(cipherData);
            return output;
        } catch (NoSuchAlgorithmException e) {
            throw new Exception("無此解密算法");
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
            return null;
        }catch (InvalidKeyException e) {
            throw new Exception("解密私鑰非法,請檢查");
        } catch (IllegalBlockSizeException e) {
            throw new Exception("密文長度非法");
        } catch (BadPaddingException e) {
            throw new Exception("密文數據已損壞");
        }        
    }


    
    public static void main(String[] args){
        RSAUtil rsaEncrypt= new RSAUtil();
        //加載公鑰
        try {
            rsaEncrypt.loadPublicKey(new FileInputStream(RSAUtil.class.getClassLoader().getResource("rsa_public_key.pem").getPath()));
            System.out.println("加載公鑰成功");
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.err.println("加載公鑰失敗");
        }

        //加載私鑰
        try {
            rsaEncrypt.loadPrivateKey(new FileInputStream(RSAUtil.class.getClassLoader().getResource("rsa_private_key.pem").getPath()));
            System.out.println("加載私鑰成功");
        } catch (Exception e) {
            System.err.println(e.getMessage());
            System.err.println("加載私鑰失敗");
        }

        //完整加解密
        try {
            //測試字符串
            String encryptStr= "13392801646";
            System.out.println("加密前:");
            System.out.println(encryptStr);
            //加密
            byte[] cipher = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), encryptStr.getBytes());
            //解密
            byte[] plainText = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), cipher);
            BASE64Encoder encode = new BASE64Encoder(); 
            String buffer= encode.encode(cipher);
            System.out.println("加密后:");
            System.out.println(new String(buffer));
            System.out.println("解密后:");
            System.out.println(new String(plainText));
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }   
            
        //小米提供的密文,解密用例  
        try {
             BASE64Decoder base64Decoder= new BASE64Decoder();
             byte[] dd = base64Decoder.decodeBuffer("tv8BHq/CYcEC/eJo68hE+r2lYwzx/bfaNfrZx+a81oSLjHBWl+6lgy+1DuBD7pThA9cFrpcHimkV7iHZVp8AWvJyI5U2Z7jDhG4XK1/P0kZK4wShI6ay7MyFYOI4fYL47RpCongRcYsv2A1RDW92/0lsiut43BXD8K80xA56sBQ=");
             byte[] dds  = rsaEncrypt.decrypt(rsaEncrypt.getPrivateKey(), dd);
             System.out.println("測試解密:"+new String(dds));
        } catch (Exception e) {
            
        }   
            
    }

}

 

   2、生成RSA私鑰
    命令:openssl genrsa -out 私鑰名稱.pem 1024
    demo:openssl genrsa -out rsa_private_key.pem 1024

   3、生成私鑰
    命令:openssl rsa -in 私鑰名稱.pem -pubout -out 公鑰名稱.pem
    demo:openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

   4、通過ftp工具下載生成的公私鑰

   5、導入項目,代碼實現參考"RSAUtil.java"文件

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM