非對稱加密需要兩個密鑰:公鑰(publickey) 和私鑰 (privatekey)。公鑰和私鑰是一對,如果用公鑰對數據加密,那麼只能用對應的私鑰解密。如果用私鑰對數據加密,只能用對應的公鑰進行解密。因為加密和解密用的是不同的密鑰,所以稱為非對稱加密。
非對稱加密演算法的保密性好,它消除了最終用戶交換密鑰的需要。但是加解密速度要遠遠慢於對稱加密,在某些極端情況下,甚至能比對稱加密慢上1000倍。
演算法強度復雜、安全性依賴於演算法與密鑰但是由於其演算法復雜,而使得加密解密速度沒有對稱加密解密的速度快。對稱密碼體制中只有一種密鑰,並且是非公開的,如果要解密就得讓對方知道密鑰。所以保證其安全性就是保證密鑰的安全,而非對稱密鑰體制有兩種密鑰,其中一個是公開的,這樣就可以不需要像對稱密碼那樣傳輸對方的密鑰了。這樣安全性就大了很多。
RSA、Elgamal、背包演算法、Rabin、D-H、ECC (橢圓曲線加密演算法)。使用最廣泛的是 RSA 演算法,Elgamal 是另一種常用的非對稱加密演算法。
收信者是唯一能夠解開加密信息的人,因此收信者手裡的必須是私鑰。發信者手裡的是公鑰,其它人知道公鑰沒有關系,因為其它人發來的信息對收信者沒有意義。
客戶端需要將認證標識傳送給伺服器,此認證標識 (可能是一個隨機數) 其它客戶端可以知道,因此需要用私鑰加密,客戶端保存的是私鑰。伺服器端保存的是公鑰,其它伺服器知道公鑰沒有關系,因為客戶端不需要登錄其它伺服器。
數字簽名是為了表明信息沒有受到偽造,確實是信息擁有者發出來的,附在信息原文的後面。就像手寫的簽名一樣,具有不可抵賴性和簡潔性。
簡潔性:對信息原文做哈希運算,得到消息摘要,信息越短加密的耗時越少。
不可抵賴性:信息擁有者要保證簽名的唯一性,必須是唯一能夠加密消息摘要的人,因此必須用私鑰加密 (就像字跡他人無法學會一樣),得到簽名。如果用公鑰,那每個人都可以偽造簽名了。
問題起源:對1和3,發信者怎麼知道從網上獲取的公鑰就是真的?沒有遭受中間人攻擊?
這樣就需要第三方機構來保證公鑰的合法性,這個第三方機構就是 CA (Certificate Authority),證書中心。
CA 用自己的私鑰對信息原文所有者發布的公鑰和相關信息進行加密,得出的內容就是數字證書。
信息原文的所有者以後發布信息時,除了帶上自己的簽名,還帶上數字證書,就可以保證信息不被篡改了。信息的接收者先用 CA給的公鑰解出信息所有者的公鑰,這樣可以保證信息所有者的公鑰是真正的公鑰,然後就能通過該公鑰證明數字簽名是否真實了。
RSA 是目前最有影響力的公鑰加密演算法,該演算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密密鑰,即公鑰,而兩個大素數組合成私鑰。公鑰是可發布的供任何人使用,私鑰則為自己所有,供解密之用。
A 要把信息發給 B 為例,確定角色:A 為加密者,B 為解密者。首先由 B 隨機確定一個 KEY,稱之為私鑰,將這個 KEY 始終保存在機器 B 中而不發出來;然後,由這個 KEY 計算出另一個 KEY,稱之為公鑰。這個公鑰的特性是幾乎不可能通過它自身計算出生成它的私鑰。接下來通過網路把這個公鑰傳給 A,A 收到公鑰後,利用公鑰對信息加密,並把密文通過網路發送到 B,最後 B 利用已知的私鑰,就能對密文進行解碼了。以上就是 RSA 演算法的工作流程。
由於進行的都是大數計算,使得 RSA 最快的情況也比 DES 慢上好幾倍,無論是軟體還是硬體實現。速度一直是 RSA 的缺陷。一般來說只用於少量數據加密。RSA 的速度是對應同樣安全級別的對稱密碼演算法的1/1000左右。
比起 DES 和其它對稱演算法來說,RSA 要慢得多。實際上一般使用一種對稱演算法來加密信息,然後用 RSA 來加密比較短的公鑰,然後將用 RSA 加密的公鑰和用對稱演算法加密的消息發送給接收方。
這樣一來對隨機數的要求就更高了,尤其對產生對稱密碼的要求非常高,否則的話可以越過 RSA 來直接攻擊對稱密碼。
和其它加密過程一樣,對 RSA 來說分配公鑰的過程是非常重要的。分配公鑰的過程必須能夠抵擋中間人攻擊。假設 A 交給 B 一個公鑰,並使 B 相信這是A 的公鑰,並且 C 可以截下 A 和 B 之間的信息傳遞,那麼 C 可以將自己的公鑰傳給 B,B 以為這是 A 的公鑰。C 可以將所有 B 傳遞給 A 的消息截下來,將這個消息用自己的密鑰解密,讀這個消息,然後將這個消息再用 A 的公鑰加密後傳給 A。理論上 A 和 B 都不會發現 C 在偷聽它們的消息,今天人們一般用數字認證來防止這樣的攻擊。
(1) 針對 RSA 最流行的攻擊一般是基於大數因數分解。1999年,RSA-155 (512 bits) 被成功分解,花了五個月時間(約8000 MIPS 年)和224 CPU hours 在一台有3.2G 中央內存的 Cray C916計算機上完成。
RSA-158 表示如下:
2009年12月12日,編號為 RSA-768 (768 bits, 232 digits) 數也被成功分解。這一事件威脅了現通行的1024-bit 密鑰的安全性,普遍認為用戶應盡快升級到2048-bit 或以上。
RSA-768表示如下:
(2) 秀爾演算法
量子計算里的秀爾演算法能使窮舉的效率大大的提高。由於 RSA 演算法是基於大數分解 (無法抵抗窮舉攻擊),因此在未來量子計算能對 RSA 演算法構成較大的威脅。一個擁有 N 量子位的量子計算機,每次可進行2^N 次運算,理論上講,密鑰為1024位長的 RSA 演算法,用一台512量子比特位的量子計算機在1秒內即可破解。
DSA (Digital Signature Algorithm) 是 Schnorr 和 ElGamal 簽名演算法的變種,被美國 NIST 作為 DSS (DigitalSignature Standard)。 DSA 是基於整數有限域離散對數難題的。
簡單的說,這是一種更高級的驗證方式,用作數字簽名。不單單只有公鑰、私鑰,還有數字簽名。私鑰加密生成數字簽名,公鑰驗證數據及簽名,如果數據和簽名不匹配則認為驗證失敗。數字簽名的作用就是校驗數據在傳輸過程中不被修改,數字簽名,是單向加密的升級。
橢圓加密演算法(ECC)是一種公鑰加密演算法,最初由 Koblitz 和 Miller 兩人於1985年提出,其數學基礎是利用橢圓曲線上的有理點構成 Abel 加法群上橢圓離散對數的計算困難性。公鑰密碼體制根據其所依據的難題一般分為三類:大整數分解問題類、離散對數問題類、橢圓曲線類。有時也把橢圓曲線類歸為離散對數類。
ECC 的主要優勢是在某些情況下它比其他的方法使用更小的密鑰 (比如 RSA),提供相當的或更高等級的安全。ECC 的另一個優勢是可以定義群之間的雙線性映射,基於 Weil 對或是 Tate 對;雙線性映射已經在密碼學中發現了大量的應用,例如基於身份的加密。不過一個缺點是加密和解密操作的實現比其他機制花費的時間長。
ECC 被廣泛認為是在給定密鑰長度的情況下,最強大的非對稱演算法,因此在對帶寬要求十分緊的連接中會十分有用。
比特幣錢包公鑰的生成使用了橢圓曲線演算法,通過橢圓曲線乘法可以從私鑰計算得到公鑰, 這是不可逆轉的過程。
https://github.com/esxgx/easy-ecc
java 中 Chipher、Signature、KeyPairGenerator、KeyAgreement、SecretKey 均不支持 ECC 演算法。
https://www.jianshu.com/p/58c1750c6f22
DH,全稱為"Diffie-Hellman",它是一種確保共享 KEY 安全穿越不安全網路的方法,也就是常說的密鑰一致協議。由公開密鑰密碼體制的奠基人 Diffie 和 Hellman 所提出的一種思想。簡單的說就是允許兩名用戶在公開媒體上交換信息以生成"一致"的、可以共享的密鑰。也就是由甲方產出一對密鑰 (公鑰、私鑰),乙方依照甲方公鑰產生乙方密鑰對 (公鑰、私鑰)。
以此為基線,作為數據傳輸保密基礎,同時雙方使用同一種對稱加密演算法構建本地密鑰 (SecretKey) 對數據加密。這樣,在互通了本地密鑰 (SecretKey) 演算法後,甲乙雙方公開自己的公鑰,使用對方的公鑰和剛才產生的私鑰加密數據,同時可以使用對方的公鑰和自己的私鑰對數據解密。不單單是甲乙雙方兩方,可以擴展為多方共享數據通訊,這樣就完成了網路交互數據的安全通訊。
具體例子可以移步到這篇文章: 非對稱密碼之DH密鑰交換演算法
參考:
https://blog.csdn.net/u014294681/article/details/86705999
https://www.cnblogs.com/wangzxblog/p/13667634.html
https://www.cnblogs.com/taoxw/p/15837729.html
https://www.cnblogs.com/fangfan/p/4086662.html
https://www.cnblogs.com/utank/p/7877761.html
https://blog.csdn.net/m0_59133441/article/details/122686815
https://www.cnblogs.com/muliu/p/10875633.html
https://www.cnblogs.com/wf-zhang/p/14923279.html
https://www.jianshu.com/p/7a927db713e4
https://blog.csdn.net/ljx1400052550/article/details/79587133
https://blog.csdn.net/yuanjian0814/article/details/109815473
㈡ JAVA 公鑰與私鑰的問題
這個公鑰和私鑰如果是非對稱加密的演算法,那麼用公鑰加密的話,就需要用私鑰才能解密了。如果是對稱加密的話,就用加密的公鑰就可以解密了。
SSL加密通信的過程一般都是首先雙方確認大家支持的加密方式,然後採用一種大家都支持的,然後的話,就先用非對稱加密將公鑰加密然後發給client,然後client解密獲得公鑰。之後的話,大家就可以用公鑰進行對稱加密了。
㈢ java非對稱加密的源代碼(RSA)
鑒於rsa加密的重要性和相關源代碼的匱乏 經過整理特此貼出 需要下載bcprov jdk jar import javax crypto Cipher;import java security *;import java security spec RSAPublicKeySpec;清納import java security spec RSAPrivateKeySpec;import java security spec InvalidKeySpecException;import java security interfaces RSAPrivateKey;import java security interfaces RSAPublicKey;import java io *;import java math BigInteger;/*** RSA 工具類 提供加密 解密 生成密鑰對等方法 * 需要到下載bcprov jdk jar **/public class RSAUtil {/*** 生成密鑰對* @return KeyPair* @throws EncryptException*/public static KeyPair generateKeyPair() throws EncryptException {try {槐碼KeyPairGenerator keyPairGen = KeyPairGenerator getInstance( RSA new bouncycastle jce provider BouncyCastleProvider());final int KEY_SIZE = ;//沒什麼好說的了 這個值關繫到塊加密的大小 可以更改 但是不要太大 否則效率會低keyPairGen initialize(KEY_SIZE new SecureRandom());KeyPair keyPair = keyPairGen genKeyPair();return keyPair;} catch (Exception e) {throw new EncryptException(e getMessage());}}/*** 生成公鑰* @param molus* @param publicExponent* @return RSAPublicKey* @throws EncryptException*/public static RSAPublicKey generateRSAPublicKey(byte[] molus byte[] publicExponent) throws EncryptException {KeyFactory keyFac = null;try {keyFac = KeyFactory getInstance( RSA new bouncycastle jce provider BouncyCastleProvider());} catch (NoSuchAlgorithmException ex) {throw new EncryptException(ex getMessage());}RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(molus) new BigInteger(publicExponent));try {return (RSAPublicKey) keyFac generatePublic(pubKeySpec);} catch (InvalidKeySpecException ex) {throw new EncryptException(ex getMessage());}}/*** 生成私鑰* @param molus鉛正哪* @param privateExponent* @return RSAPrivateKey* @throws EncryptException*/public static RSAPrivateKey generateRSAPrivateKey(byte[] molus byte[] privateExponent) throws EncryptException {KeyFactory keyFac = null;try {keyFac = KeyFactory getInstance( RSA new bouncycastle jce provider BouncyCastleProvider());} catch (NoSuchAlgorithmException ex) {throw new EncryptException(ex getMessage());}RSAPrivateKeySpec priKeySpec = new RSAPrivateKeySpec(new BigInteger(molus) new BigInteger(privateExponent));try {return (RSAPrivateKey) keyFac generatePrivate(priKeySpec);} catch (InvalidKeySpecException ex) {throw new EncryptException(ex getMessage());}}/*** 加密* @param key 加密的密鑰* @param data 待加密的明文數據* @return 加密後的數據* @throws EncryptException*/public static byte[] encrypt(Key key byte[] data) throws EncryptException {try {Cipher cipher = Cipher getInstance( RSA new bouncycastle jce provider BouncyCastleProvider());cipher init(Cipher ENCRYPT_MODE key);int blockSize = cipher getBlockSize();//獲得加密塊大小 如 加密前數據為 個byte 而key_size= 加密塊大小為 byte 加密後為 個byte;因此共有 個加密塊 第一個 byte第二個為 個byteint outputSize = cipher getOutputSize(data length);//獲得加密塊加密後塊大小int leavedSize = data length % blockSize;int blocksSize = leavedSize != ? data length / blockSize + : data length / blockSize;byte[] raw = new byte[outputSize * blocksSize];int i = ;while (data length i * blockSize > ) {if (data length i * blockSize > blockSize)cipher doFinal(data i * blockSize blockSize raw i * outputSize);elsecipher doFinal(data i * blockSize data length i * blockSize raw i * outputSize);//這裡面doUpdate方法不可用 查看源代碼後發現每次doUpdate後並沒有什麼實際動作除了把byte[]放到ByteArrayOutputStream中 而最後doFinal的時候才將所有的byte[]進行加密 可是到了此時加密塊大小很可能已經超出了OutputSize所以只好用dofinal方法 i++;}return raw;} catch (Exception e) {throw new EncryptException(e getMessage());}}/*** 解密* @param key 解密的密鑰* @param raw 已經加密的數據* @return 解密後的明文* @throws EncryptException*/public static byte[] decrypt(Key key byte[] raw) throws EncryptException {try {Cipher cipher = Cipher getInstance( RSA new bouncycastle jce provider BouncyCastleProvider());cipher init(cipher DECRYPT_MODE key);int blockSize = cipher getBlockSize();ByteArrayOutputStream bout = new ByteArrayOutputStream( );int j = ;while (raw length j * blockSize > ) {bout write(cipher doFinal(raw j * blockSize blockSize));j++;}return bout toByteArray();} catch (Exception e) {throw new EncryptException(e getMessage());}}/**** @param args* @throws Exception*/public static void main(String[] args) throws Exception {File file = new File( l );FileInputStream in = new FileInputStream(file);ByteArrayOutputStream bout = new ByteArrayOutputStream();byte[] tmpbuf = new byte[ ];int count = ;while ((count = in read(tmpbuf)) != ) {bout write(tmpbuf count);tmpbuf = new byte[ ];}in close();byte[] Data = bout toByteArray();KeyPair keyPair = RSAUtil generateKeyPair();RSAPublicKey pubKey = (RSAPublicKey) keyPair getPublic();RSAPrivateKey priKey = (RSAPrivateKey) keyPair getPrivate();byte[] pubModBytes = pubKey getMolus() toByteArray();byte[] pubPubExpBytes = pubKey getPublicExponent() toByteArray();byte[] priModBytes = priKey getMolus() toByteArray();byte[] priPriExpBytes = priKey getPrivateExponent() toByteArray();RSAPublicKey recoveryPubKey = RSAUtil generateRSAPublicKey(pubModBytes pubPubExpBytes);RSAPrivateKey recoveryPriKey = RSAUtil generateRSAPrivateKey(priModBytes priPriExpBytes);byte[] raw = RSAUtil encrypt(priKey Data);file = new File( encrypt_result dat );OutputStream out = new FileOutputStream(file);out write(raw);out close();byte[] data = RSAUtil decrypt(recoveryPubKey raw);file = new File( l );out = new FileOutputStream(file);out write(data);out flush();out close();}}加密可以用公鑰 解密用私鑰 或者加密用私鑰 通常非對稱加密是非常消耗資源的 因此可以對大數據用對稱加密如 des(具體代碼可以看我以前發的貼子) 而對其對稱密鑰進行非對稱加密 這樣既保證了數據的安全 還能保證效率 lishixin/Article/program/Java/gj/201311/27391
㈣ a與b通信加密時用的密鑰是什麼
這個都是自己設定的。
A和B進行加密通信時,B首先要生成一對密鑰。一個是公鑰,給A,B自己持有私鑰。A使用B的公鑰加密要加密發送的內容,然後B在通過自己的私鑰解密內容。
這個是JAVA的非對稱性加密演算法,Java是一門面向對象的編程語言,不僅吸收了C++語言的各種優點,還摒棄了C++里難以理解的多繼承、指針等概念,因此Java語言具有功能強大和簡單易用兩個特徵。
㈤ 快速了解常用的對稱加密演算法,再也不用擔心面試官的刨根問底
加密演算法通常被分為兩種: 對稱加密 和 非對稱加密 。其中,對稱加密演算法在加密和解密時使用的密鑰相同;非對稱加密演算法在加密和解密時使用的密鑰不同,分為公鑰和私鑰。此外,還有一類叫做 消息摘要演算法 ,是對數據進行摘要並且不可逆的演算法。
這次我們了解一下對稱加密演算法。
對稱加密演算法在加密和解密時使用的密鑰相同,或是使用兩個可以簡單地相互推算的密鑰。在大多數的對稱加密演算法中,加密和解密的密鑰是相同的。
它要求雙方在安全通信之前,商定一個密鑰。對稱演算法的安全性依賴於密鑰,泄漏密鑰就意味著任何人都可以對他們發送的信息進行解密,這也是對稱加密演算法的主要缺點之一。
常見的對稱加密演算法有:DES演算法、3DES演算法、AES演算法。
DES演算法(Data Encryption Standard)是一種常見的分組加密演算法。
分組加密演算法是將明文分成固定長度的組,每一組都採用同一密鑰和演算法進行加密,輸出也是固定長度的密文。
由IBM公司在1972年研製,1976年被美國聯邦政府的國家標准局確定為聯邦資料處理標准(FIPS),隨後在國際上廣泛流傳開來。
在DES演算法中,密鑰固定長度為64位。明文按64位進行分組,分組後的明文組和密鑰按位置換或交換的方法形成密文組,然後再把密文組拼裝成密文。
密鑰的每個第八位設置為奇偶校驗位,也就是第8、16、24、32、40、48、56、64位,所以密鑰的實際參與加密的長度為56位。
我們用Java寫個例子:
運行結果如下:
DES現在已經不是一種安全的加密方法,主要因為它使用的密鑰過短,很容易被暴力破解。
3DES演算法(Triple Data Encryption Algorithm)是DES演算法的升級版本,相當於是對明文進行了三次DES加密。
由於計算機運算能力的增強,DES演算法由於密鑰長度過低容易被暴力破解;3DES演算法提供了一種相對簡單的方法,即通過增加DES的密鑰長度來避免類似的攻擊,而不是設計一種全新的塊密碼演算法。
在DES演算法中,密鑰固定長度為192位。在加密和解密時,密鑰會被分為3個64位的密鑰。
加密過程如下:
解密過程如下:
我們用Java寫個例子:
運行結果如下:
雖然3DES演算法在安全性上有所提升,但是因為使用了3次DES演算法,加密和解密速度比較慢。
AES(Advanced Encryption Standard,高級加密標准)主要是為了取代DES加密演算法的,雖然出現了3DES的加密方法,但由於它的加密時間是DES演算法的3倍多,密鑰位數還是不能滿足對安全性的要求。
1997年1月2號,美國國家標准與技術研究院(NIST)宣布希望徵集高級加密標准,用以取代DES。全世界很多密碼工作者都提交了自己設計的演算法。經過甄選流程,高級加密標准由美國國家標准與技術研究院於2001年11月26日發布於FIPS PUB 197,並在2002年5月26日成為有效的標准。
該演算法為比利時密碼學家Joan Daemen和Vincent Rijmen所設計,結合兩位作者的名字,以 Rijndael 為名投稿高級加密標準的甄選流程。
AES演算法的密鑰長度是固定,密鑰的長度可以使用128位、192位或256位。
AES演算法也是一種分組加密演算法,其分組長度只能是128位。分組後的明文組和密鑰使用幾種不同的方法來執行排列和置換運算形成密文組,然後再把密文組拼裝成密文。
我們用Java寫個例子:
運行結果如下:
AES演算法是目前應用最廣泛的對稱加密演算法。
對稱加密演算法在加密和解密時使用的密鑰相同,常見的對稱加密演算法有:DES演算法、3DES演算法、AES演算法。
由於安全性低、加密解密效率低,DES演算法和3DES演算法是不推薦使用的,AES演算法是目前應用最廣泛的對稱加密演算法。
㈥ java 非對稱加密演算法有哪些
1、初始化密鑰 構建密鑰對,生成公鑰、私鑰保存到keymap中
KeyPairGenerator ---> KeyPair --> RSAPublicKey、RSAPrivateKey
2、甲方使用私鑰加密, 加密後在用私鑰對加密數據進行數據簽名,然後發送給乙方
RSACoder.encryptByPrivateKey(data, privateKey);
RSACoder.sign(encodedData, privateKey);
3、乙方則通過公鑰驗證簽名的加密數據,如果驗證正確則在通過公鑰對加密數據進行解密
RSACoder.verify(encodedData, publicKey, sign);
RSACoder.decryptByPublicKey(encodedData, publicKey);
4、乙方在通過公鑰加密發送給甲方
RSACoder.encryptByPublicKey(decodedData, publicKey);
5、甲方通過私鑰解密該數據
RSACoder.decryptPrivateKey(encodedData, privateKey);
㈦ java的MD5withRSA演算法可以看到解密的內容么
您好,
<一>. MD5加密演算法:
? ? ? ?消息摘要演算法第五版(Message Digest Algorithm),是一種單向加密演算法,只能加密、無法解密。然而MD5加密演算法已經被中國山東大學王小雲教授成功破譯,但是在安全性要求不高的場景下,MD5加密演算法仍然具有應用價值。
?1. 創建md5對象:?
<pre name="code" class="java">MessageDigest md5 = MessageDigest.getInstance("md5");
?2. ?進行加密操作:歲宏?
byte[] cipherData = md5.digest(plainText.getBytes());
?3. ?將其中的每個位元組轉成十六進制字元串:byte類型的數據最高位是符號位,通過和0xff進行與操作,轉換為int類型的正整數。?
String toHexStr = Integer.toHexString(cipher & 0xff);
?4. 如果該正數小於16(長度為1個字元),前面拼接0佔位:確保最後生成的是32位字元串。?
builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);
?5.?加密轉換之後的字元串為:?
?6. 完整的MD5演算法應用如下所示:?
/**
* 功能簡述: 測試MD5單向加密.
* @throws Exception
*/
@Test
public void test01() throws Exception {
String plainText = "Hello , world !"乎派冊;
MessageDigest md5 = MessageDigest.getInstance("md5");
byte[] cipherData = md5.digest(plainText.getBytes());
StringBuilder builder = new StringBuilder();
for(byte cipher : cipherData) {
String toHexStr = Integer.toHexString(cipher & 0xff);
builder.append(toHexStr.length() == 1 ? "0" + toHexStr : toHexStr);
}
System.out.println(builder.toString());
//
}
??
<二>. 使用BASE64進行加密/解密:
? ? ? ? 使用BASE64演算法通常用作對二進制數據進行加密,加密之後的數據不易被肉眼識別。嚴格來說,經過BASE64加密的數據其實沒有安全性可言,因為它的加密解密演算法都是公開的,典型的防菜鳥不防程序羨逗猿的呀。?經過標準的BASE64演算法加密後的數據,?通常包含/、+、=等特殊符號,不適合作為url參數傳遞,幸運的是Apache的Commons Codec模塊提供了對BASE64的進一步封裝。? (參見最後一部分的說明)
?1.?使用BASE64加密:?
BASE64Encoder encoder = new BASE64Encoder();
String cipherText = encoder.encode(plainText.getBytes());
? 2.?使用BASE64解密:?
BASE64Decoder decoder = new BASE64Decoder();
plainText = new String(decoder.decodeBuffer(cipherText));
? 3. 完整代碼示例:?
/**
* 功能簡述: 使用BASE64進行雙向加密/解密.
* @throws Exception
*/
@Test
public void test02() throws Exception {
BASE64Encoder encoder = new BASE64Encoder();
BASE64Decoder decoder = new BASE64Decoder();
String plainText = "Hello , world !";
String cipherText = encoder.encode(plainText.getBytes());
System.out.println("cipherText : " + cipherText);
//cipherText : SGVsbG8gLCB3b3JsZCAh
System.out.println("plainText : " +
new String(decoder.decodeBuffer(cipherText)));
//plainText : Hello , world !
}
??
<三>. 使用DES對稱加密/解密:
? ? ? ? ?數據加密標准演算法(Data Encryption Standard),和BASE64最明顯的區別就是有一個工作密鑰,該密鑰既用於加密、也用於解密,並且要求密鑰是一個長度至少大於8位的字元串。使用DES加密、解密的核心是確保工作密鑰的安全性。
?1.?根據key生成密鑰:?
DESKeySpec keySpec = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");
SecretKey secretKey = keyFactory.generateSecret(keySpec);
? 2.?加密操作:?
Cipher cipher = Cipher.getInstance("des");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, new SecureRandom());
byte[] cipherData = cipher.doFinal(plainText.getBytes());
? 3.?為了便於觀察生成的加密數據,使用BASE64再次加密:?
String cipherText = new BASE64Encoder().encode(cipherData);
? ? ?生成密文如下:PtRYi3sp7TOR69UrKEIicA==?
? 4.?解密操作:?
cipher.init(Cipher.DECRYPT_MODE, secretKey, new SecureRandom());
byte[] plainData = cipher.doFinal(cipherData);
String plainText = new String(plainData);
? 5. 完整的代碼demo:?
/**
* 功能簡述: 使用DES對稱加密/解密.
* @throws Exception
*/
@Test
public void test03() throws Exception {
String plainText = "Hello , world !";
String key = "12345678"; //要求key至少長度為8個字元
SecureRandom random = new SecureRandom();
DESKeySpec keySpec = new DESKeySpec(key.getBytes());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("des");
SecretKey secretKey = keyFactory.generateSecret(keySpec);
Cipher cipher = Cipher.getInstance("des");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, random);
byte[] cipherData = cipher.doFinal(plainText.getBytes());
System.out.println("cipherText : " + new BASE64Encoder().encode(cipherData));
//PtRYi3sp7TOR69UrKEIicA==
cipher.init(Cipher.DECRYPT_MODE, secretKey, random);
byte[] plainData = cipher.doFinal(cipherData);
System.out.println("plainText : " + new String(plainData));
//Hello , world !
}
??
<四>. 使用RSA非對稱加密/解密:
? ? ? ? RSA演算法是非對稱加密演算法的典型代表,既能加密、又能解密。和對稱加密演算法比如DES的明顯區別在於用於加密、解密的密鑰是不同的。使用RSA演算法,只要密鑰足夠長(一般要求1024bit),加密的信息是不能被破解的。用戶通過https協議訪問伺服器時,就是使用非對稱加密演算法進行數據的加密、解密操作的。
? ? ? ?伺服器發送數據給客戶端時使用私鑰(private key)進行加密,並且使用加密之後的數據和私鑰生成數字簽名(digital signature)並發送給客戶端。客戶端接收到伺服器發送的數據會使用公鑰(public key)對數據來進行解密,並且根據加密數據和公鑰驗證數字簽名的有效性,防止加密數據在傳輸過程中被第三方進行了修改。
? ? ? ?客戶端發送數據給伺服器時使用公鑰進行加密,伺服器接收到加密數據之後使用私鑰進行解密。
?1.?創建密鑰對KeyPair:
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("rsa");
keyPairGenerator.initialize(1024); //密鑰長度推薦為1024位.
KeyPair keyPair = keyPairGenerator.generateKeyPair();
? 2.?獲取公鑰/私鑰:
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
? 3.?伺服器數據使用私鑰加密:
Cipher cipher = Cipher.getInstance("rsa");
cipher.init(Cipher.ENCRYPT_MODE, privateKey, new SecureRandom());
byte[] cipherData = cipher.doFinal(plainText.getBytes());
? 4.?用戶使用公鑰解密:
cipher.init(Cipher.DECRYPT_MODE, publicKey, new SecureRandom());
byte[] plainData = cipher.doFinal(cipherData);
? 5.?伺服器根據私鑰和加密數據生成數字簽名:
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(cipherData);
byte[] signData = signature.sign();
? 6.?用戶根據公鑰、加密數據驗證數據是否被修改過:
signature.initVerify(publicKey);
signature.update(cipherData);
boolean status = signature.verify(signData);
? 7. RSA演算法代碼demo:<img src="http://www.cxyclub.cn/Upload/Images/2014081321/99A5FC9C0C628374.gif" alt="尷尬" title="尷尬" border="0">
/**
* 功能簡述: 使用RSA非對稱加密/解密.
* @throws Exception
*/
@Test
public void test04() throws Exception {
String plainText = "Hello , world !";
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("rsa");
keyPairGenerator.initialize(1024);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
Cipher cipher = Cipher.getInstance("rsa");
SecureRandom random = new SecureRandom();
cipher.init(Cipher.ENCRYPT_MODE, privateKey, random);
byte[] cipherData = cipher.doFinal(plainText.getBytes());
System.out.println("cipherText : " + new BASE64Encoder().encode(cipherData));
//gDsJxZM98U2GzHUtUTyZ/Ir/
///ONFOD0fnJoGtIk+T/+3yybVL8M+RI+HzbE/jdYa/+
//yQ+vHwHqXhuzZ/N8iNg=
cipher.init(Cipher.DECRYPT_MODE, publicKey, random);
byte[] plainData = cipher.doFinal(cipherData);
System.out.println("plainText : " + new String(plainData));
//Hello , world !
Signature signature = Signature.getInstance("MD5withRSA");
signature.initSign(privateKey);
signature.update(cipherData);
byte[] signData = signature.sign();
System.out.println("signature : " + new BASE64Encoder().encode(signData));
//+
//co64p6Sq3kVt84wnRsQw5mucZnY+/+vKKXZ3pbJMNT/4
///t9ewo+KYCWKOgvu5QQ=
signature.initVerify(publicKey);
signature.update(cipherData);
boolean status = signature.verify(signData);
System.out.println("status : " + status);
//true
}
㈧ Java中RSA的方式如何實現非對稱加密的示例
代碼如下,需要依賴一個jar包commons-codec-1.9.jar,用於Base64轉換,請自行下載。
importorg.apache.commons.codec.binary.Base64;
importjavax.crypto.BadPaddingException;
importjavax.crypto.Cipher;
importjavax.crypto.IllegalBlockSizeException;
importjava.io.ByteArrayOutputStream;
importjava.io.UnsupportedEncodingException;
importjava.security.*;
importjava.security.interfaces.RSAPrivateKey;
importjava.security.interfaces.RSAPublicKey;
importjava.security.spec.PKCS8EncodedKeySpec;
importjava.security.spec.X509EncodedKeySpec;
publicclassRSAUtils{
//加密方式
="RSA";
//簽名演算法
_ALGORITHM="SHA1WithRSA";
//創建密鑰對初始長度
privatestaticfinalintKEY_SIZE=512;
//字元編碼格式
="UTF-8";
//RSA最大加密明文大小
privatestaticfinalintMAX_ENCRYPT_BLOCK=117;
//RSA最大解密密文大小
privatestaticfinalintMAX_DECRYPT_BLOCK=128;
privateKeyFactorykeyFactory;
publicRSAUtils(){
keyFactory=KeyFactory.getInstance(ALGORITHM);
}
/**
*私鑰加密
*
*@paramcontent待加密字元串
*@paramprivateKey私鑰
*@return加密後字元串(BASE64編碼)
*/
(Stringcontent,StringprivateKey)throwsException{
Stringresult;
try(ByteArrayOutputStreamout=newByteArrayOutputStream()){
byte[]keyBytes=newBase64().decode(privateKey);
=newPKCS8EncodedKeySpec(keyBytes);
PrivateKeypKey=keyFactory.generatePrivate(pkcs8KeySpec);
Ciphercipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE,pKey);
byte[]data=content.getBytes(CHARSET);
write2Stream(cipher,data,out);
byte[]resultBytes=out.toByteArray();
result=Base64.encodeBase64String(resultBytes);
}catch(Exceptione){
thrownewException(e);
}
returnresult;
}
/**
*公鑰解密
*
*@paramcontent已加密字元串(BASE64加密)
*@parampublicKey公鑰
*@return
*/
(Stringcontent,StringpublicKey)throwsException{
Stringresult="";
try(ByteArrayOutputStreamout=newByteArrayOutputStream()){
byte[]keyBytes=newBase64().decode(publicKey);
X509EncodedKeySpecx509KeySpec=newX509EncodedKeySpec(keyBytes);
PublicKeypKey=keyFactory.generatePublic(x509KeySpec);
Ciphercipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE,pKey);
byte[]data=Base64.decodeBase64(content);
write2Stream(cipher,data,out);
byte[]resultBytes=out.toByteArray();
result=newString(resultBytes);
}catch(Exceptione){
thrownewException(e);
}
returnresult;
}
/**
*公鑰加密
*
*@paramcontent待加密字元串
*@parampublicKey公鑰
*@return加密後字元串(BASE64編碼)
*/
(Stringcontent,StringpublicKey)throwsException{
Stringresult="";
try(ByteArrayOutputStreamout=newByteArrayOutputStream()){
byte[]keyBytes=newBase64().decode(publicKey);
X509EncodedKeySpecx509KeySpec=newX509EncodedKeySpec(keyBytes);
PublicKeypKey=keyFactory.generatePublic(x509KeySpec);
Ciphercipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE,pKey);
byte[]data=content.getBytes(CHARSET);
write2Stream(cipher,
data,out);
byte[]resultBytes=out.toByteArray();
result=Base64.encodeBase64String(resultBytes);
}catch(Exceptione){
thrownewException(e);
}
returnresult;
}
/**
*私鑰解密
*
*@paramcontent已加密字元串
*@paramprivateKey私鑰
*@return解密後字元串
*/
(Stringcontent,StringprivateKey)throwsException{
Stringresult="";
try(ByteArrayOutputStreamout=newByteArrayOutputStream()){
byte[]keyBytes=newBase64().decode(privateKey);
=newPKCS8EncodedKeySpec(keyBytes);
PrivateKeypKey=keyFactory.generatePrivate(pkcs8KeySpec);
Ciphercipher=Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE,pKey);
byte[]data=Base64.decodeBase64(content);
write2Stream(cipher,data,out);
byte[]resultBytes=out.toByteArray();
result=newString(resultBytes);
}catch(Exceptione){
thrownewException(e);
}
returnresult;
}
privatestaticvoidwrite2Stream(Ciphercipher,byte[]data,ByteArrayOutputStreamout)throws
BadPaddingException,IllegalBlockSizeException{
intdataLen=data.length;
intoffSet=0;
byte[]cache;
inti=0;
//對數據分段解密
while(dataLen-offSet>0){
if(dataLen-offSet>MAX_DECRYPT_BLOCK){
cache=cipher.doFinal(data,offSet,MAX_DECRYPT_BLOCK);
}else{
cache=cipher.doFinal(data,offSet,dataLen-offSet);
}
out.write(cache,0,cache.length);
i++;
offSet=i*MAX_DECRYPT_BLOCK;
}
}
/**
*用私鑰對信息生成數字簽名
*
*@paramdata已加密數據
*@paramprivateKey私鑰(BASE64編碼)
*@returnsign
*/
publicStringsign(Stringdata,StringprivateKey)throwsException{
Stringresult="";
try{
byte[]keyBytes=newBase64().decode(privateKey);
=newPKCS8EncodedKeySpec(keyBytes);
PrivateKeyprivateK=keyFactory.generatePrivate(pkcs8KeySpec);
Signaturesignature=Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(parse2HexStr(data).getBytes(CHARSET));
result=newBase64().encodeToString(signature.sign());
}catch(Exceptione){
thrownewException(e);
}
returnresult;
}
/**
*校驗數字簽名
*
*@paramdata已加密數據
*@parampublicKey公鑰(BASE64編碼)
*@paramsign數字簽名
*@return
*@throwsException
*/
publicbooleanverify(Stringdata,StringpublicKey,Stringsign)throwsException{
booleanresult;
try{
byte[]keyBytes=newBase64().decode(publicKey);
X509EncodedKeySpeckeySpec=newX509EncodedKeySpec(keyBytes);
PublicKeypublicK=keyFactory.generatePublic(keySpec);
Signaturesignature=Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(parse2HexStr(data).getBytes(CHARSET));
result=signature.verify(newBase64().decode(sign));
}catch(Exceptione){
thrownewException(e);
}
returnresult;
}
/**
*將二進制轉換成16進制
*
*@paramdata
*@return
*/
(Stringdata)throwsException{
Stringresult="";
try{
byte[]buf=data.getBytes(CHARSET);
StringBuffersb=newStringBuffer();
for(inti=0;i<buf.length;i++){
Stringhex=Integer.toHexString(buf[i]&0xFF);
if(hex.length()==1){
hex='0'+hex;
}
sb.append(hex.toUpperCase());
}
result=sb.toString();
}catch(UnsupportedEncodingExceptione){
thrownewException(e);
}
returnresult;
}
/**
*生成公鑰與私鑰
*/
publicstaticvoidcreateKey()throwsException{
try{
=KeyPairGenerator.getInstance(ALGORITHM);
keyPairGenerator.initialize(KEY_SIZE);
KeyPairkeyPair=keyPairGenerator.generateKeyPair();
RSAPublicKeyrsaPublicKey=(RSAPublicKey)keyPair.getPublic();
RSAPrivateKeyrsaPrivateKey=(RSAPrivateKey)keyPair.getPrivate();
StringpublicKey=Base64.encodeBase64String(rsaPublicKey.getEncoded());
StringprivateKey=Base64.encodeBase64String(rsaPrivateKey.getEncoded());
System.out.println("publicKey="+publicKey+" privateKey="+privateKey);
}catch(NoSuchAlgorithmExceptione){
thrownewException(e);
}
}
publicstaticvoidmain(String[]args)throwsException{
StringPRIVATE_KEY="+m+/fNs1bmgfJhI8lhr/o/Hy8EFB/I/DDyLcCcU4bCLtxpki8edC+KJR2WvyYfnVmWEe//++W5C+lesEOAqdO5nahRZsL8BIDoxTEn2j+DSa///1qX+t8f5wD8i/8GU702PeCwkGI5ymrARq+/+/nkefTq0SNpUDVbGxVpJi9/FOUf";
StringPUBLIC_KEY="+lc///NfOvKvQndzDH60DzLGOMdE0NBrTn/5zEjGwJbVdlvCfOiHwIDAQAB";
RSAUtilsrsaUtil=newRSAUtils();
StringencryptByPublicKey=rsaUtil.encryptByPublicKey("你好!",PUBLIC_KEY);
System.out.println(encryptByPublicKey);
StringdecryptByPrivateKey=rsaUtil.decryptByPrivateKey(encryptByPublicKey,PRIVATE_KEY);
System.out.println(decryptByPrivateKey);
StringencryptByPrivateKey=rsaUtil.encryptByPrivateKey("你好!",PRIVATE_KEY);
System.out.println(encryptByPrivateKey);
StringdecryptByPublicKey=rsaUtil.decryptByPublicKey(encryptByPrivateKey,PUBLIC_KEY);
System.out.println(decryptByPublicKey);
Stringsign=rsaUtil.sign("1234",PRIVATE_KEY);
System.out.println("sign:"+sign);
System.out.println(rsaUtil.verify("1234",PUBLIC_KEY,sign));
}
}
㈨ java加密的幾種方式
朋友你好,很高興為你作答。
首先,Java加密能夠應對的風險包括以下幾個:
1、核心技術竊取
2、核心業務破解
3、通信模塊破解
4、API介面暴露
本人正在使用幾維安全Java加密方式,很不錯,向你推薦,希望能夠幫助到你。
幾維安全Java2C針對DEX文件進行加密保護,將DEX文件中標記的Java代碼翻譯為C代碼,編譯成加固後的SO文件。默認情況只加密activity中的onCreate函數,如果開發者想加密其它類和方法,只需對相關類或函數添加標記代碼,在APK加密時會自動對標記的代碼進行加密處理。
與傳統的APP加固方案相比,不涉及到自定義修改DEX文件的載入方式,所以其兼容性非常好;其次Java函數被完全轉化為C函數,直接在Native層執行,不存在Java層解密執行的步驟,其性能和執行效率更優。
如果操作上有不明白的地方,可以聯系技術支持人員幫你完成Java加密。
希望以上解答能夠幫助到你。
㈩ 請高手指教如何用java編寫RSA演算法謝謝
你是用rsa演算法去加密,還是要自己編寫一個rsa演算法?
RSA是非御侍派對稱加密演算法,可以用它鎮賀通過KeyPairGenerator來生成KeyPari,它裡面有公鑰和私鑰。
通過Cipher.getInstance("PBEWithMD5AndDES")得到Cipher對象並初始化為加密/解密模式。最doFinal即可完成加解密。除了生成KeyPari外,還可以通過RSA演算法的證書和密鑰庫來得到公/私鑰。如果閣下想自己編寫一個RSA演算法的,本人就無能為力談耐了。