RSA加密解密

http://files.cnblogs.com/files/liuJava/rsa.zip、

直接上工具類 JAR 和前臺JS 都在上面的鏈接里

?

package my.tools.security;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyFactory;
import java.security.KeyPairGenerator;
import java.security.Provider;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidParameterException;
import java.security.interfaces.RSAPublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.InvalidKeySpecException;import javax.crypto.Cipher;import org.apache.commons.io.IOUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;/*** RSA算法加密/解密工具類。* * @author fuchun* @version 1.0.0, 2010-05-05*/
public abstract class RSAUtils {private static final Logger LOGGER = LoggerFactory.getLogger(RSAUtils.class);/** 算法名稱 */private static final String ALGORITHOM = "RSA";/**保存生成的密鑰對的文件名稱。 */private static final String RSA_PAIR_FILENAME = "/__RSA_PAIR.txt";/** 密鑰大小 */private static final int KEY_SIZE = 1024;/** 默認的安全服務提供者 */private static final Provider DEFAULT_PROVIDER = new BouncyCastleProvider();private static KeyPairGenerator keyPairGen = null;private static KeyFactory keyFactory = null;/** 緩存的密鑰對。 */private static KeyPair oneKeyPair = null;private static File rsaPairFile = null;static {try {keyPairGen = KeyPairGenerator.getInstance(ALGORITHOM, DEFAULT_PROVIDER);keyFactory = KeyFactory.getInstance(ALGORITHOM, DEFAULT_PROVIDER);} catch (NoSuchAlgorithmException ex) {LOGGER.error(ex.getMessage());}rsaPairFile = new File(getRSAPairFilePath());}private RSAUtils() {}/*** 生成并返回RSA密鑰對。*/private static synchronized KeyPair generateKeyPair() {try {keyPairGen.initialize(KEY_SIZE, new SecureRandom(DateFormatUtils.format("yyyyMMdd").getBytes()));oneKeyPair = keyPairGen.generateKeyPair();saveKeyPair(oneKeyPair);return oneKeyPair;} catch (InvalidParameterException ex) {LOGGER.error("KeyPairGenerator does not support a key length of " + KEY_SIZE + ".", ex);} catch (NullPointerException ex) {LOGGER.error("RSAUtils#KEY_PAIR_GEN is null, can not generate KeyPairGenerator instance.",ex);}return null;}/*** 返回生成/讀取的密鑰對文件的路徑。*/private static String getRSAPairFilePath() {String urlPath = RSAUtils.class.getResource("/").getPath();return (new File(urlPath).getParent() + RSA_PAIR_FILENAME);}/*** 若需要創建新的密鑰對文件,則返回 {@code true},否則 {@code false}。*/private static boolean isCreateKeyPairFile() {// 是否創建新的密鑰對文件boolean createNewKeyPair = false;if (!rsaPairFile.exists() || rsaPairFile.isDirectory()) {createNewKeyPair = true;}return createNewKeyPair;}/*** 將指定的RSA密鑰對以文件形式保存。* * @param keyPair 要保存的密鑰對。*/private static void saveKeyPair(KeyPair keyPair) {FileOutputStream fos = null;ObjectOutputStream oos = null;try {fos = FileUtils.openOutputStream(rsaPairFile);oos = new ObjectOutputStream(fos);oos.writeObject(keyPair);} catch (Exception ex) {ex.printStackTrace();} finally {IOUtils.closeQuietly(oos);IOUtils.closeQuietly(fos);}}/*** 返回RSA密鑰對。*/public static KeyPair getKeyPair() {// 首先判斷是否需要重新生成新的密鑰對文件if (isCreateKeyPairFile()) {// 直接強制生成密鑰對文件,并存入緩存。return generateKeyPair();}if (oneKeyPair != null) {return oneKeyPair;}return readKeyPair();}// 同步讀出保存的密鑰對private static KeyPair readKeyPair() {FileInputStream fis = null;ObjectInputStream ois = null;try {fis = FileUtils.openInputStream(rsaPairFile);ois = new ObjectInputStream(fis);oneKeyPair = (KeyPair) ois.readObject();return oneKeyPair;} catch (Exception ex) {ex.printStackTrace();} finally {IOUtils.closeQuietly(ois);IOUtils.closeQuietly(fis);}return null;}/*** 根據給定的系數和專用指數構造一個RSA專用的公鑰對象。* * @param modulus 系數。* @param publicExponent 專用指數。* @return RSA專用公鑰對象。*/public static RSAPublicKey generateRSAPublicKey(byte[] modulus, byte[] publicExponent) {RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(new BigInteger(modulus),new BigInteger(publicExponent));try {return (RSAPublicKey) keyFactory.generatePublic(publicKeySpec);} catch (InvalidKeySpecException ex) {LOGGER.error("RSAPublicKeySpec is unavailable.", ex);} catch (NullPointerException ex) {LOGGER.error("RSAUtils#KEY_FACTORY is null, can not generate KeyFactory instance.", ex);}return null;}/*** 根據給定的系數和專用指數構造一個RSA專用的私鑰對象。* * @param modulus 系數。* @param privateExponent 專用指數。* @return RSA專用私鑰對象。*/public static RSAPrivateKey generateRSAPrivateKey(byte[] modulus, byte[] privateExponent) {RSAPrivateKeySpec privateKeySpec = new RSAPrivateKeySpec(new BigInteger(modulus),new BigInteger(privateExponent));try {return (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);} catch (InvalidKeySpecException ex) {LOGGER.error("RSAPrivateKeySpec is unavailable.", ex);} catch (NullPointerException ex) {LOGGER.error("RSAUtils#KEY_FACTORY is null, can not generate KeyFactory instance.", ex);}return null;}/*** 根據給定的16進制系數和專用指數字符串構造一個RSA專用的私鑰對象。* * @param modulus 系數。* @param privateExponent 專用指數。* @return RSA專用私鑰對象。*/public static RSAPrivateKey getRSAPrivateKey(String hexModulus, String hexPrivateExponent) {if(StringUtils.isBlank(hexModulus) || StringUtils.isBlank(hexPrivateExponent)) {if(LOGGER.isDebugEnabled()) {LOGGER.debug("hexModulus and hexPrivateExponent cannot be empty. RSAPrivateKey value is null to return.");}return null;}byte[] modulus = null;byte[] privateExponent = null;try {modulus = Hex.decodeHex(hexModulus.toCharArray());privateExponent = Hex.decodeHex(hexPrivateExponent.toCharArray());} catch(DecoderException ex) {LOGGER.error("hexModulus or hexPrivateExponent value is invalid. return null(RSAPrivateKey).");}if(modulus != null && privateExponent != null) {return generateRSAPrivateKey(modulus, privateExponent);}return null;}/*** 根據給定的16進制系數和專用指數字符串構造一個RSA專用的公鑰對象。* * @param modulus 系數。* @param publicExponent 專用指數。* @return RSA專用公鑰對象。*/public static RSAPublicKey getRSAPublidKey(String hexModulus, String hexPublicExponent) {if(StringUtils.isBlank(hexModulus) || StringUtils.isBlank(hexPublicExponent)) {if(LOGGER.isDebugEnabled()) {LOGGER.debug("hexModulus and hexPublicExponent cannot be empty. return null(RSAPublicKey).");}return null;}byte[] modulus = null;byte[] publicExponent = null;try {modulus = Hex.decodeHex(hexModulus.toCharArray());publicExponent = Hex.decodeHex(hexPublicExponent.toCharArray());} catch(DecoderException ex) {LOGGER.error("hexModulus or hexPublicExponent value is invalid. return null(RSAPublicKey).");}if(modulus != null && publicExponent != null) {return generateRSAPublicKey(modulus, publicExponent);}return null;}/*** 使用指定的公鑰加密數據。* * @param publicKey 給定的公鑰。* @param data 要加密的數據。* @return 加密后的數據。*/public static byte[] encrypt(PublicKey publicKey, byte[] data) throws Exception {Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER);ci.init(Cipher.ENCRYPT_MODE, publicKey);return ci.doFinal(data);}/*** 使用指定的私鑰解密數據。* * @param privateKey 給定的私鑰。* @param data 要解密的數據。* @return 原數據。*/public static byte[] decrypt(PrivateKey privateKey, byte[] data) throws Exception {Cipher ci = Cipher.getInstance(ALGORITHOM, DEFAULT_PROVIDER);ci.init(Cipher.DECRYPT_MODE, privateKey);return ci.doFinal(data);}/*** 使用給定的公鑰加密給定的字符串。* <p />* 若 {@code publicKey} 為 {@code null},或者 {@code plaintext} 為 {@code null} 則返回 {@code* null}。* * @param publicKey 給定的公鑰。* @param plaintext 字符串。* @return 給定字符串的密文。*/public static String encryptString(PublicKey publicKey, String plaintext) {if (publicKey == null || plaintext == null) {return null;}byte[] data = plaintext.getBytes();try {byte[] en_data = encrypt(publicKey, data);return new String(Hex.encodeHex(en_data));} catch (Exception ex) {LOGGER.error(ex.getCause().getMessage());}return null;}/*** 使用默認的公鑰加密給定的字符串。* <p />* 若{@code plaintext} 為 {@code null} 則返回 {@code null}。* * @param plaintext 字符串。* @return 給定字符串的密文。*/public static String encryptString(String plaintext) {if(plaintext == null) {return null;}byte[] data = plaintext.getBytes();KeyPair keyPair = getKeyPair();try {byte[] en_data = encrypt((RSAPublicKey)keyPair.getPublic(), data);return new String(Hex.encodeHex(en_data));} catch(NullPointerException ex) {LOGGER.error("keyPair cannot be null.");} catch(Exception ex) {LOGGER.error(ex.getCause().getMessage());}return null;}/*** 使用給定的私鑰解密給定的字符串。* <p />* 若私鑰為 {@code null},或者 {@code encrypttext} 為 {@code null}或空字符串則返回 {@code null}。* 私鑰不匹配時,返回 {@code null}。* * @param privateKey 給定的私鑰。* @param encrypttext 密文。* @return 原文字符串。*/public static String decryptString(PrivateKey privateKey, String encrypttext) {if (privateKey == null || StringUtils.isBlank(encrypttext)) {return null;}try {byte[] en_data = Hex.decodeHex(encrypttext.toCharArray());byte[] data = decrypt(privateKey, en_data);return new String(data);} catch (Exception ex) {LOGGER.error(String.format("\"%s\" Decryption failed. Cause: %s", encrypttext, ex.getCause().getMessage()));}return null;}/*** 使用默認的私鑰解密給定的字符串。* <p />* 若{@code encrypttext} 為 {@code null}或空字符串則返回 {@code null}。* 私鑰不匹配時,返回 {@code null}。* * @param encrypttext 密文。* @return 原文字符串。*/public static String decryptString(String encrypttext) {if(StringUtils.isBlank(encrypttext)) {return null;}KeyPair keyPair = getKeyPair();try {byte[] en_data = Hex.decodeHex(encrypttext.toCharArray());byte[] data = decrypt((RSAPrivateKey)keyPair.getPrivate(), en_data);return new String(data);} catch(NullPointerException ex) {LOGGER.error("keyPair cannot be null.");} catch (Exception ex) {LOGGER.error(String.format("\"%s\" Decryption failed. Cause: %s", encrypttext, ex.getMessage()));}return null;}/*** 使用默認的私鑰解密由JS加密(使用此類提供的公鑰加密)的字符串。* * @param encrypttext 密文。* @return {@code encrypttext} 的原文字符串。*/public static String decryptStringByJs(String encrypttext) {String text = decryptString(encrypttext);if(text == null) {return null;}return StringUtils.reverse(text);}/** 返回已初始化的默認的公鑰。*/public static RSAPublicKey getDefaultPublicKey() {KeyPair keyPair = getKeyPair();if(keyPair != null) {return (RSAPublicKey)keyPair.getPublic();}return null;}/** 返回已初始化的默認的私鑰。*/public static RSAPrivateKey getDefaultPrivateKey() {KeyPair keyPair = getKeyPair();if(keyPair != null) {return (RSAPrivateKey)keyPair.getPrivate();}return null;}
}

  

用法說下:還是直接上個JAVA里面的測試:

public static void main(String[] args) {RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey();char[] encodeHex = Hex.encodeHex(publicKey.getPublicExponent().toByteArray());String exponent = new String (encodeHex);char[] encodeHex2 = Hex.encodeHex(publicKey.getModulus().toByteArray());String modulus=new String (encodeHex2);String encryptString = RSAUtils.encryptString(publicKey, "你好啊啊啊啊");System.out.println(encryptString);String decryptStringByJs = RSAUtils.decryptStringByJs(encryptString);char[] charArray = decryptStringByJs.toCharArray();String resultString = ""; for (int i=charArray.length-1; i>=0; i--){ resultString += charArray[i]; } System.out.println(resultString);}

