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

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

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

服務器之家 - 編程語言 - JAVA教程 - Java加解密技術系列之RSA詳解

Java加解密技術系列之RSA詳解

2020-06-29 11:06crazyYong JAVA教程

出于安全考慮,網絡的傳輸中經常對傳輸數據做加密和編碼處理,本篇文章主要介紹Java加解密技術系列之RSA詳解,非常具有實用價值,需要的朋友可以參考下。

距離上一次寫博客感覺已經很長時間了,先吐槽一下,這個月以來,公司一直在加班,又是發版、上線,又是新項目太緊,具體的就不多說了。今天來說說非對稱加密真的是太重要了,我們的日常生活中,都離不開非對稱加密。

概念

在說 RSA 之前,首先聊聊什么是非對稱加密。在講對稱加密的時候,就曾經說過,對稱加密算法在加密和解密時使用的是同一個秘鑰,加解密雙方必須使用同一個密鑰才能進行正常的溝通。而非對稱加密則不然,非對稱加密算法需要兩個密鑰來進行加密和解密,分別是公鑰和私鑰。

需要注意的一點,這個公鑰和私鑰必須是一對的,如果用公鑰對數據進行加密,那么只有使用對應的私鑰才能解密,反之亦然。由于加密和解密使用的是兩個不同的密鑰,因此,這種算法叫做非對稱加密算法。

工作過程

如下圖,甲乙之間使用非對稱加密的方式傳輸數據。

Java加解密技術系列之RSA詳解

在非對稱加密中使用的主要算法有:RSA、Elgamal、背包算法、Rabin、D-H、ECC(橢圓曲線加密算法)等。今天主要是介紹 RSA ,至于其他的算法,后續會選擇幾個進行介紹。

RSA

其實,在早在 1978 年的時候,RSA就已經出現了,它是第一個既能用于數據加密也能用于數字簽名的算法。它易于理解和操作,也很流行。其原理就如上面的工作過程所述。

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
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
import com.google.common.collect.Maps;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
 
import javax.crypto.Cipher;
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.Map;
 
/**
 * Created by xiang.li on 2015/3/3.
 * RSA 加解密工具類
 */
public class RSA {
  /**
   * 定義加密方式
   */
  private final static String KEY_RSA = "RSA";
  /**
   * 定義簽名算法
   */
  private final static String KEY_RSA_SIGNATURE = "MD5withRSA";
  /**
   * 定義公鑰算法
   */
  private final static String KEY_RSA_PUBLICKEY = "RSAPublicKey";
  /**
   * 定義私鑰算法
   */
  private final static String KEY_RSA_PRIVATEKEY = "RSAPrivateKey";
 
  /**
   * 初始化密鑰
   * @return
   */
  public static Map<String, Object> init() {
    Map<String, Object> map = null;
    try {
      KeyPairGenerator generator = KeyPairGenerator.getInstance(KEY_RSA);
      generator.initialize(1024);
      KeyPair keyPair = generator.generateKeyPair();
      // 公鑰
      RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
      // 私鑰
      RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
      // 將密鑰封裝為map
      map = Maps.newHashMap();
      map.put(KEY_RSA_PUBLICKEY, publicKey);
      map.put(KEY_RSA_PRIVATEKEY, privateKey);
    } catch (NoSuchAlgorithmException e) {
      e.printStackTrace();
    }
    return map;
  }
 
  /**
   * 用私鑰對信息生成數字簽名
   * @param data 加密數據
   * @param privateKey 私鑰
   * @return
   */
  public static String sign(byte[] data, String privateKey) {
    String str = "";
    try {
      // 解密由base64編碼的私鑰
      byte[] bytes = decryptBase64(privateKey);
      // 構造PKCS8EncodedKeySpec對象
      PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(bytes);
      // 指定的加密算法
      KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
      // 取私鑰對象
      PrivateKey key = factory.generatePrivate(pkcs);
      // 用私鑰對信息生成數字簽名
      Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
      signature.initSign(key);
      signature.update(data);
      str = encryptBase64(signature.sign());
    } catch (Exception e) {
      e.printStackTrace();
    }
    return str;
  }
 
