基于RSA的前后端登陸密碼加密JAVA實現(xiàn)

之前一直在做公司內網(wǎng)項目,對與加密基本沒有考慮,最近看到加密的方法,在此做一個筆記,以便后面使用,

RSA加密算法簡介

SA加密算法是一種非對稱加密算法着憨。在公開密鑰加密和電子商業(yè)中RSA被廣泛使用。對極大整數(shù)做因數(shù)分解的難度決定了RSA算法的可靠性圈匆。換言之邻吭,對一極大整數(shù)做因數(shù)分解愈困難晤斩,RSA算法愈可靠焕檬。假如有人找到一種快速因數(shù)分解的算法的話,那么用RSA加密的信息的可靠性就肯定會極度下降澳泵。但找到這樣的算法的可能性是非常小的实愚。今天只有短的RSA鑰匙才可能被強力方式解破。到目前為止兔辅,世界上還沒有任何可靠的攻擊RSA算法的方式腊敲。只要其鑰匙的長度足夠長,用RSA加密的信息實際上是不能被解破的维苔。

RSA加密的java實現(xiàn)

實現(xiàn)的思路,由RSA隨機生成一對公鑰和私鑰,公鑰方到客戶端,私鑰放到服務端,發(fā)送數(shù)據(jù)的時候由公鑰對傳輸數(shù)據(jù)進行加密,然后發(fā)送給服務端,服務端用私鑰才能對數(shù)據(jù)進行解密.下面是代碼實現(xiàn)的例子

package com.yihur.demo

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
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.HashMap;
import java.util.Map;

/**
 * @author yihur
 * @description RSA加密
 * @date 2019/4/3
 */
public class MyRSAencryptionMethod {

    private static Logger logger = LoggerFactory.getLogger(MyRSAencryptionMethod .class);


    /**
     * 用于封裝隨機產(chǎn)生的公鑰與私鑰
     *
     * @author yihur
     * @date 2019/4/4
     * @param
     * @return
     */
    private static Map<Integer, String> keyMap = new HashMap<>();


    /**
     * 測試方法
     *
     * @param args
     * @return void
     * <p>
     * <p>
     * 前端用crypto-js進行加密碰辅,
     * npm i jsencrypt,
     * 然后頁面頭引入import JSEncrypt from 'jsencrypt';
     * const encrypt = new JSEncrypt();
     * encrypt.setPublicKey('你的公鑰');
     * password = encrypt.encrypt(‘你的密碼’);// 加密后的字符串
     * @author yihur
     * @date 2019/4/4
     */
    public static void main(String[] args) {
        //生成公鑰和私鑰
        genKeyPair();
        //加密字符串
        String message = "df723820";
        System.out.println("隨機生成的公鑰為:" + keyMap.get(0));
        System.out.println("隨機生成的私鑰為:" + keyMap.get(1));
        String messageEn = encrypt(message, keyMap.get(0));
        System.out.println("加密后的字符串為:" + messageEn);
        String messageDe = decrypt(messageEn, keyMap.get(1));
        System.out.println("還原后的字符串為:" + messageDe);
    }

    /**
     * 隨機生成密鑰對
     *
     * @param
     * @return void
     * @author yihur
     * @date 2019/4/4
     */
    public static void genKeyPair() {
        // KeyPairGenerator類用于生成公鑰和私鑰對介时,基于RSA算法生成對象
        KeyPairGenerator keyPairGen = null;
        try {
            keyPairGen = KeyPairGenerator.getInstance("RSA");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            logger.info(e.getMessage());
        }
        // 初始化密鑰對生成器没宾,密鑰大小為96-1024位
        assert keyPairGen != null;
        keyPairGen.initialize(1024, new SecureRandom());
        // 生成一個密鑰對,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();   // 得到私鑰
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();  // 得到公鑰
        String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
        // 得到私鑰字符串
        String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
        // 將公鑰和私鑰保存到Map
        keyMap.put(0, publicKeyString);  //0表示公鑰
        keyMap.put(1, privateKeyString);  //1表示私鑰
    }

