激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

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

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));
 
  }
}

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

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 精品一二三区视频 | 九九视频在线观看黄 | 成人午夜在线免费观看 | 欧美一及 | 国产精品免费一区二区三区四区 | 黄色网址在线免费 | 性色tv| 亚洲第一综合 | 中文日韩欧美 | 日本一区二区不卡在线观看 | 国产精品久久久久久影视 | 精品一区免费 | 成人性视频在线 | 91精品动漫在线观看 | 国产精品久久久久久久久久大牛 | 亚洲一区二区三区在线免费观看 | 久久av免费 | 99ri在线 | 91看片资源 | 欧美 日韩 亚洲 中文 | 免费看h网站 | 久久精品视频国产 | 最新中文字幕日本 | 国产欧美在线观看不卡一 | 精品成人免费视频 | 国产精品久久久乱弄 | 欧美性黄| 偿还电影免费 | 99精彩视频在线观看 | 欧美乱淫 | 天天曰夜夜操 | 久久久久久久久淑女av国产精品 | 美女福利视频国产 | 艹艹艹逼 | 国产一区二区免费看 | 色网站免费观看 | 国产一区二区成人在线 | 日本成人一区二区 | 毛片免费在线观看视频 | 一级免费观看 | 亚洲一区二区中文字幕在线观看 |