中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用Java實現RSA非對稱加密算法

發布時間:2021-05-20 12:22:49 來源:億速云 閱讀:267 作者:小新 欄目:開發技術

這篇文章主要介紹如何使用Java實現RSA非對稱加密算法,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

一、非對稱加密

非對稱加密算法是一種密鑰的保密方法。

非對稱加密算法需要兩個密鑰:公開密鑰(publickey:簡稱公鑰)和私有密鑰(privatekey:簡稱私鑰)。公鑰與私鑰是一對,如果用公鑰對數據進行加密,只有用對應的私鑰才能解密。因為加密和解密使用的是兩個不同的密鑰,所以這種算法叫作非對稱加密算法。 非對稱加密算法實現機密信息交換的基本過程是:甲方生成一對密鑰并將公鑰公開,需要向甲方發送信息的其他角色(乙方)使用該密鑰(甲方的公鑰)對機密信息進行加密后再發送給甲方;甲方再用自己私鑰對加密后的信息進行解密。甲方想要回復乙方時正好相反,使用乙方的公鑰對數據進行加密,同理,乙方使用自己的私鑰來進行解密。

另一方面,甲方可以使用自己的私鑰對機密信息進行簽名后再發送給乙方;乙方再用甲方的公鑰對甲方發送回來的數據進行驗簽。

甲方只能用其私鑰解密由其公鑰加密后的任何信息。 非對稱加密算法的保密性比較好,它消除了最終用戶交換密鑰的需要。

非對稱密碼體質的特點:算法強度復雜、安全性依賴于算法與密鑰但是由于其算法復雜,而使得加密解密速度沒有對稱加密解密的速度快。對稱密碼體制中只有一種密鑰,并且是非公開的,如果要解密就得讓對方知道密鑰。所以保證其安全性就是保證密鑰的安全,而非對稱密鑰體制有兩種密鑰,其中一個是公開的,這樣就可以不需要像對稱密碼那樣傳輸對方的密鑰了。這樣安全性就大了很多。

二、RSA算法

簡介:

RSA公開密鑰密碼體質是一種使用不同的加密密鑰與解密密鑰,“由已知加密密鑰推導出解密密鑰在計算上是不可行的”密碼體制 。

在公開密鑰密碼體制中,加密密鑰(即公開密鑰)PK是公開信息,而解密密鑰(即秘密密鑰)SK是需要保密的。加密算法E和解密算法D也都是公開的。雖然解密密鑰SK是由公開密鑰PK決定的,但卻不能根據PK計算出SK 。

正是基于這種理論,1978年出現了著名的RSA算法,它通常是先生成一對RSA密鑰,其中之一是保密密鑰,由用戶保存;另一個為公開密鑰,可對外公開,甚至可在網絡服務器中注冊。為提高保密強度,RSA密鑰至少為500位長,一般推薦使用1024位。這就使加密的計算量很大。為減少計算量,在傳送信息時,常采用傳統加密方法與公開密鑰加密方法相結合的方式,即信息采用改進的DES或IDEA對話密鑰加密,然后使用RSA密鑰加密對話密鑰和信息摘要。對方收到信息后,用不同的密鑰解密并可核對信息摘要 。

RSA是被研究得最廣泛的公鑰算法,從提出到現在已近三十年,經歷了各種攻擊的考驗,逐漸為人們接受,普遍認為是目前最優秀的公鑰方案之一。1983年麻省理工學院在美國為RSA算法申請了專利。

算法原理:

RSA公開密鑰密碼體制的原理是:根據數論,尋求兩個大素數比較簡單,而將它們的乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰 。

算法描述:

(1)任意選取兩個不同的大素數p和q計算乘積

如何使用Java實現RSA非對稱加密算法

(2)任意選取一個大整數e,滿足

如何使用Java實現RSA非對稱加密算法

整數e用做加密鑰(注意:e的選取是很容易的,例如,所有大于p和q的素數都可用)

(3)確定的解密鑰d,滿足

如何使用Java實現RSA非對稱加密算法

如何使用Java實現RSA非對稱加密算法

是一個任意的整數;所以,若知道e和則很容易計算出d

如何使用Java實現RSA非對稱加密算法

(4)公開整數n和e,秘密保存d

(5)將明文m(m<n是一個整數)加密成密文c,加密算法為

如何使用Java實現RSA非對稱加密算法

(6)將密文c解密為明文m,解密算法為

如何使用Java實現RSA非對稱加密算法

RSA允許你選擇公鑰的大小。512位的密鑰被視為不安全的;768位的密鑰不用擔心受到除了國家安全管理(NSA)外的其他事物的危害;1024位的密鑰幾乎是安全的。RSA在一些主要產品內部都有嵌入,像 Windows、網景 Navigator、 Quicken和 Lotus Notes 。

三、RSA算法Java語言實現

