java實(shí)現(xiàn)的RSA加密算法詳解
本文實(shí)例講述了java實(shí)現(xiàn)的RSA加密算法。分享給大家供大家參考,具體如下:
一、什么是非對稱加密
1、加密的密鑰與加密的密鑰不相同,這樣的加密算法稱之為非對稱加密
2、密鑰分為:公鑰,私鑰
公鑰:可以對外給任何人的加密和解密的密碼,是公開的
私鑰:通過私鑰可以生成公鑰,但從公鑰被認(rèn)為無法生成公鑰(被推導(dǎo)出的概率小到不考慮)
3、當(dāng)將要加密的內(nèi)容用公鑰加密的時(shí)候,只能用私鑰來解密
當(dāng)將要加密的內(nèi)容用私鑰加密的時(shí)候,只能用公鑰來解密
4、公鑰與私鑰的關(guān)系,利用一個(gè)簡單的公式來生成公鑰和私鑰,即非對稱加密的公鑰和私鑰之間存在某一個(gè)公式關(guān)系
5、常見的非對稱加密算法
RSA,DSA
二、什么是RSA算法
RSA算法是一種非對稱密碼算法,所謂非對稱,就是指該算法需要一對密鑰,使用其中一個(gè)加密,則需要用另一個(gè)才能解密。
RSA的算法涉及三個(gè)參數(shù),n、e1、e2。
其中,n是兩個(gè)大質(zhì)數(shù)p、q的積,n的二進(jìn)制表示時(shí)所占用的位數(shù),就是所謂的密鑰長度。
e1和e2是一對相關(guān)的值,e1可以任意取,但要求e1與(p-1)*(q-1)互質(zhì);再選擇e2,要求(e2*e1)mod((p-1)*(q-1))=1。
(n,e1),(n,e2)就是密鑰對。其中(n,e1)為公鑰,(n,e2)為私鑰。
RSA加解密的算法完全相同,設(shè)A為明文,B為密文,則:A=B^e2 mod n;B=A^e1 mod n;(公鑰加密體制中,一般用公鑰加密,私鑰解密)
e1和e2可以互換使用,即:
A=B^e1 mod n;B=A^e2 mod n;
三、RSA加密算法的使用
1、RSA密鑰的生成,返回一個(gè)KeyPair對象
KeyPair 用于非對稱加密,KeyPair中包含了一個(gè)公鑰和一個(gè)私鑰
/** * 通過指定的密鑰長度生成非對稱的密鑰對 * @param keySize 推薦使用1024,2048 ,不允許低于1024 * @return */ public static KeyPair generateRSAKeyPair(int keySize){ KeyPair ret = null; try { //1、準(zhǔn)備生成 KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); //2、初始化,設(shè)置秘鑰長度 generator.initialize(keySize); //3、生成,并且返回 ret = generator.generateKeyPair(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ret; }
2、獲取私鑰和公鑰
PublicKey 和 PrivateKey 都是Key類型的
KeyPair keyPair = EncryptUtil.generateRSAKeyPair(1024); //獲取公鑰,可以給任何人 PublicKey publicKey = keyPair.getPublic(); //獲取私鑰 PrivateKey privateKey = keyPair.getPrivate();
3、RSA加密
/** * RSA 加密 * @param data 需要加密的數(shù)據(jù) * @param key 可以是 PublicKey,也可以是PrivateKey * @return */ public static byte[] rsaEncrypt(byte[] data ,Key key){ byte[] ret = null; if (data != null && data.length>0 && key!=null) { // 1、創(chuàng)建Cipher 使用RSA try { Cipher cipher = Cipher.getInstance("RSA"); //設(shè)置Key cipher.init(Cipher.ENCRYPT_MODE,key); ret = cipher.doFinal(data); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } } return ret; }
4、RSA解密
/** * RSA 解密 * @param data 要解密的數(shù)據(jù) * @param key 可以是 PublicKey,也可以是PrivateKey * @return */ public static byte[] rsaDecrypt(byte[] data ,Key key){ byte[] ret = null; if (data != null && data.length>0 && key!=null) { // 1、創(chuàng)建Cipher 使用RSA try { Cipher cipher = Cipher.getInstance("RSA"); //設(shè)置Key cipher.init(Cipher.DECRYPT_MODE,key); ret = cipher.doFinal(data); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (NoSuchPaddingException e) { e.printStackTrace(); } catch (InvalidKeyException e) { e.printStackTrace(); } catch (BadPaddingException e) { e.printStackTrace(); } catch (IllegalBlockSizeException e) { e.printStackTrace(); } } return ret; }
5、公鑰與私鑰的存儲
一對公鑰和私鑰創(chuàng)建好之后,我們需要存儲起來以后使用
//獲得公鑰 私鑰 PrivateKey privateKey = keyPair.getPrivate(); PublicKey publicKey = keyPair.getPublic(); //編碼將PublicKey和PrivateKey對象轉(zhuǎn)換為字節(jié)數(shù)組,該字節(jié)數(shù)組為公鑰、私鑰的實(shí)際數(shù)據(jù) byte[] publicKeyEncoded = publicKey.getEncoded(); byte[] privateKeyEncoded = privateKey.getEncoded(); //將字節(jié)數(shù)組通過Base64編碼算法 編碼成可見的字符形式 String publickey = Base64.encodeToString(publicKeyEncoded, Base64.NO_WRAP); String privatekey = Base64.encodeToString(privateKeyEncoded, Base64.NO_WRAP); //進(jìn)行存儲操作 。。。。
6、公鑰與私鑰的加載
通常 1、獲取密鑰對 2、獲取公鑰、私鑰 3、保存公鑰、私鑰,保存形式基本為字符串形式
那么在以后的使用中就需要獲取公鑰和私鑰來使用
需要知道:
6.1、KeyFactory可以來加載相應(yīng)的公鑰和私鑰
6.2、公鑰加載 使用 X509EncodedKeySpec(byte[])
6.3、私鑰加載 使用 PCKS8EncodedKeySpec(byte[])
//獲取公鑰 //str_publickey 為公鑰字符串形式數(shù)據(jù)(公鑰先編碼成byte[] 在 形成字符串) //解碼 byte[] publicdecode = Base64.decode(new String(str_publickey), Base64.NO_WRAP); //構(gòu)造X509EncodedKeySpec對象 X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicdecode); //指定加密算法 KeyFactory keyFactory = KeyFactory.getInstance("RSA"); //取得公鑰 PublicKey publicKey = keyFactory.generatePublic(publicKeySpec); //解碼 //獲取私鑰 //str_private 為私鑰字符串形式的數(shù)據(jù) byte[] privatedecode = Base64.decode(new String(str_private), Base64.NO_WRAP); //構(gòu)造X509EncodedKeySpec對象 PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privatedecode); //指定加密算法 keyFactory = KeyFactory.getInstance("RSA"); //取得私鑰 PrivateKey privateKey = keyFactory.generatePrivate(privateKeySpec);
PS:關(guān)于加密解密感興趣的朋友還可以參考本站在線工具:
MD5在線加密工具:
http://tools.jb51.net/password/CreateMD5Password
迅雷、快車、旋風(fēng)URL加密/解密工具:
http://tools.jb51.net/password/urlrethunder
在線散列/哈希算法加密工具:
http://tools.jb51.net/password/hash_encrypt
在線MD5/hash/SHA-1/SHA-2/SHA-256/SHA-512/SHA-3/RIPEMD-160加密工具:
http://tools.jb51.net/password/hash_md5_sha
在線sha1/sha224/sha256/sha384/sha512加密工具:
http://tools.jb51.net/password/sha_encode
更多關(guān)于java相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Java數(shù)學(xué)運(yùn)算技巧總結(jié)》、《Java數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Java字符與字符串操作技巧總結(jié)》、《java日期與時(shí)間操作技巧匯總》、《Java操作DOM節(jié)點(diǎn)技巧總結(jié)》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設(shè)計(jì)有所幫助。
相關(guān)文章
gateway網(wǎng)關(guān)接口請求的校驗(yàn)方式
這篇文章主要介紹了gateway網(wǎng)關(guān)接口請求的校驗(yàn)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07SpringBoot中攔截器和動態(tài)代理的區(qū)別詳解
在?Spring?Boot?中,攔截器和動態(tài)代理都是用來實(shí)現(xiàn)功能增強(qiáng)的,所以在很多時(shí)候,有人會認(rèn)為攔截器的底層是通過動態(tài)代理實(shí)現(xiàn)的,所以本文就來盤點(diǎn)一下他們兩的區(qū)別,以及攔截器的底層實(shí)現(xiàn)吧2023-09-09簡單了解JAVA SimpleDateFormat yyyy和YYYY的區(qū)別
這篇文章主要介紹了簡單了解JAVA SimpleDateFormat yyyy和YYYY的區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Java中Date類和Calendar類的常用實(shí)例小結(jié)
這篇文章主要介紹了Java中Date類和Calendar類的常用實(shí)例小結(jié),是Java入門學(xué)習(xí)中的基礎(chǔ)知識的運(yùn)用,需要的朋友可以參考下2015-08-08Java 利用dom方式讀取、創(chuàng)建xml詳解及實(shí)例代碼
這篇文章主要介紹了Java 利用dom方式讀取、創(chuàng)建xml的相關(guān)資料,需要的朋友可以參考下2017-03-03SpringBoot使用@valid進(jìn)行參數(shù)校驗(yàn)的流程步驟
SpringBoot 提供了一種方便的方式來進(jìn)行參數(shù)校驗(yàn):使用 Hibernate Validator,Spring Boot 提供了一種方便的方式來進(jìn)行參數(shù)校驗(yàn):使用 Hibernate Validator,所以本文給大家介紹了SpringBoot使用@valid進(jìn)行參數(shù)校驗(yàn)的流程步驟,需要的朋友可以參考下2023-09-09