一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - JAVA加密算法- 非對稱加密算法(DH,RSA)的詳細介紹

JAVA加密算法- 非對稱加密算法(DH,RSA)的詳細介紹

2020-06-29 11:12我有切糕 JAVA教程

這篇文章主要介紹了JAVA加密算法- 非對稱加密算法(DH,RSA),詳細介紹了DH,RSA的用法和示例,需要的朋友可以了解一下。

非對稱密碼概念

1、與對稱加密算法的主要差別在于,加密和解密的密鑰不相同,一個公開(公鑰),一個保密(私鑰)。主要解決了對稱加密算法密鑰分配管理的問題,提高了算法安全性。

2、非對稱加密算法的加密、解密的效率比較低。在算法設計上,非對稱加密算法對待加密的數據長度有著苛刻的要求。例如RSA算法要求待加密的數據不得大于53個字節。

3、非對稱加密算法主要用于 交換對稱加密算法的密鑰,而非數據交換

4、java6提供實現了DH和RSA兩種算法。Bouncy Castle提供了E1Gamal算法支持。除了上述三種算法還有一個ECC算法,目前沒有相關的開源組件提供支持

需要兩個密鑰進行加密或解密,分為公鑰和私鑰

特點:安全性高,速度慢

用途

【密鑰交換(DH)】

雙方在沒有確定共同密鑰的情況下,生成密鑰,不提供加密工作,加解密還需要其他對稱加密算法實現

DH算法示例

?
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
import javax.crypto.KeyAgreement;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;
 
//1 生成源密鑰
//2 把源公鑰交給目標,目標通過源公鑰,生成目標公鑰和私鑰
//3 把目標公鑰交給源
//4 雙方使用對方的公鑰和和自己的私鑰,生成本地密鑰
//5 如果雙方生成本地密鑰相同則完成密鑰交換
public class DHUtil {
 
  public static final String PUBLIC_KEY = "DH_Public_Key";
  public static final String PRIVATE_KEY = "DH_Private_key";
 
  /**
   * 生成源密鑰對
   * @return
   * @throws Exception
   */
  public static Map<String,Object> initSourceKey() throws Exception{
    //創建KeyPairGenerator的實例,選用DH算法
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
 
    //初始化密鑰長度,默認1024,可選范圍512-65536 & 64的倍數
    keyPairGenerator.initialize(1024);
 
    //生成密鑰對
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
    DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
 
    //將密鑰對放入Map
    Map<String,Object> keyMap = new HashMap<String, Object>();
    keyMap.put(PUBLIC_KEY, dhPublicKey);
    keyMap.put(PRIVATE_KEY, dhPrivateKey);
    return keyMap;
  }
 
  /**
   * 通過源公鑰 生成 目標密鑰對
   * @param sourcePublicKey
   * @return
   * @throws Exception
   */
  public static Map<String,Object> initTargetKey(byte[] sourcePublicKey) throws Exception {
 
    KeyFactory keyFactory = KeyFactory.getInstance("DH");
 
    //通過源公鑰,生成keySpec,使用KeyFactory生成源PublicKey相關信息
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(sourcePublicKey);
    DHPublicKey sourcePublic = (DHPublicKey) keyFactory.generatePublic(keySpec);
 
    DHParameterSpec dhPublicKeyParams = sourcePublic.getParams();
 
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
    keyPairGenerator.initialize(dhPublicKeyParams);
 
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    DHPublicKey dhPublicKey = (DHPublicKey) keyPair.getPublic();
    DHPrivateKey dhPrivateKey = (DHPrivateKey) keyPair.getPrivate();
 
    //將密鑰對放入Map
    Map<String,Object> keyMap = new HashMap<String, Object>();
    keyMap.put(PUBLIC_KEY, dhPublicKey);
    keyMap.put(PRIVATE_KEY, dhPrivateKey);
    return keyMap;
  }
 