RSA算法工具類源碼:

package com.ljt.rsa.util;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
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;

/**
 * @ClassName: RSAUtil
 * @Description:  RSA非對稱加密算法工具類
 * @Author: 寒山月初°C
 * @Date 2021/5/16 17:47
 * @Version 1.0
 */

public class RSAUtil {

    public static final String CHARSET = "UTF-8";
    public static final String RSA_ALGORITHM = "RSA";


    public static Map<String, String> createKeys(int keySize){
        //為RSA算法創建一個KeyPairGenerator對象(KeyPairGenerator,密鑰對生成器,用于生成公鑰和私鑰對)
        KeyPairGenerator kpg;
        try{
            kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
        }catch(NoSuchAlgorithmException e){
            throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
        }

        //初始化KeyPairGenerator對象,密鑰長度
        kpg.initialize(keySize);
        //生成密匙對
        KeyPair keyPair = kpg.generateKeyPair();
        //得到公鑰
        Key publicKey = keyPair.getPublic();
        String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded()); //返回一個publicKey經過二次加密后的字符串
        //得到私鑰
        Key privateKey = keyPair.getPrivate();
        String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded()); 返回一個privateKey經過二次加密后的字符串

        Map<String, String> keyPairMap = new HashMap<String, String>();
        keyPairMap.put("publicKey", publicKeyStr);
        keyPairMap.put("privateKey", privateKeyStr);

        return keyPairMap;
    }

    /**
     * 得到公鑰
     * @param publicKey 密鑰字符串(經過base64編碼)
     * @throws Exception
     */
    public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //通過X509編碼的Key指令獲得公鑰對象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
        RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
        return key;
    }

    /**
     * 得到私鑰
     * @param privateKey 密鑰字符串(經過base64編碼)
     * @throws Exception
     */
    public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        //通過PKCS#8編碼的Key指令獲得私鑰對象
        KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
        PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
        RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
        return key;
    }

    /**
     * 公鑰加密
     * @param data
     * @param publicKey
     * @return
     */
    public static String publicEncrypt(String data, RSAPublicKey publicKey){
        try{
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);
            return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
        }catch(Exception e){
            throw new RuntimeException("加密字符串[" + data + "]時遇到異常", e);
        }
    }

    /**
     * 私鑰解密
     * @param data
     * @param privateKey
     * @return
     */

    public static String privateDecrypt(String data, RSAPrivateKey privateKey){
        try{
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, privateKey);
            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
        }catch(Exception e){
            throw new RuntimeException("解密字符串[" + data + "]時遇到異常", e);
        }
    }

    /**
     * 私鑰加密
     * @param data
     * @param privateKey
     * @return
     */

    public static String privateEncrypt(String data, RSAPrivateKey privateKey){
        try{
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.ENCRYPT_MODE, privateKey);
            return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), privateKey.getModulus().bitLength()));
        }catch(Exception e){
            throw new RuntimeException("加密字符串[" + data + "]時遇到異常", e);
        }
    }

    /**
     * 公鑰解密
     * @param data
     * @param publicKey
     * @return
     */

    public static String publicDecrypt(String data, RSAPublicKey publicKey){
        try{
            Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
            cipher.init(Cipher.DECRYPT_MODE, publicKey);
            return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), publicKey.getModulus().bitLength()), CHARSET);
        }catch(Exception e){
            throw new RuntimeException("解密字符串[" + data + "]時遇到異常", e);
        }
    }

    private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize){
        int maxBlock = 0;
        if(opmode == Cipher.DECRYPT_MODE){
            maxBlock = keySize / 8;
        }else{
            maxBlock = keySize / 8 - 11;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        int offSet = 0;
        byte[] buff;
        int i = 0;
        try{
            while(datas.length > offSet){
                if(datas.length-offSet > maxBlock){
                    buff = cipher.doFinal(datas, offSet, maxBlock);
                }else{
                    buff = cipher.doFinal(datas, offSet, datas.length-offSet);
                }
                out.write(buff, 0, buff.length);
                i++;
                offSet = i * maxBlock;
            }
        }catch(Exception e){
            throw new RuntimeException("加解密閥值為["+maxBlock+"]的數據時發生異常", e);
        }
        byte[] resultDatas = out.toByteArray();
        IOUtils.closeQuietly(out);
        return resultDatas;
    }
}

編寫測試類:

