介紹:非對(duì)稱加密相對(duì)與對(duì)稱加密算法來說是高級(jí)的,。 舉個(gè)雙保險(xiǎn)的例子: 銀行的保險(xiǎn)柜,客戶往銀行的保險(xiǎn)柜存貴重東西,,這個(gè)保險(xiǎn)柜的鑰匙會(huì)有兩把,,客戶有一把,,銀行有一把,。如果想打開保險(xiǎn)柜就需要銀行的鑰匙和客戶的鑰匙一塊使用才能打開保險(xiǎn)柜。 公鑰,,私鑰:客戶和銀行的鑰匙 公鑰:是通過非安全的通道發(fā)放的,,也就是說是公開的方式 私鑰:自己保存的。 公鑰和私鑰一般是成對(duì)出現(xiàn)的,,使用公鑰加密的數(shù)據(jù)只有與它對(duì)應(yīng)的私鑰才能解開,。 在非對(duì)稱加密算法中有一些算法是可以公鑰加密私鑰解密,私鑰加密公鑰解密都支持的,,有一些算法只支持一種方式的,。 非對(duì)稱加密算法種類: DH(Diffie-Hellman):密鑰交換算法 RSA:基于因子分解,既能用于數(shù)字加密也能用于數(shù)字簽名 Elgamal:基于離散對(duì)數(shù) ECC(Elliptical Curve Cryptography):橢圓曲線加密 DH對(duì)稱加密算法的弊端: 對(duì)稱加密算法中公布密鑰這個(gè)步驟會(huì)有問題,,發(fā)送密鑰的時(shí)候可能會(huì)出現(xiàn)泄露密鑰的情況,。一旦密鑰被泄露,那么所有的數(shù)據(jù)就很容易被破解掉,。 但是DH(密鑰交換算法)是通過構(gòu)建本地密鑰來解決密鑰容易在傳遞中泄露的問題的,。 初始化發(fā)送方密鑰涉及的三個(gè)類: 1. KeyPairGenerator(通過KeyPairGenerator來得到KeyPair類的對(duì)象) //創(chuàng)建KeyPairGenerator對(duì)象
KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator.getInstance("DH");//"DH"指定算法的名稱
2 KeyPair(得到密鑰對(duì),,包括公鑰和私鑰) 3. PublicKey:公鑰 初始化接收方密鑰涉及到的類: 1. KeyFactory:作用是生成密鑰(包括公鑰和私鑰) generatePublic()方法用來生成公鑰 generatePrivate()方法用來生成私鑰 2 X509EncodedKeySpec:根據(jù)ASN.1標(biāo)準(zhǔn)進(jìn)行密鑰編碼 3. DHPublicKey:是PublicKey的某種具體的形式 4. DHParameterSpec:隨從著DH算法來使用的參數(shù)的集合 5. KeyPairGenerator:通過KeyPairGenerator來得到KeyPair類的對(duì)象 6. PrivateKey:私鑰 密鑰構(gòu)建涉及的類 - KeyAgreement:提供密鑰一致性(或密鑰交換)協(xié)議的功能
//生成實(shí)現(xiàn)指定密鑰一致算法的KeyAgreement對(duì)象
static keyAgreement getInstance(String algorithm)
//為來自指定提供程序的指定密鑰一致算法生成一個(gè)KeyAgreement對(duì)象
static keyAgreement getInstance(String algorithm,Provider provider)
2 SecretKey:生成一個(gè)分組的秘密密鑰,同時(shí)提供了相應(yīng)的類型安全的操作 3. KeyFactory 4. X509EncodedKeySpec 5. PublicKey 加解密涉及到的類: Cipher 例子 package com.timliu.security.asymmetric_encryption;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
import java.util.Objects;
import javax.crypto.Cipher;
import javax.crypto.KeyAgreement;
import javax.crypto.SecretKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import org.apache.commons.codec.binary.Base64;
public class DHTest {
public static final String src = "hello world";
public static void main(String[] args) {
jdkDH();
}
// jdk實(shí)現(xiàn):
public static void jdkDH() {
try {
/*
* 發(fā)送方的操作
*/
// 1.初始化發(fā)送方密鑰
KeyPairGenerator senderKeyPairGenerator = KeyPairGenerator
.getInstance("DH");
senderKeyPairGenerator.initialize(512);//設(shè)置長度
KeyPair senderKeyPair = senderKeyPairGenerator.generateKeyPair();//生成keypair
// 保存了發(fā)送方公鑰的字節(jié)數(shù)組,,發(fā)送給接收方(發(fā)送方式:網(wǎng)絡(luò),、文件。,。,。)
byte[] senderPublicKeyEnc = senderKeyPair.getPublic().getEncoded();
/*
* 接收方的操作
*/
// 2.初始化接收方密鑰
KeyFactory receiverKeyFactory = KeyFactory.getInstance("DH");
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(senderPublicKeyEnc);
PublicKey receiverPublicKey = receiverKeyFactory.generatePublic(x509EncodedKeySpec);
DHParameterSpec dhParameterSpec = ((DHPublicKey) receiverPublicKey).getParams();
KeyPairGenerator receiverKeyPairGenerator = KeyPairGenerator.getInstance("DH");
receiverKeyPairGenerator.initialize(dhParameterSpec);
KeyPair receiverKeypair = receiverKeyPairGenerator.generateKeyPair();
PrivateKey receiverPrivateKey = receiverKeypair.getPrivate();
//保存了接收方公鑰的字節(jié)數(shù)組,發(fā)送給發(fā)送方(發(fā)送方式:網(wǎng)絡(luò),,文件,。。,。,。)
byte[] receiverPublicKeyEnc = receiverKeypair.getPublic().getEncoded();
// 3.密鑰構(gòu)建
KeyAgreement receiverKeyAgreement = KeyAgreement.getInstance("DH");
receiverKeyAgreement.init(receiverPrivateKey);
receiverKeyAgreement.doPhase(receiverPublicKey, true);
//生成接收方的本地密鑰
SecretKey receiverDesKey = receiverKeyAgreement.generateSecret("DES");
/*
* 發(fā)送方的操作
*/
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);
//生成發(fā)送方的本地密鑰
SecretKey senderDesKey = senderKeyAgreement.generateSecret("DES");
if(Objects.equals(receiverDesKey, senderDesKey)){
System.out.println("發(fā)送方和接收方密鑰相同。");
}else{
System.out.println("發(fā)送方和接收方密鑰不相同");
}
// 4.加密
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, senderDesKey);
byte[] result = cipher.doFinal(src.getBytes());
System.out.println("bc dh encrypt:"+ Base64.encodeBase64String(result));
// 5.解密
cipher.init(Cipher.DECRYPT_MODE, receiverDesKey);
result = cipher.doFinal(result);
System.out.println("bc dh decrypt:" + new String(result));
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
運(yùn)行結(jié)果:
DH算法的應(yīng)用場(chǎng)景
RSA唯一廣泛接受并實(shí)現(xiàn)的非對(duì)稱加密的算法,。 可以實(shí)現(xiàn)數(shù)據(jù)加密和數(shù)字簽名,。 提供了: 1. 公鑰加密,私鑰解密 2. 私鑰加密,,公鑰解密
例子: package com.timliu.security.asymmetric_encryption;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
public class RSATest {
public static final String src = "hello world";
public static void main(String[] args) {
jdkRSA();
}
// jdk實(shí)現(xiàn):
public static void jdkRSA() {
try {
// 1.初始化發(fā)送方密鑰
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:"+ Base64.encodeBase64String(rsaPublicKey.getEncoded()));
System.out.println("Private Key:"+ Base64.encodeBase64String(rsaPrivateKey.getEncoded()));
// 2.私鑰加密,、公鑰解密 ---- 加密
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());
System.out.println("私鑰加密,、公鑰解密 ---- 加密:"+ Base64.encodeBase64String(result));
// 3.私鑰加密,、公鑰解密 ---- 解密
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKey);
result = cipher.doFinal(result);
System.out.println("私鑰加密、公鑰解密 ---- 解密:" + new String(result));
// 4.公鑰加密,、私鑰解密 ---- 加密
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
KeyFactory keyFactory2 = KeyFactory.getInstance("RSA");
PublicKey publicKey2 = keyFactory2.generatePublic(x509EncodedKeySpec2);
Cipher cipher2 = Cipher.getInstance("RSA");
cipher2.init(Cipher.ENCRYPT_MODE, publicKey2);
byte[] result2 = cipher2.doFinal(src.getBytes());
System.out.println("公鑰加密,、私鑰解密 ---- 加密:"+ Base64.encodeBase64String(result2));
// 5.公鑰加密、私鑰解密 ---- 解密
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory5 = KeyFactory.getInstance("RSA");
PrivateKey privateKey5 = keyFactory5.generatePrivate(pkcs8EncodedKeySpec5);
Cipher cipher5 = Cipher.getInstance("RSA");
cipher5.init(Cipher.DECRYPT_MODE, privateKey5);
byte[] result5 = cipher5.doFinal(result2);
System.out.println("公鑰加密,、私鑰解密 ---- 解密:" + new String(result5));
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
運(yùn)行結(jié)果: Public Key:
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAOz8ggiZp7ly13XoE9CtW3OlXQjVbrXc8zZCdKhFagXSSFcUvGqKbdfZuvjAjET7Vec7GurqLX14w99KnxFAbD8CAwEAAQ==
Private Key:
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEA7PyCCJmnuXLXdegT0K1bc6VdCNVutdzzNkJ0qEVqBdJIVxS8aopt19m6+MCMRPtV5zsa6uotfXjD30qfEUBsPwIDAQABAkAjp4nYyWVWnVSVRKlWh/5uU76/iXzyl59v1me+uVLONR7XjkQyz7Kq3uh33276FAxZtHFlabphCpZf0aqpUFuBAiEA9lAF2lMjx379oTtRJhs75iw11z7f+hpaxaUN+JMa1RECIQD2TpWxJfF20bRyDCi0U2sl2ElqdxjZe0pAAiebgr3sTwIgbEChQeHWUMBUMf9C2++ONMvrYc1FXMMmb8TpzfzBBzECIQCOB4y8JRQTHyO9bBOAwGWV4h2bneefaT/MnzF1tDOOcwIhALs3oH3XIAPBU2bFBaGqBTO//XIUoE8CfyOfPA3fvusC
私鑰加密,、公鑰解密 ---- 加密:
cIvL/HQH8gMBpD5qi99B4Cql/qZiNFc7eHfnua9qlQLGfQ436wNV9tzCQg+n7cR+/mDlAUSAvegwvk/0FD/Jmw==
私鑰加密、公鑰解密 ---- 解密:hello world
公鑰加密,、私鑰解密 ---- 加密:
rvG7tdyCbU5B4fbT2xrFPkH8tUUsepkpZwGALi56/CCpVWOyvGq/aqBS4dQJKxjwH0t0pfWzt+iw3fJe3qTwGg==
公鑰加密,、私鑰解密 ---- 解密:hello world
RSA應(yīng)用場(chǎng)景:
ElGamal提供公鑰加密算法。 基于離散對(duì)數(shù),。 JDK沒有提供ElGamal算法的實(shí)現(xiàn),,是Bouncy Castle提供的。
例子: package com.timliu.security.asymmetric_encryption;
import java.security.AlgorithmParameterGenerator;
import java.security.AlgorithmParameters;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Security;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
import javax.crypto.spec.DHParameterSpec;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public class ElGamalTest {
public static final String src = "hello world";
public static void main(String[] args) {
BCElgamal();
}
/**
*
* 對(duì)于:“Illegal key size or default
* parameters”異常,,是因?yàn)槊绹某隹谙拗?,Sun通過權(quán)限文件(local_policy
* .jar、US_export_policy.jar)做了相應(yīng)限制,。因此存在一些問題: Java 6
* 無政策限制文件:http://www.oracle
* .com/technetwork/java/javase/downloads/jce-6-download-429243.html Java 7
* 無政策限制文件
* :http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download
* -432124.html 我的時(shí)java7,,自己安裝的,。
* /Library/Java/JavaVirtualMachines/jdk1.7.0_71
* .jdk/Contents/Home/jre/lib/security目錄下
* ,對(duì)應(yīng)覆蓋local_policy.jar和US_export_policy.jar兩個(gè)文件,。
*
* 切換到%JDK_Home%\jre\lib\security目錄下,,對(duì)應(yīng)覆蓋local_policy.jar和US_export_policy.
* jar兩個(gè)文件。同時(shí),,你可能有必要在%JRE_Home%\lib\security目錄下,,也需要對(duì)應(yīng)覆蓋這兩個(gè)文件。
*/
// BC實(shí)現(xiàn):“私鑰解密,、公鑰加密” ,, 對(duì)于:“私鑰加密、公鑰解密”有問題,,因?yàn)镋lgamal不支持
public static void BCElgamal() {
try {
// 加入對(duì)BouncyCastle支持
Security.addProvider(new BouncyCastleProvider());
// 1.初始化發(fā)送方密鑰
AlgorithmParameterGenerator algorithmParameterGenerator = AlgorithmParameterGenerator
.getInstance("Elgamal");
// 初始化參數(shù)生成器
algorithmParameterGenerator.init(256);
// 生成算法參數(shù)
AlgorithmParameters algorithmParameters = algorithmParameterGenerator
.generateParameters();
// 構(gòu)建參數(shù)材料
DHParameterSpec dhParameterSpec = (DHParameterSpec) algorithmParameters
.getParameterSpec(DHParameterSpec.class);
// 實(shí)例化密鑰生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator
.getInstance("Elgamal");
// 初始化密鑰對(duì)生成器
keyPairGenerator.initialize(dhParameterSpec, new SecureRandom());
KeyPair keyPair = keyPairGenerator.generateKeyPair();
// 公鑰
PublicKey elGamalPublicKey = keyPair.getPublic();
// 私鑰
PrivateKey elGamalPrivateKey = keyPair.getPrivate();
System.out.println("Public Key:"
+ Base64.encodeBase64String(elGamalPublicKey.getEncoded()));
System.out
.println("Private Key:"
+ Base64.encodeBase64String(elGamalPrivateKey
.getEncoded()));
// 2.私鑰解密,、公鑰加密 ---- 加密
// 初始化公鑰
// 密鑰材料轉(zhuǎn)換
X509EncodedKeySpec x509EncodedKeySpec2 = new X509EncodedKeySpec(
elGamalPublicKey.getEncoded());
// 實(shí)例化密鑰工廠
KeyFactory keyFactory2 = KeyFactory.getInstance("Elgamal");
// 產(chǎn)生公鑰
PublicKey publicKey2 = keyFactory2
.generatePublic(x509EncodedKeySpec2);
// 數(shù)據(jù)加密
// Cipher cipher2 = Cipher.getInstance("Elgamal");
Cipher cipher2 = Cipher.getInstance(keyFactory2.getAlgorithm());
cipher2.init(Cipher.ENCRYPT_MODE, publicKey2);
byte[] result2 = cipher2.doFinal(src.getBytes());
System.out.println("私鑰加密、公鑰解密 ---- 加密:"
+ Base64.encodeBase64String(result2));
// 3.私鑰解密,、公鑰加密 ---- 解密
PKCS8EncodedKeySpec pkcs8EncodedKeySpec5 = new PKCS8EncodedKeySpec(
elGamalPrivateKey.getEncoded());
KeyFactory keyFactory5 = KeyFactory.getInstance("Elgamal");
PrivateKey privateKey5 = keyFactory5
.generatePrivate(pkcs8EncodedKeySpec5);
// Cipher cipher5 = Cipher.getInstance("Elgamal");
Cipher cipher5 = Cipher.getInstance(keyFactory5.getAlgorithm());
cipher5.init(Cipher.DECRYPT_MODE, privateKey5);
byte[] result5 = cipher5.doFinal(result2);
System.out.println("Elgamal 私鑰加密,、公鑰解密 ---- 解密:"
+ new String(result5));
} catch (Exception e) {
e.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
運(yùn)行結(jié)果:
應(yīng)用場(chǎng)景:
|