  /**
   * 使用一方的公鑰和另一方的私鑰,生成本地密鑰
   * @return
   */
  public static byte[] generateLocalSecretKey(byte[] aPublicKey, byte[] bPrivateKey) throws Exception{
    KeyFactory keyFactory = KeyFactory.getInstance("DH");
 
    //通過A公鑰,生成keySpec,使用KeyFactory生成A PublicKey相關信息
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(aPublicKey);
    PublicKey publicKey = keyFactory.generatePublic(keySpec);
 
    //通過B私鑰,生成B PrivateKey相關信息
    PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bPrivateKey);
    PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
 
    //通過KeyAgreement對A的PublicKey和B的PrivateKey進行加密
    KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
    keyAgreement.init(privateKey);
    keyAgreement.doPhase(publicKey,true);
 
 
    return keyAgreement.generateSecret("AES").getEncoded();//算法使用對稱加密算法(DES,DESede,AES)
    //return keyAgreement.generateSecret();        // 也可以不選擇算法,使用默認方法計算
  }
 
  //獲取公鑰字節數組
  public static byte[] getPublicKey(Map<String,Object> map){
    return ((DHPublicKey) map.get(PUBLIC_KEY)).getEncoded();
  }
 
  //獲取私鑰字節數組
  public static byte[] getPrivateKey(Map<String,Object> map){
    return ((DHPrivateKey) map.get(PRIVATE_KEY)).getEncoded();
  }
 
  public static void main(String[] args) throws Exception {
 
    byte[] source_public_key;
    byte[] source_private_key;
    byte[] source_local_key;
 
    byte[] target_public_key;
    byte[] target_private_key;
    byte[] target_local_key;
 
    Map<String, Object> sourceKey = initSourceKey();
    source_public_key = getPublicKey(sourceKey);
    source_private_key = getPrivateKey(sourceKey);
 
    System.out.println("源公鑰:"+BytesToHex.fromBytesToHex(source_public_key));
    System.out.println("源私鑰:"+BytesToHex.fromBytesToHex(source_private_key));
 
    Map<String, Object> targetKey = initTargetKey(getPublicKey(sourceKey));
    target_public_key = getPublicKey(targetKey);
    target_private_key = getPrivateKey(targetKey);
 
    System.out.println("目標公鑰:"+BytesToHex.fromBytesToHex(target_public_key));
    System.out.println("目標私鑰:"+BytesToHex.fromBytesToHex(target_private_key));
 
    source_local_key = generateLocalSecretKey(target_public_key, source_private_key);
    target_local_key = generateLocalSecretKey(source_public_key, target_private_key);
 
    System.out.println("源本地密鑰:"+BytesToHex.fromBytesToHex(source_local_key));
    System.out.println("目標本地密鑰:"+BytesToHex.fromBytesToHex(target_local_key));
  }
}

【加密/解密(RSA)】【數字簽名(RSA)】

RSA算法晚于DH算法,這五個字母全都是人名首字母.DH算法是第一個非對稱密碼體系.

RSA算法運算速度慢,不適宜加密大量數據.一種解決方案是,將RSA跟對稱加密方式混合使用,將數據使用對稱加密方式加密,對稱加密的密鑰使用RSA算法加密,因為密鑰很短,所以時間費不了太多.實際上,對稱加密方式唯一的弊端就是密鑰不好傳遞,對稱加密方式也很難破解.

RSA的適用情景一:

(1)服務器生成一個公鑰和一個私鑰,把公鑰公開了.

(2)客戶端使用公鑰把數據進行加密,上交服務器.別人是沒法理解加密后的數據的.

(3)服務器使用私鑰將數據解密,查看用戶提交的數據.

這種情景下,公鑰像是一個信箱,每個人都可以往這個信箱里面放信,但是這個信箱里面的信只有掌握信箱鑰匙的人才能開箱查看.

RSA適用情景二:

(1)皇上生成一個公鑰和一個密鑰,把公鑰公開了.

(2)皇上發布了一封詔書,昭告天下.詔書右下角有兩串數字,第一串數字是一個隨機串,第二串數字是用私鑰加密第一串數字所得的結果.

(3)有人不相信這詔書是皇上寫的,就把第二串數字使用公鑰解密,解密之后發現跟第一串數字一樣,說明確實是皇上寫的,因為一般人沒有密鑰,也就沒法加密那些能夠用公鑰解密的數據.