    /**
     * RSA公鑰加密
     *
     * @param str       加密字符串
     * @param publicKey 公鑰
     * @return 密文
     */
    public static String encrypt(String str, String publicKey) {
        //base64編碼的公鑰
        byte[] decoded = Base64.decodeBase64(publicKey);
        RSAPublicKey pubKey = null;
        String outStr = null;
        try {
            pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
            Cipher cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            outStr = Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
        } catch (InvalidKeySpecException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException | NoSuchPaddingException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            logger.info(e.getMessage());
        }
        //RSA加密
        return outStr;
    }

    /**
     * RSA私鑰解密
     *
     * @param str        加密字符串
     * @param privateKey 私鑰
     * @return 銘文
     */
    public static String decrypt(String str, String privateKey) {
        //64位解碼加密后的字符串
        byte[] inputByte = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
        //base64編碼的私鑰
        byte[] decoded = Base64.decodeBase64(privateKey);
        RSAPrivateKey priKey = null;
        //RSA解密
        Cipher cipher = null;
        String outStr = null;
        try {
            priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
            cipher = Cipher.getInstance("RSA");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            outStr = new String(cipher.doFinal(inputByte));
        } catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException | InvalidKeyException e) {
            e.printStackTrace();
            logger.info(e.getMessage());
        }
        return outStr;
    }

}

RSA加密的前端用法

前端用crypto-js進行加密沸柔,
npm i jsencrypt循衰,
然后頁面頭引入import JSEncrypt from 'jsencrypt';
const encrypt = new JSEncrypt();
encrypt.setPublicKey('你的公鑰');
password = encrypt.encrypt(‘你的密碼’);// 加密后的字符串

后續(xù)

在實際應用中RSA加密也還是遠遠不夠,一般還會加入MD5加密的方式,以及加密驗證,token等等方式作為請求連接的校驗,比如后端加密一個MD5字符串,給前端之后,前端用特定組合加上傳輸數(shù)據(jù)返回一個RSA加密的字符串,后端接收后解密,然后和自身的字符串進行對比,以確認數(shù)據(jù)來源的準確性.
這都是本人的淺淺理解,加密這一塊水深似海,我不過是看到了小小的一點,如果內容有誤歡迎各位大佬指正,謝謝.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市褐澎,隨后出現(xiàn)的幾起案子会钝,更是在濱河造成了極大的恐慌,老刑警劉巖工三,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件顽素,死亡現(xiàn)場離奇詭異咽弦,居然都是意外死亡,警方通過查閱死者的電腦和手機胁出,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來段审,“玉大人全蝶,你說我怎么就攤上這事∷峦鳎” “怎么了抑淫?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長姥闪。 經(jīng)常有香客問我始苇,道長,這世上最難降的妖魔是什么筐喳? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任催式,我火速辦了婚禮,結果婚禮上避归,老公的妹妹穿的比我還像新娘荣月。我一直安慰自己,他們只是感情好梳毙,可當我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布哺窄。 她就那樣靜靜地躺著,像睡著了一般账锹。 火紅的嫁衣襯著肌膚如雪萌业。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天奸柬,我揣著相機與錄音生年,去河邊找鬼。 笑死鸟缕,一個胖子當著我的面吹牛晶框,可吹牛的內容都是我干的。 我是一名探鬼主播懂从,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼授段,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了番甩?” 一聲冷哼從身側響起侵贵,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎缘薛,沒想到半個月后窍育,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體卡睦,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年漱抓,在試婚紗的時候發(fā)現(xiàn)自己被綠了表锻。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡乞娄,死狀恐怖瞬逊,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情仪或,我是刑警寧澤确镊,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布,位于F島的核電站范删,受9級特大地震影響蕾域,放射性物質發(fā)生泄漏。R本人自食惡果不足惜到旦,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一旨巷、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧厢绝,春花似錦契沫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至靶病,卻和暖如春会通,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娄周。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工涕侈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人煤辨。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓裳涛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親众辨。 傳聞我的和親對象是個殘疾皇子端三,可洞房花燭夜當晚...
    茶點故事閱讀 43,627評論 2 350