  在WEB項目中 給一些需要加密的數據加密的時候?

后臺分發秘鑰

RSAPublicKey publicKey = RSAUtils.getDefaultPublicKey();char[] encodeHex = Hex.encodeHex(publicKey.getPublicExponent().toByteArray());String exponent = new String (encodeHex);ActionContext.getContext().put("exponent", exponent); ActionContext.getContext().put("modulus", new String(Hex.encodeHex(publicKey.getModulus().toByteArray())));

  

演示下JS請求 后臺秘鑰的過程

function dls(){// 這2個 就是請求來的 var modulus = $("#modulus").val(), exponent = $("#exponentid").val();var key = RSAUtils.getKeyPair(exponent, "", modulus);pwd2 = RSAUtils.encryptedString(key, $("#passwordid").val());$("#passwordid").val(pwd2)document.getElementById("formid").submit();}

  后臺解密的過程

解密:
password = RSAUtils.decryptStringByJs(password);

  

?

轉載于:https://www.cnblogs.com/liuJava/p/5069777.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/286181.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/286181.shtml
英文地址,請注明出處:http://en.pswp.cn/news/286181.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Atitit.js圖表控件總結

Atitit.js圖表控件總結 1. 為什么要使用圖表1 2. 圖表分類1 3. 數據可視化的優點1 4. 流行的js圖表類庫1 5. 參考2 1. 為什么要使用圖表 因為要可視化 2. 圖表分類 條形圖、柱狀圖、折線圖和餅圖是圖表中四種最常用的基本類型 分類 條形圖、柱狀圖、折線圖和餅圖是圖表中四種最…

Matlab圖像處理函數大全(建議收藏)

文章目錄 第1章: 圖像顯示與圖像文件輸入輸出函數第2章: 圖形繪制第3章: 圖像類型和類型轉換第4章: 圖形用戶界面工具第5章: 空間變換和圖像配準第6章: 圖像分析和統計第7章: 圖像代數運算第8章: 圖像增強第9章: 圖像去模糊第10章: 線性濾波和變換第11章: 形態學操作…

Asp.net 批量導入Excel用戶數據功能加強版

平時我們用Asp.net導入用戶&#xff0c;一般是提供一個用戶Excel表的模板&#xff0c;實際導入數據時并非有些人愿意按你的模版制表&#xff0c;因此對Asp.net導入功能進行加強&#xff0c;可以導入非模版化的Excel數據&#xff0c;并且支持一次處理多個Sheet表&#xff0c;方便…

C語言試題三十八之將s所指字符串中除了下標為偶數、同時ascii值也為偶數的字符外,其余的全都刪除;串中剩余字符所形成的一個新串放在t所指的一個數組中。

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 請編寫一個…

C#+Signalr+Vue實現B站視頻自動回復評論,當一個最懶程序員!

Part1前言前幾天刷到了程序員魚皮的自動回復視頻評論的視頻&#xff0c;于是我也想來試試&#xff01;Part2開始第一步打開想要自動回復評論的視頻url&#xff0c;打開調試模式&#xff01;然后找到可以觸發評論的網絡請求可以看到我們的oid是可以唯一確定視頻的id,那么這個oid…

一張圖不用,純CSS 做個生日賀卡

朋友生日了&#xff0c;直接畫&#xff0c;炫技并且表示本人閑的全身疼才會去拿CSS畫畫&#xff0c;以此嘲弄對方的加班&#xff1a; 既然賀卡做出來了&#xff0c;那就順便介紹一下賀卡制作流程吧&#xff0c;其實也不是什么技術&#xff0c;也就是CSS 拼拼拼就可以了&#…

C語言試題三十九之將s所指字符串中除了下標為奇數、同時ascii值也為奇數的字符外,其余的全都刪除;串中剩余字符所形成的一個新串放在t所指的一個數組中。

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 請編寫一個…

The type android.support.v4.view.ScrollingView cannot be resolved. It is indirectly referenced from

前幾天另一個項目使用RecyclerView控件&#xff0c;引用類庫然后繼承一切都很順序 詳細&#xff1a;http://www.cnblogs.com/freexiaoyu/p/5022602.html 今天打算將另一個項目的ListView控件也替換成RecyclerView以同樣的方式引用了RecyclerView,引用地址請點擊上面的鏈接查看 …

Mysql索引的類型和優缺點

索引是一種特殊的文件(InnoDB數據表上的索引是表空間的一個組成部分)&#xff0c;它們包含著對數據表里所有記錄的引用指針。注&#xff1a;[1]索引不是萬能的&#xff01;索引可以加快數據檢索操作&#xff0c;但會使數據修改操作變慢。每修改數據記錄&#xff0c;索引就必須刷…

Android Notification總結

Android Notification總結 目錄[-] &#xfeff;&#xfeff;一、通知的主要功能 二、通知簡介 三、通知的使用流程 四、使用NotificationCompat.Builder設置通知的屬性&#xff1a; 五、管理通知 &#xfeff;&#xfeff;一、通知的主要功能 顯示接收到短消息、即使消息等信…

C#-Linq源碼解析之Any

前言在Dotnet開發過程中&#xff0c;Any作為IEnumerable的擴展方法&#xff0c;十分常用。本文對Any方法的關鍵源碼進行簡要分析&#xff0c;以方便大家日后更好的使用該方法。使用Any 確定序列中是否包含元素或存在元素滿足指定條件。看這樣一個例子&#xff0c;我們判斷集合中…

python_getopt解析命令行輸入參數的使用

[cpp] view plaincopyprint? import getopt import sys config { "input":"", "output":".", } #getopt三個選項&#xff0c;第一個一般為sys.argv[1:],第二個參數為短參數&#xff0c;如…

五、登錄頁倒計時制作《仿淘票票系統前后端完全制作(除支付外)》

一、登錄功能的實現 首先打開在線編輯器進入我們的項目&#xff1a;https://editor.ivx.cn/ 上一節我們已經完成了基本頁面的制作&#xff0c;在本節中&#xff0c;我們將會開始完成登錄功能的實現。 實現登錄功能需要增加一個用戶組件&#xff1a; 這個用戶組件是需要選擇…

【MATLAB統計分析與應用100】案例001:matlab使用Importdata函數導入文本txt數據

配套實驗數據包下載&#xff1a;鏈接&#xff1a;https://pan.baidu.com/s/1T4zUFmCIOCKIisdGRQPddg?pwdddi1 文章目錄1. 調用importdata函數讀取文件中的數據2. 調用importdata函數讀取文件數據&#xff0c;返回結構體變量x3. 調用importdata函數讀取文件中的數據&#xff0c…

TextView的部分點擊事件和點擊事件

1.在TextView中實現部分點擊 我在activity中使用了clickablespan這個類&#xff0c;然后完全按照視頻上的操作下來&#xff0c;發現點擊時不響應&#xff0c;于是我便設置了電話的鏈接&#xff0c;發現這時點擊 自己設置的區域就會響應&#xff0c;但是如果我把電話鏈接刪了&am…

C語言試題四十之使字符串中尾部的*號不得多于n個;若多于n個,則刪除多于的*號;若少于或等于n個,則什么也不做,字符串中間和前面的*號不刪除。

??個人主頁:個人主頁 ??系列專欄:C語言試題200例目錄 ??推薦一款刷算法、筆試、面經、拿大公司offer神器 ?? 點擊跳轉進入網站 ?作者簡介:大家好,我是碼莎拉蒂,CSDN博客專家(全站排名Top 50),阿里云博客專家、51CTO博客專家、華為云享專家 1、題目 請編寫一個…

Meta http-equiv屬性詳解

Meta http-equiv屬性詳解 博客分類&#xff1a; Web綜合HTML瀏覽器IECache搜索引擎 http-equiv顧名思義&#xff0c;相當于http的文件頭作用&#xff0c;它可以向瀏覽器傳回一些有用的信息&#xff0c;以幫助正確和精確地顯示網頁內容&#xff0c;與之對應的屬性值為content&am…

MAUI 入門教程系列(3.多目標平臺)

前言如果您是第一次創建MAUI項目, 并且在之前也并沒有接觸過Xamarin.Forms應用, 或許你并不知道MAUI的強大優勢, 在原來的Xamarin.Forms當中, 我們基于不同平臺的項目他們是單獨維護的。如下所示:因為如此, 你需要維護不同平臺的項目。包括每個項目當中包含的資源、圖像、屬性定…

關于質量的聯想:消費示范效應

IT業界有新聞說&#xff0c;根據可靠性數據研究專家Rescue.com發布的今年一季度可靠性報告&#xff0c;“五大電腦公司中&#xff0c;聯想-IBM的分數高居首位&#xff0c;第二名是華碩&#xff0c;之前的可靠性冠軍蘋果跌落第三&#xff0c;東芝、惠普-康柏則排在第五”。大部分…