class Test{
    public static void main (String[] args) throws Exception {
        Map<String, String> keyMap = RSAUtil.createKeys(1024);
        String  publicKey = keyMap.get("publicKey");
        String  privateKey = keyMap.get("privateKey");
        System.out.println("公鑰: \n\r" + publicKey);
        System.out.println("私鑰: \n\r" + privateKey);

        System.out.println("公鑰加密——私鑰解密");
        String str = "寒山月初℃";
        System.out.println("\r明文:\r\n" + str);
        System.out.println("\r明文大小:\r\n" + str.getBytes().length);
        String encodedData = RSAUtil.publicEncrypt(str, RSAUtil.getPublicKey(publicKey));
        System.out.println("密文:\r\n" + encodedData);
        String decodedData = RSAUtil.privateDecrypt(encodedData, RSAUtil.getPrivateKey(privateKey));
        System.out.println("解密后文字: \r\n" + decodedData);
    }

}

運行結果:

公鑰:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyrF0HBVsYdA2fTy1iYIWh7j1OoCDzLiBWomWO3Ngn1ajl2wSPk05E7yINxLiTaQSA0H86EWv0jRJrGSdg6kwqzhWv53hza4xEXozLNgDR5L0bxEAmtv1abFALwpMHMPr8NzbpvXHwNaHer6mBrhXDVuyPdgZkWuh0kLrpvXHetQIDAQAB
私鑰:
MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALKsXQcFWxh0DZ9PLWJghaHuPU6gIPMuIFaiZY7c2CfVqOXbBI-TTkTvIg3EuJNpBIDQfzoRa_SNEmsZJ2DqTCrOFa_neHNrjERejMs2ANHkvRvEQCa2_VpsUAvCkwcw-vw3Num9cfA1od6vqYGuFcNW7I92BmRa6HSQuum9cd61AgMBAAECgYA5KNch9d6stgPdoVDdlg9qPHM0ghnIcks6K_3ddF1acQn1btnIrNFvUClOyk5aKlCcfRcWlpg4xiDMTmHAqXPv_H2AQTqqLdhKC6cz0AZDuiv_itO40rqmvi9n0lcJWP0zq3cJyNlE8ogNsb9heHn_XdPIxD4tdl3QztZQHBfOgQJBAObDr9SBD0EsiGCeULMEj-hEOHsMh0NANpHvNdzKj9xNb28fAZ4H8reRG5frUqpCSTkxgigBwsMhYeQu_ebNoAUCQQDGNl8iVw219K0e3Awwd7TUmM8Ugt8intD1rbYObsYDZlss6rzsm0XzUgkJE9X6xcdu_O5jWZ49mgC3i-jg7HLxAkBZ9h383VdiFAdSi0VwlK25YacXKUouCIF9oODBo2I0AygXDOJnhje0Imi8b-v5HgBHwKo6CH2x7nioKT2oVa81AkByl8KedtfNZ1yjJ7LAXqSj-IhYImVgfZLvRnOnmnFOS-HQcRGydP6W8smYfuhJ6Agp6X7k30317VAWzYNgbjLxAkEAvOYGU33Ll871QFzWTW8eHg1SJMP4oTL3jKuQi5lVMrZTWoCQF_wvuHKAKgIs0AzFwh6vrkNN1fv5QASzwtIGzg
公鑰加密——私鑰解密
明文:
寒山月初℃
明文大小:
15
密文:
pnQYCefqnlYLZ2wuMcxsbkD9feA3WFcDXShYx6HajvlsriQGWzb4Xxdwz0KTzjz3nqho9AxUc2bZmBhq05v-DCyB14u2NyabENuMXoiKft4QGKNVG3WxGps55xRHr3lVt4Rj59mDBX_manNsQDwxj7gy_Brv6Uv_NRzd6M91aGk
解密后文字:
寒山月初℃                                                                                                                                                                                      Process finished with exit code 0

常用的java框架有哪些

1.SpringMVC,Spring Web MVC是一種基于Java的實現了Web MVC設計模式的請求驅動類型的輕量級Web框架。2.Shiro,Apache Shiro是Java的一個安全框架。3.Mybatis,MyBatis 是支持普通 SQL查詢,存儲過程和高級映射的優秀持久層框架。4.Dubbo,Dubbo是一個分布式服務框架。5.Maven,Maven是個項目管理和構建自動化工具。6.RabbitMQ,RabbitMQ是用Erlang實現的一個高并發高可靠AMQP消息隊列服務器。7.Ehcache,EhCache 是一個純Java的進程內緩存框架。

以上是“如何使用Java實現RSA非對稱加密算法”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

剑川县| 祁门县| 东乌珠穆沁旗| 嘉义县| 寿阳县| 浪卡子县| 梁平县| 沈阳市| 绍兴市| 乾安县| 墨竹工卡县| 凤凰县| 鸡泽县| 郧西县| 普安县| 云林县| 和顺县| 巴林左旗| 聊城市| 射洪县| 柳江县| 牟定县| 安宁市| 万山特区| 东源县| 监利县| 信丰县| 正定县| 巴里| 乾安县| 墨竹工卡县| 山阳县| 古丈县| 化德县| 获嘉县| 丰县| 龙门县| 新源县| 罗源县| 东明县| 宁强县|