国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

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

香港云服务器
服務(wù)器之家 - 編程語言 - JAVA教程 - JAVA加密算法- 非對稱加密算法(DH,RSA)的詳細(xì)介紹

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

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

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

非對稱密碼概念

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

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

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

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

需要兩個密鑰進(jìn)行加密或解密,分為公鑰和私鑰

特點:安全性高,速度慢

用途

【密鑰交換(DH)】

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

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 把源公鑰交給目標(biāo),目標(biāo)通過源公鑰,生成目標(biāo)公鑰和私鑰
//3 把目標(biāo)公鑰交給源
//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{
    //創(chuàng)建KeyPairGenerator的實例,選用DH算法
    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DH");
 
    //初始化密鑰長度,默認(rèn)1024,可選范圍512-65536 & 64的倍數(shù)
    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;
  }
 
  /**
   * 通過源公鑰 生成 目標(biāo)密鑰對
   * @param sourcePublicKey
   * @return
   * @throws Exception
   */
  public static Map<String,Object> initTargetKey(byte[] sourcePublicKey) throws Exception {
 
    KeyFactory keyFactory = KeyFactory.getInstance("DH");
 
    //通過源公鑰,生成keySpec,使用KeyFactory生成源PublicKey相關(guān)信息
    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相關(guān)信息
    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(aPublicKey);
    PublicKey publicKey = keyFactory.generatePublic(keySpec);
 
    //通過B私鑰,生成B PrivateKey相關(guān)信息
    PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(bPrivateKey);
    PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
 
    //通過KeyAgreement對A的PublicKey和B的PrivateKey進(jìn)行加密
    KeyAgreement keyAgreement = KeyAgreement.getInstance("DH");
    keyAgreement.init(privateKey);
    keyAgreement.doPhase(publicKey,true);
 
 
    return keyAgreement.generateSecret("AES").getEncoded();//算法使用對稱加密算法(DES,DESede,AES)
    //return keyAgreement.generateSecret();        // 也可以不選擇算法,使用默認(rèn)方法計算
  }
 
  //獲取公鑰字節(jié)數(shù)組
  public static byte[] getPublicKey(Map<String,Object> map){
    return ((DHPublicKey) map.get(PUBLIC_KEY)).getEncoded();
  }
 
  //獲取私鑰字節(jié)數(shù)組
  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("目標(biāo)公鑰:"+BytesToHex.fromBytesToHex(target_public_key));
    System.out.println("目標(biāo)私鑰:"+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("目標(biāo)本地密鑰:"+BytesToHex.fromBytesToHex(target_local_key));
  }
}

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

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

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

RSA的適用情景一:

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

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

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

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

RSA適用情景二:

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

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

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

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

實際上,簽名沒有必要特別長,一般情況下,簽名是定長的,要想定長,可以使用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的倍數(shù)
    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);
  }
 
  /**
   * 使用公鑰對數(shù)據(jù)進(jìn)行加密
   * @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 = "周杰倫-東風(fēng)破";
    Map<String, Object> keyMap = initKey();
 
    byte[] miwen = encrypt(data.getBytes(),getPublicKey(keyMap));
    System.out.println("加密后的內(nèi)容:"+BytesToHex.fromBytesToHex(miwen));
 
    byte[] plain = decrypt(miwen, getPrivateKey(keyMap));
    System.out.println("解密后的內(nèi)容:"+new String(plain));
 
  }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。

延伸 · 閱讀

精彩推薦
433
主站蜘蛛池模板: 成人网页在线 | 国产一区欧美 | 日韩欧美国产一区二区 | 亚洲五月婷婷 | 久久大陆 | 欧美色综合天天久久综合精品 | 在线观看成人 | 免费一级a毛片免费观看 | 欧美日韩国产在线播放 | 精品一区二区视频 | 日本中文在线视频 | 美日韩一区二区三区 | 激情中文网 | 伊人二区| 无码日韩精品一区二区免费 | 人人九九精 | 欧美a在线 | 黄a在线观看| 亚洲欧美在线观看 | 88tv成人| 国产一区二区三区四区hd | 一区二区三区高清 | 中文av电影 | 国产一区二区三区在线 | 午夜精品久久久久久久久久久久 | 色综合天天网 | 黄a一级| 能直接看的av网站 | 免费观看日本视频 | 久久亚洲国产精品 | 国产av毛片 | 国产亚洲欧美在线 | 欧美色视频在线观看 | av天天干 | 国产精品久久久久国产a级 最新国产视频 | 中文字幕久久网 | 日韩欧美专区 | 久久久久久国产精品 | 欧美视频二区 | 成人免费网站 | 免费观看a视频 |