Java實(shí)現(xiàn)非對稱加密的三種方法
1. 簡介
公開密鑰密碼學(xué)(英語:Public-key cryptography)也稱非對稱式密碼學(xué)(英語:Asymmetric cryptography)是密碼學(xué)的一種算法,它需要兩個(gè)密鑰,一個(gè)是公開密鑰,另一個(gè)是私有密鑰;公鑰用作加密,私鑰則用作解密。使用公鑰把明文加密后所得的密文,只能用相對應(yīng)的私鑰才能解密并得到原本的明文,最初用來加密的公鑰不能用作解密。由于加密和解密需要兩個(gè)不同的密鑰,故被稱為非對稱加密;不同于加密和解密都使用同一個(gè)密鑰的對稱加密。公鑰可以公開,可任意向外發(fā)布;私鑰不可以公開,必須由用戶自行嚴(yán)格秘密保管,絕不透過任何途徑向任何人提供,也不會透露給被信任的要通信的另一方。
基于公開密鑰加密的特性,它還能提供數(shù)字簽名的功能,使電子文件可以得到如同在紙本文件上親筆簽署的效果。公開密鑰基礎(chǔ)建設(shè)透過信任數(shù)字證書認(rèn)證機(jī)構(gòu)的根證書、及其使用公開密鑰加密作數(shù)字簽名核發(fā)的公開密鑰認(rèn)證,形成信任鏈架構(gòu),已在TLS實(shí)現(xiàn)并在萬維網(wǎng)的HTTP以HTTPS、在電子郵件的SMTP以SMTPS或STARTTLS引入。
在現(xiàn)實(shí)世界上可作比擬的例子是,一個(gè)傳統(tǒng)保管箱,開門和關(guān)門都是使用同一條鑰匙,這是對稱加密;而一個(gè)公開的郵箱,投遞口是任何人都可以寄信進(jìn)去的,這可視為公鑰;而只有信箱主人擁有鑰匙可以打開信箱,這就視為私鑰。
非對稱加密過程:

此流程圖顯示非對稱加密過程是單向的,其中一條密鑰加密后只能用相對應(yīng)的另一條密鑰解密。
2. 非對稱加密算法–DH(密鑰交換)
| 密鑰長度 | 默認(rèn) | 工作模式 | 填充方式 | 實(shí)現(xiàn)方 |
|---|---|---|---|---|
| 512~1024(64倍數(shù)) | 1024 | 無 | 無 | JDK |
DH加解密應(yīng)用:
package com.bity.dh;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyAgreement;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
import java.util.Objects;
import static java.lang.System.*;
/**
* <p>Title: JdkDh</p >
* <p>Description: DH非對稱算法實(shí)現(xiàn) </p >
* <p>Company: http://www.agree.com</p >
* <p>Project: security</p >
*
* @author <a href="mailto:weiqi@agree.com.cn" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >WEIQI</a>
* @version 1.0
* @date 2022-04-27 19:51
*/
public class JdkDh {
private static final String SRC = "I'm DH encryption algorithm";
public static void main(String[] args) {
// 解決 Unsupported secret key algorithm: DES 異常
System.getProperties().setProperty("jdk.crypto.KeyAgreement.legacyKDF", "true");
jdkDh();
}
private static void jdkDh() {
try {
// 初始化發(fā)送方密鑰
KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");
senderKeyPairGenerator.initialize(512);
KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();
// 發(fā)送方密鑰,發(fā)送給接收方(可以通過文件、優(yōu)盤、網(wǎng)絡(luò)等...)
byte[] senderPublicKeyEnc = senderKeyPair.getPublic().getEncoded();
// 初始化接收方密鑰,注意在實(shí)際環(huán)境中接收方和發(fā)送方肯定不會在一個(gè)函數(shù)中
KeyFactory keyFactory = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyEnc);
PublicKey receiverPublicKey = keyFactory.generatePublic(x509EncodedKeySpec);
DHParameterSpec dhParameterSpec = ((DHPublicKey)receiverPublicKey).getParams();
KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
receiverKeyPairGenerator.initialize(dhParameterSpec);
KeyPair receiverKeyPair = receiverKeyPairGenerator.generateKeyPair();
PrivateKey receiverPrivateKey = receiverKeyPair.getPrivate();
byte[] receiverPublicKeyEnc = receiverKeyPair.getPublic().getEncoded();
// 構(gòu)建密鑰
KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
receiverKeyAgreement.init(receiverPrivateKey);
receiverKeyAgreement.doPhase(receiverPublicKey, true);
SecretKey receiverSecretKey = receiverKeyAgreement.generateSecret("DES");
KeyFactory senderKeyFactory = KeyFactory.getInstance("DH");
x509EncodedKeySpec = new X509EncodedKeySpec(receiverPublicKeyEnc);
PublicKey senderPublicKey = senderKeyFactory.generatePublic(x509EncodedKeySpec);
KeyAgreement senderKeyAgreement = KeyAgreement.getInstance("DH");
senderKeyAgreement.init(senderKeyPair.getPrivate());
senderKeyAgreement.doPhase(senderPublicKey, true);
SecretKey senderSecretKey = senderKeyAgreement.generateSecret("DES");
if (Objects.equals(receiverSecretKey, senderSecretKey)) {
out.println("雙方密鑰相同");
}
// 加密
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, senderSecretKey);
byte[] result = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));
out.println("jdk dh encryption is : " + Base64.encodeBase64String(result));
// 解密
cipher.init(Cipher.DECRYPT_MODE, receiverSecretKey);
result = cipher.doFinal(result);
out.println("jdk dh decrypt is : " + new String(result));
} catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidAlgorithmParameterException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
}
}
運(yùn)行結(jié)果:
雙方密鑰相同
jdk dh encryption is : Be3LeXqV/q1PDEbpH62LL129gaV5Og0Eo3GY9e00B4o=
jdk dh decrypt is : I'm DH encryption algorithm
注意:由于JDK8 update 161之后,DH的密鑰長度至少為512位,但DES算法密鑰不能達(dá)到這樣的長度,所以運(yùn)行會拋出Unsupported secret key algorithm: DES異常。解決辦法有兩種如下:
- 在代碼中加如下代碼:
System.getProperties().setProperty("jdk.crypto.KeyAgreement.legacyKDF", "true");
在啟動的時(shí)候添加JVM變量:-Djdk.crypto.KeyAgreement.legacyKDF=true