  /**
   * 校驗數字簽名
   * @param data 加密數據
   * @param publicKey 公鑰
   * @param sign 數字簽名
   * @return 校驗成功返回true,失敗返回false
   */
  public static boolean verify(byte[] data, String publicKey, String sign) {
    boolean flag = false;
    try {
      // 解密由base64編碼的公鑰
      byte[] bytes = decryptBase64(publicKey);
      // 構造X509EncodedKeySpec對象
      X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
      // 指定的加密算法
      KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
      // 取公鑰對象
      PublicKey key = factory.generatePublic(keySpec);
      // 用公鑰驗證數字簽名
      Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
      signature.initVerify(key);
      signature.update(data);
      flag = signature.verify(decryptBase64(sign));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return flag;
  }
 
  /**
   * 私鑰解密
   * @param data 加密數據
   * @param key 私鑰
   * @return
   */
  public static byte[] decryptByPrivateKey(byte[] data, String key) {
    byte[] result = null;
    try {
      // 對私鑰解密
      byte[] bytes = decryptBase64(key);
      // 取得私鑰
      PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
      KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
      PrivateKey privateKey = factory.generatePrivate(keySpec);
      // 對數據解密
      Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
      cipher.init(Cipher.DECRYPT_MODE, privateKey);
      result = cipher.doFinal(data);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return result;
  }
 
  /**
   * 私鑰解密
   * @param data 加密數據
   * @param key 公鑰
   * @return
   */
  public static byte[] decryptByPublicKey(byte[] data, String key) {
    byte[] result = null;
    try {
      // 對公鑰解密
      byte[] bytes = decryptBase64(key);
      // 取得公鑰
      X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
      KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
      PublicKey publicKey = factory.generatePublic(keySpec);
      // 對數據解密
      Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
      cipher.init(Cipher.DECRYPT_MODE, publicKey);
      result = cipher.doFinal(data);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return result;
  }
 
  /**
   * 公鑰加密
   * @param data 待加密數據
   * @param key 公鑰
   * @return
   */
  public static byte[] encryptByPublicKey(byte[] data, String key) {
    byte[] result = null;
    try {
      byte[] bytes = decryptBase64(key);
      // 取得公鑰
      X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
      KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
      PublicKey publicKey = factory.generatePublic(keySpec);
      // 對數據加密
      Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
      cipher.init(Cipher.ENCRYPT_MODE, publicKey);
      result = cipher.doFinal(data);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return result;
  }
 
  /**
   * 私鑰加密
   * @param data 待加密數據
   * @param key 私鑰
   * @return
   */
  public static byte[] encryptByPrivateKey(byte[] data, String key) {
    byte[] result = null;
    try {
      byte[] bytes = decryptBase64(key);
      // 取得私鑰
      PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
      KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
      PrivateKey privateKey = factory.generatePrivate(keySpec);
      // 對數據加密
      Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
      cipher.init(Cipher.ENCRYPT_MODE, privateKey);
      result = cipher.doFinal(data);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return result;
  }
 
  /**
   * 獲取公鑰
   * @param map
   * @return
   */
  public static String getPublicKey(Map<String, Object> map) {
    String str = "";
    try {
      Key key = (Key) map.get(KEY_RSA_PUBLICKEY);
      str = encryptBase64(key.getEncoded());
    } catch (Exception e) {
      e.printStackTrace();
    }
    return str;
  }
 
  /**
   * 獲取私鑰
   * @param map
   * @return
   */
  public static String getPrivateKey(Map<String, Object> map) {
    String str = "";
    try {
      Key key = (Key) map.get(KEY_RSA_PRIVATEKEY);
      str = encryptBase64(key.getEncoded());
    } catch (Exception e) {
      e.printStackTrace();
    }
    return str;
  }
 
  /**
   * BASE64 解密
   * @param key 需要解密的字符串
   * @return 字節數組
   * @throws Exception
   */
  public static byte[] decryptBase64(String key) throws Exception {
    return (new BASE64Decoder()).decodeBuffer(key);
  }
 
  /**
   * BASE64 加密
   * @param key 需要加密的字節數組
   * @return 字符串
   * @throws Exception
   */
  public static String encryptBase64(byte[] key) throws Exception {
    return (new BASE64Encoder()).encodeBuffer(key);
  }
 
  /**
   * 測試方法
   * @param args
   */
  public static void main(String[] args) {
    String privateKey = "";
    String publicKey = "";
    // 生成公鑰私鑰
    Map<String, Object> map = init();
    publicKey = getPublicKey(map);
    privateKey = getPrivateKey(map);
    System.out.println("公鑰: \n\r" + publicKey);
    System.out.println("私鑰: \n\r" + privateKey);
    System.out.println("公鑰加密--------私鑰解密");
    String word = "你好,世界!";
    byte[] encWord = encryptByPublicKey(word.getBytes(), publicKey);
    String decWord = new String(decryptByPrivateKey(encWord, privateKey));
    System.out.println("加密前: " + word + "\n\r" + "解密后: " + decWord);
    System.out.println("私鑰加密--------公鑰解密");
    String english = "Hello, World!";
    byte[] encEnglish = encryptByPrivateKey(english.getBytes(), privateKey);
    String decEnglish = new String(decryptByPublicKey(encEnglish, publicKey));
    System.out.println("加密前: " + english + "\n\r" + "解密后: " + decEnglish);
    System.out.println("私鑰簽名——公鑰驗證簽名");
    // 產生簽名
    String sign = sign(encEnglish, privateKey);
    System.out.println("簽名:\r" + sign);
    // 驗證簽名
    boolean status = verify(encEnglish, publicKey, sign);
    System.out.println("狀態:\r" + status);
  }
}

加解密結果

Java加解密技術系列之RSA詳解

結束語

其實,看似很復雜的過程,用一句話就可以描述:使用公鑰加密、私鑰解密,完成了乙方到甲方的一次數據傳遞,通過私鑰加密、公鑰解密,同時通過私鑰簽名、公鑰驗證簽名,完成了一次甲方到乙方的數據傳遞與驗證,兩次數據傳遞完成一整套的數據交互。

非對稱加密算法的出現,就是為了解決只有一把密鑰的加解密,只要這一把密鑰丟失或者被公開,那么加密數據就很容易被攻擊。同時,也正是由于非對稱加密算法的出現,才有了后面的數字簽名、數字證書等等。

好了,今天就到這吧,下一篇繼續非對稱加密,至于哪一種,到時候就知道了,這里先保密

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产日皮视频 | 黄网站在线观看 | 国产成人影院 | 欧美日韩精品一区二区三区 | 亚洲一区二区久久 | 午夜精品福利在线观看 | 天天艹 | 91粉色视频| 黄网站色 | 高清hd写真福利在线播放 | 色婷婷av久久久久久久 | 超碰人人操 | 日韩国产一区 | 欧美日韩精品免费 | 99视频在线| 中文字幕欧美激情 | 中文字幕在线观看视频地址二 | 精品伊人| 亚洲久久久久 | 欧美自拍偷拍 | 91视频国产精品 | 亚洲精品综合 | av在线一区二区 | 欧美亚洲一 | 一级大毛片 | 久久97视频 | 久国产精品韩国三级视频 | 欧美日韩精品一区二区三区 | 中文字幕三区 | 狠狠天天| 免费观看一级视频 | 国产成人精品久久二区二区 | av在线免费观看一区二区 | 精品国产91亚洲一区二区三区www | 久久伊人久久 | 欧美一级二级视频 | 国产在亚洲 线视频播放 | 伦理午夜电影免费观看 | 日本天堂在线 | 欧美二区三区 | 国产精品久久久久久久 |