這種情境下,公鑰用于解密,私鑰用于加密,這可以用于發布公告時,證明這個公告確實是某個人發的.相當于簽名.

實際上,簽名沒有必要特別長,一般情況下,簽名是定長的,要想定長,可以使用MessageDigest算法,如MD5和SHA系列.所以就有了多種簽名算法,如MD5withRSA等.

RSA 加密/解密 示例

?
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
import javax.crypto.Cipher;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.util.HashMap;
import java.util.Map;
 
/**
 * RSA加密工具
 */
public class RSAUtil {
 
  public static final String PUBLIC_KEY = "RSA_Public_Key";
  public static final String PRIVATE_KEY = "RSA_Private_Key";
 
  /**
   * 初始化密鑰
   * @return
   * @throws Exception
   */
  public static Map<String,Object> initKey() throws Exception{
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
    keyPairGenerator.initialize(1024);//512-65536 & 64的倍數
    KeyPair keyPair = keyPairGenerator.generateKeyPair();
    RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
    RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
 
    Map<String,Object> keyMap = new HashMap<String, Object>();
    keyMap.put(PUBLIC_KEY, publicKey);
    keyMap.put(PRIVATE_KEY, privateKey);
    return keyMap;
  }
 
  public static RSAPublicKey getPublicKey(Map<String,Object> keyMap) {
    return (RSAPublicKey) keyMap.get(PUBLIC_KEY);
  }
 
  public static RSAPrivateKey getPrivateKey(Map<String,Object> keyMap){
    return (RSAPrivateKey) keyMap.get(PRIVATE_KEY);
  }
 
  /**
   * 使用公鑰對數據進行加密
   * @param data
   * @param publicKey
   * @return
   * @throws Exception
   */
  public static byte[] encrypt(byte[] data, RSAPublicKey publicKey) throws Exception{
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.ENCRYPT_MODE,publicKey);
    return cipher.doFinal(data);
  }
 
  /**
   * 使用私鑰解密
   * @param data
   * @param privateKey
   * @return
   * @throws Exception
   */
  public static byte[] decrypt(byte[] data, RSAPrivateKey privateKey) throws Exception{
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE,privateKey);
    return cipher.doFinal(data);
  }
 
  public static void main(String[] args) throws Exception {
    String data = "周杰倫-東風破";
    Map<String, Object> keyMap = initKey();
 
    byte[] miwen = encrypt(data.getBytes(),getPublicKey(keyMap));
    System.out.println("加密后的內容:"+BytesToHex.fromBytesToHex(miwen));
 
    byte[] plain = decrypt(miwen, getPrivateKey(keyMap));
    System.out.println("解密后的內容:"+new String(plain));
 
  }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品性影院一区二区三区内射 | 精品亚洲永久免费精品 | 欧美人体高清在线观看ggogo | 欧美国产合集在线视频 | 亚洲成在人网站天堂一区二区 | 黑人女性猛交xxxxxⅹxx | 精品欧美一区二区精品久久 | 99精品在线免费 | 国内剧情麻豆 | 亚久久伊人精品青青草原2020 | 国产激情一区二区三区成人91 | 疯狂激吻添下边小说 | 亚洲欧洲综合 | 欧美国产精品 | 国产极品麻豆91在线 | 男人把大ji巴放进男人免费视频 | 女生被草 | 高h生子双性美人受 | 午夜福利合集1000在线 | 日韩成人一级 | 成人国产在线视频在线观看 | 欧洲vodafone精品性 | 超级乱淫变态伦短篇小说全集 | 国产成人在线视频播放 | 男人操美女逼视频 | 精品国产免费观看一区高清 | 国产高清视频网站 | 亚洲国产区中文在线观看 | 女女性恋爱视频入口 | 亚洲欧美7777| 国产精品亚洲va在线观看 | 成人永久免费 | 白丝vk丨tk失禁 | 日韩一区二三区无 | 亚洲国产精品一区二区久久 | 日本高清二三四本2021 | 日韩欧美一区二区三区免费看 | 黄网在线观看免费网站台湾swag | 日本免费不卡在线一区二区三区 | 惊弦45集免费看 | 青青青视频蜜桃一区二区 |