3. 非對稱加密算法–RSA
RSA加密算法是一種非對稱加密算法,在公開密鑰加密和電子商業(yè)中被廣泛使用。RSA是由羅納德·李維斯特(Ron Rivest)、阿迪·薩莫爾(Adi Shamir)和倫納德·阿德曼(Leonard Adleman)在1977年一起提出的。當(dāng)時(shí)他們?nèi)硕荚诼槭±砉W(xué)院工作。RSA 就是他們?nèi)诵帐祥_頭字母拼在一起組成的。
對極大整數(shù)做因數(shù)分解的難度決定了 RSA 算法的可靠性。換言之,對一極大整數(shù)做因數(shù)分解愈困難,RSA 算法愈可靠。假如有人找到一種快速因數(shù)分解的算法的話,那么用 RSA 加密的信息的可靠性就會極度下降。但找到這樣的算法的可能性是非常小的。今天只有短的 RSA 鑰匙才可能被強(qiáng)力方式破解。到2020年為止,世界上還沒有任何可靠的攻擊RSA算法的方式。只要其鑰匙的長度足夠長,用RSA加密的信息實(shí)際上是不能被破解的。
RSA算法加密實(shí)現(xiàn):
package com.bity.rsa;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
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 static java.lang.System.*;
/**
* <p>Title: JdkRsa</p >
* <p>Description: RSA非對稱加密算法實(shí)現(xiàn) </p >
* <p>Company: http://www.agree.com</p >
* <p>Project: security</p >
*
* @author <a href="mailto:weiqi@agree.com.cn" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >WEIQI</a>
* @version 1.0
* @date 2022-04-27 21:38
*/
public class JdkRsa {
private static final String SRC = "I'm RSA encryption algorithm";
public static void main(String[] args) {
jdkRsa();
}
/**
* JDK-RSA算法實(shí)現(xiàn)
*
* @author: <a href="mailto:weiqi@agree.com.cn" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >WEIQI</a>
* @date: 2022-04-28 0:15
*/
private static void jdkRsa() {
try {
// 初始化密鑰
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
out.println("public key is : " + Base64.encodeBase64String(rsaPublicKey.getEncoded()));
out.println("private key is : " + Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
// 私鑰加密,公鑰解密 -- 加密
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] result = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));
out.println("私鑰加密,公鑰解密 -- 加密 : " + Base64.encodeBase64String(result));
// 私鑰加密,公鑰解密 -- 解密
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
result = cipher.doFinal(result);
out.println("私鑰加密,公鑰解密 -- 解密 : " + new String(result));
// 公鑰加密,私鑰解密 -- 加密
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] res = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));
out.println("公鑰加密,私鑰解密 -- 加密 : " + Base64.encodeBase64String(res));
// 公鑰加密,私鑰解密 -- 解密
cipher.init(Cipher.DECRYPT_MODE, privateKey);
res = cipher.doFinal(res);
out.println("公鑰加密,私鑰解密 -- 解密 : " + new String(res));
} catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
e.printStackTrace();
}
}
}
運(yùn)行結(jié)果:
public key is : MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIfDTXqCrjGHP9tCmLujavsngP8nqSHIl/JkFN8ZmQEcn48xzSXdijEG8Ssgm3SkDWICT0cW9wf3mZ+UkVxLx90CAwEAAQ==
private key is : MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAh8NNeoKuMYc/20KYu6Nq+yeA/yepIciX8mQU3xmZARyfjzHNJd2KMQbxKyCbdKQNYgJPRxb3B/eZn5SRXEvH3QIDAQABAkASyfa5E8jj1eICiE72+QDfTXJO3cBMiqRsyWkSD0rbmlL/Qv1xDDQonWM58sIR6DOBWQZ+uXbkL1VtOuZ9sgfBAiEA9IxhRwkTYA1GVUKmgZPX+7CsfUmIZi8P/r9/C29XQZUCIQCOHtBkIOupaTLPv3A4yznEidygfbL8nrLV2Xhf6wVrKQIhAJ+RdewPDPhw0QLTIaiNWrIdXv/FWl4quUolk/VXKl1dAiASpbpkGOmy7cmr9otr+EZZIlmfeT695LjEVGd19mlcmQIhAJfua+j3/PT0+z0nPIaGDvczviyl5SxmDo79rfMNpi10
私鑰加密,公鑰解密 -- 加密 : AiYjJSlGlz5x86mwVW/wjieG/uJsoLEqF+xRcPLzq2HL7yIrSrE3oT4wibrvUDR6kp37eHvFaAT+/wVYCreVvg==
私鑰加密,公鑰解密 -- 解密 : I'm RSA encryption algorithm
公鑰加密,私鑰解密 -- 加密 : Io2diORtKbeTz5eOOziHrqZKzS1K19U4t3YPydhM4w2LrzW7bJK/d4DQrWTBAhg8rt28OjbGcJfqd1w8MMy4iw==
公鑰加密,私鑰解密 -- 解密 : I'm RSA encryption algorithm
從上面例子可以看出RSA算法是支持私鑰加密、公鑰解密和公鑰加密、私鑰解密的算法。RSA也是唯一被廣泛接受并實(shí)現(xiàn)的非對稱加密算法,從某種程度來說,RSA已經(jīng)成為非對稱加密算法的一個(gè)標(biāo)準(zhǔn)了。
RSA數(shù)據(jù)加密傳輸圖示:

4、非對稱加密算法–EIGamal
在密碼學(xué)中,ElGamal加密算法是一個(gè)基于迪菲-赫爾曼密鑰交換的非對稱加密算法。它在1985年由塔希爾·蓋莫爾提出。GnuPG和PGP等很多密碼學(xué)系統(tǒng)中都應(yīng)用到了ElGamal算法。
ElGamal加密算法由三部分組成:密鑰生成、加密和解密。
ElGamal算法加解密應(yīng)用:
package com.bity.eigamal;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.DHParameterSpec;
import java.nio.charset.StandardCharsets;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import static java.lang.System.out;
/**
* <p>Title: BouncyCastleEiGamal</p >
* <p>Description: ElGamal加密算法實(shí)現(xiàn) </p >
* <p>Company: http://www.agree.com</p >
* <p>Project: security</p >
*
* @author <a href="mailto:weiqi@agree.com.cn" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >WEIQI</a>
* @version 1.0
* @date 2022-04-28 0:38
*/
public class BouncyCastleElGamal {
private static final String SRC = "I'm ElGamal encryption algorithm";
public static void main(String[] args) {
bcElGamal();
}
private static void bcElGamal() {
try {
Security.addProvider(new BouncyCastleProvider());
AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator
.getInstance("ElGamal");
algorithmParameterGenerator.init(256);
AlgorithmParameters algorithmParameters = algorithmParameterGenerator.generateParameters();
DHParameterSpec dhParameterSpec = algorithmParameters.getParameterSpec(DHParameterSpec.class);
// 初始化密鑰
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("ElGamal");
keyPairGenerator.initialize(dhParameterSpec, new SecureRandom());
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey elGamalPublicKey = keyPair.getPublic();
PrivateKey elGamalPrivateKey = keyPair.getPrivate();
out.println("public key is : " + Base64.encodeBase64String(elGamalPublicKey.getEncoded()));
out.println("private key is : " + Base64.encodeBase64String(elGamalPrivateKey.getEncoded()));
// 公鑰加密,私鑰解密 -- 加密
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(elGamalPublicKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("ElGamal");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("ElGamal");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] result = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));
out.println("私鑰加密,公鑰解密 -- 解密 : " + Base64.encodeBase64String(result));
// 公鑰加密,私鑰解密 -- 解密
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(elGamalPrivateKey.getEncoded());
keyFactory = KeyFactory.getInstance("ElGamal");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
result = cipher.doFinal(result);
out.println("私鑰加密,公鑰解密 -- 加密 : " + new String(result));
} catch (NoSuchAlgorithmException | InvalidKeySpecException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | InvalidParameterSpecException | InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
}
}
運(yùn)行結(jié)果:
public key is : MHYwTwYGKw4HAgEBMEUCIQCxvT1SNSrVl1/8KpvPhaE1MKiaXOHWk5SACDd39SfnHwIgQ5O8oKi9mIKhEDOCKwvYB+mozFgvmuoipw/ZDl6xCicDIwACIBh0K6bn2mtdvmiSMJj/HDlotAGOmTRFMZs+PFoIobQG
private key is : MHgCAQAwTwYGKw4HAgEBMEUCIQCxvT1SNSrVl1/8KpvPhaE1MKiaXOHWk5SACDd39SfnHwIgQ5O8oKi9mIKhEDOCKwvYB+mozFgvmuoipw/ZDl6xCicEIgIge9eM9ELM12n6bQKkj8iBtIXjvPeN5mwX9clNriqfSsA=
私鑰加密,公鑰解密 -- 解密 : e39h4LkKXQn1EIXdDkIxmWiB2pwgO5dZJcNfSmlXqS07SrW1VSLrx0L3RhdWm8hPLaqBZieR5quU/7oTzH/uuA==
私鑰加密,公鑰解密 -- 加密 : I'm ElGamal encryption algorithm
ElGamal數(shù)據(jù)加密傳輸圖示:

5. 總結(jié)
對稱密碼是指在加密和解密時(shí)使用同一個(gè)密鑰的方式,公鑰密碼則是指在加密和解密時(shí)使用不同密鑰的方式。
對稱密鑰加密牽涉到密鑰管理的問題,尤其是密鑰交換,它需要通信雙方在通信之前先透過另一個(gè)安全的渠道交換共享的密鑰,才可以安全地把密文透過不安全的渠道發(fā)送;對稱密鑰一旦被竊,其所作的加密將即時(shí)失效;而在互聯(lián)網(wǎng),如果通信雙方分隔異地而素未謀面,則對稱加密事先所需要的“安全渠道”變得不可行;非對稱加密則容許加密公鑰隨便散布,解密的私鑰不發(fā)往任何用戶,只在單方保管;如此,即使公鑰在網(wǎng)上被截獲,如果沒有與其匹配的私鑰,也無法解密,極為適合在互聯(lián)網(wǎng)上使用。
另一方面,公鑰解密的特性可以形成數(shù)字簽名,使數(shù)據(jù)和文件受到保護(hù)并可信賴;如果公鑰透過數(shù)字證書認(rèn)證機(jī)構(gòu)簽授成為電子證書,更可作為數(shù)字身份的認(rèn)證,這都是對稱密鑰加密無法實(shí)現(xiàn)的。不過,公鑰加密在在計(jì)算上相當(dāng)復(fù)雜,性能欠佳、遠(yuǎn)遠(yuǎn)不比對稱加密;因此,在一般實(shí)際情況下,往往通過公鑰加密來隨機(jī)創(chuàng)建臨時(shí)的對稱秘鑰,亦即對話鍵,然后才通過對稱加密來傳輸大量、主體的數(shù)據(jù)。
6 案例
6.1 案例1
package com.test;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class MyTest02 {
public static void main(String[] args) throws Exception {
MyTest02 myTest02 = new MyTest02();
myTest02.test1(); //生成密鑰
String jm = myTest02.test2(); //通過公鑰加密
myTest02.test3(jm); //通過私鑰解密
}
public void test1() throws NoSuchAlgorithmException {
// 初始化密鑰
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey rsaPublicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey) keyPair.getPrivate();
System.out.println("public key is : " + Base64.getEncoder().encodeToString(rsaPublicKey.getEncoded()));
System.out.println("private key is : " + Base64.getEncoder().encodeToString(rsaPrivateKey.getEncoded()));
}
public String test2() throws Exception {
String SRC = "I'm RSA encryption algorithm";
String pubKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIOz/OOCWjqI/6gssHGA/cHiJnR3hNdp230g1x7Y/aWzFc8WrQnjlX4v0PdEOphfkt8CtdzgDAlz4gMTLkLdU30CAwEAAQ==";
byte[] pubKeyDecode = Base64.getDecoder().decode(pubKey);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(pubKeyDecode);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] res = cipher.doFinal(SRC.getBytes(StandardCharsets.UTF_8));
System.out.println("公鑰加密,私鑰解密 -- 加密 : " + Base64.getEncoder().encodeToString(res));
return Base64.getEncoder().encodeToString(res);
}
public void test3 (String data) throws Exception {
String pvtKey = "MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAg7P844JaOoj/qCywcYD9weImdHeE12nbfSDXHtj9pbMVzxatCeOVfi/Q90Q6mF+S3wK13OAMCXPiAxMuQt1TfQIDAQABAkAbcnUvjMj1DfwJtlaHMRSxRUoyV34tznfZmfB7E0m5MEwfCMECzVKVtnmPpl3abbSt7UFwarvhnhhqfMM3Z9BBAiEA7ny1zoW04a/KM7VJRprOtkC3IQzjiyPl8aeoaseuvIkCIQCNX9t9K6GmSpwPLdBDtfk+Krk0qfiZaB9tEOhtG4hqVQIhAIriiaZJ63r7OtA+JPw/L16n9X4D2YewUjsXHleBDluxAiB9bkjs22NGiPfBN+KJ0NBcacd8hDl+0jTfrZqqAz2bKQIgUokJPDnwtnWVvWEwAK2wkDHkpIuvVRiG0HxNhS/ZDQA=";
byte[] pvtDecoder = Base64.getDecoder().decode(pvtKey);
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(pvtDecoder);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decode = Base64.getDecoder().decode(data);
byte[] res = cipher.doFinal(decode);
System.out.printf("公鑰加密,私鑰解密 -- 解密: " + new String(res));
}
6.2 案例2
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import javax.crypto.Cipher;
public class RSAEncryptionExample {
public static void main(String[] args) throws Exception {
String data = "Hello, world!";
KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = cipher.doFinal(data.getBytes());
System.out.println(Base64.getEncoder().encodeToString(encryptedData));
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData = cipher.doFinal(encryptedData);
System.out.println(new String(decryptedData));
}
}到此這篇關(guān)于Java實(shí)現(xiàn)非對稱加密的兩種方法的文章就介紹到這了,更多相關(guān)Java 非對稱加密內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring?Security配置多個(gè)數(shù)據(jù)源并添加登錄驗(yàn)證碼的實(shí)例代碼
這篇文章主要介紹了Spring?Security配置多個(gè)數(shù)據(jù)源并添加登錄驗(yàn)證碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08
幾句話說清session,cookie和token的區(qū)別及說明
這篇文章主要介紹了幾句話說清session,cookie和token的區(qū)別及說明,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Java生成10個(gè)1000以內(nèi)的隨機(jī)數(shù)并用消息框顯示數(shù)組內(nèi)容然后求和輸出
這篇文章主要介紹了Java生成10個(gè)1000以內(nèi)的隨機(jī)數(shù)并用消息框顯示數(shù)組內(nèi)容然后求和輸出,需要的朋友可以參考下2015-10-10
mybatisPlus自定義批量新增的實(shí)現(xiàn)代碼
這篇文章主要介紹了mybatisPlus自定義批量新增的實(shí)現(xiàn)代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
SpringBoot+Elasticsearch實(shí)現(xiàn)數(shù)據(jù)搜索的方法詳解
Elasticsearch是一個(gè)基于Lucene的搜索服務(wù)器。它提供了一個(gè)分布式多用戶能力的全文搜索引擎,基于RESTful?web接口。本文將利用SpringBoot整合Elasticsearch實(shí)現(xiàn)海量級數(shù)據(jù)搜索,需要的可以參考一下2022-05-05

