RSA非對稱加密簡析-java

来源:http://www.cnblogs.com/xq1314/archive/2017/11/28/7895471.html
-Advertisement-
Play Games

1 非對稱加密演算法 1.1 概述 1976年,美國學者Dime和Henman為解決信息公開傳送和密鑰管理問題,提出一種新的密鑰交換協議,允許在不安全的媒體上的通訊雙方交換信息,安全地達成一致的密鑰,這就是“公開密鑰系統”。 與對稱加密演算法不同,非對稱加密演算法需要兩個密鑰:公開密鑰(publickey ...


1 非對稱加密演算法

1.1 概述

  1976年,美國學者Dime和Henman為解決信息公開傳送和密鑰管理問題,提出一種新的密鑰交換協議,允許在不安全的媒體上的通訊雙方交換信息,安全地達成一致的密鑰,這就是“公開密鑰系統”。

  與對稱加密演算法不同,非對稱加密演算法需要兩個密鑰公開密鑰(publickey)和私有密鑰(privatekey)。公開密鑰與私有密鑰是一對,如果用公開密鑰對數據進行加密,只有用對應的私有密鑰才能解密;如果用私有密鑰對數據進行加密,那麼只有用對應的公開密鑰才能解密。因為加密和解密使用的是兩個不同的密鑰,所以這種演算法叫作非對稱加密演算法。  

1.2 加密流程

  如下圖所示,甲乙之間使用非對稱加密的方式完成了重要信息的安全傳輸。      非對稱加密工作過程簡要示意圖   1、乙方生成一對密鑰(公鑰和私鑰)並將公鑰向其它方公開。   2、得到該公鑰的甲方使用該密鑰對機密信息進行加密後再發送給乙方。   3、乙方再用自己保存的另一把專用密鑰(私鑰)對加密後的信息進行解密。乙方只能用其專用密鑰(私鑰)解密由對應的公鑰加密後的信息。   在傳輸過程中,即使攻擊者截獲了傳輸的密文,並得到了乙的公鑰,也無法破解密文,因為只有乙的私鑰才能解密密文。   同樣,如果乙要回覆加密信息給甲,那麼需要甲先公佈甲的公鑰給乙用於加密,甲自己保存甲的私鑰用於解密。

2 RSA加密演算法

2.1 概述

  RSA是目前最有影響力和最常用的公鑰加密演算法,它能夠抵抗到目前為止已知的絕大多數密碼攻擊,已被ISO推薦為公鑰數據加密標準

  RSA公開密鑰密碼體制。所謂的公開密鑰密碼體制就是使用不同的加密密鑰與解密密鑰,是一種“由已知加密密鑰推導出解密密鑰在計算上是不可行的”密碼體制。   在公開密鑰密碼體制中,加密密鑰(即公開密鑰)PK是公開信息,而解密密鑰(即秘密密鑰)SK是需要保密的。加密演算法E和解密演算法D也都是公開的。雖然解密密鑰SK是由公開密鑰PK決定的,但卻不能根據PK計算出SK。   正是基於這種理論,1978年出現了著名的RSA演算法,它通常是先生成一對RSA 密鑰,其中之一是保密密鑰,由用戶保存;另一個為公開密鑰,可對外公開,甚至可在網路伺服器中註冊。為提高保密強度,RSA密鑰至少為500位長,一般推薦使用1024位。這就使加密的計算量很大。為減少計算量,在傳送信息時,常採用傳統加密方法與公開密鑰加密方法相結合的方式,即信息採用改進的DES或IDEA對話密鑰加密,然後使用RSA密鑰加密對話密鑰和信息摘要。對方收到信息後,用不同的密鑰解密並可核對信息摘要。   RSA演算法是第一個能同時用於加密和數字簽名的演算法,也易於理解和操作。RSA是被研究得最廣泛的公鑰演算法,從提出到現今的三十多年裡,經歷了各種攻擊的考驗,逐漸為人們接受,普遍認為是目前最優秀的公鑰方案之一。

2.2  演算法實現過程

        1. 隨意選擇兩個大的質數p和q,p不等於q,計算N=pq。         2. 根據歐拉函數,不大於N且與N互質的整數個數為(p-1)(q-1)。         3. 選擇一個整數e與(p-1)(q-1)互質,並且e小於(p-1)(q-1)。         4. 用以下這個公式計算d:d× e ≡ 1 (mod (p-1)(q-1))。         5. 將p和q的記錄銷毀。           以上內容中,(N,e)是公鑰,(N,d)是私鑰。

 2.3 演算法缺點

  1)產生密鑰很麻煩,受到素數產生技術的限制,因而難以做到一次一密。

  2)安全性,RSA的安全性依賴於大數的因數分解,但並沒有從理論上證明破譯RSA的難度與大數分解難度等價,而且密碼學界多數人士傾向於因數分解不是NP問題。

  3)速度太慢,由於RSA 的分組長度太大,為保證安全性,n 至少也要 600 bits以上,使運算代價很高,尤其是速度較慢,較對稱密碼演算法慢幾個數量級;且隨著大數分解技術的發展,這個長度還在增加,不利於數據格式的標準化。

2.4 java代碼實現加解密

  1 package xin.dreaming.rsa;
  2 
  3 import java.io.ByteArrayOutputStream;
  4 import java.io.UnsupportedEncodingException;
  5 import java.security.Key;
  6 import java.security.KeyFactory;
  7 import java.security.KeyPair;
  8 import java.security.KeyPairGenerator;
  9 import java.security.NoSuchAlgorithmException;
 10 import java.security.interfaces.RSAPrivateKey;
 11 import java.security.interfaces.RSAPublicKey;
 12 import java.security.spec.PKCS8EncodedKeySpec;
 13 import java.security.spec.X509EncodedKeySpec;
 14 import java.util.HashMap;
 15 import java.util.Map;
 16 
 17 import javax.crypto.Cipher;
 18 
 19 import org.bouncycastle.util.encoders.Base64;
 20 
 21 /**
 22  * Rsa工具類
 23  * 
 24  * @author DREAMING.XIN
 25  *
 26  */
 27 public abstract class RsaUtils {
 28     /**
 29      * 生成公鑰私鑰對,使用預設模長1024。
 30      * 
 31      * @return Object[] : 0:公鑰( RSAPublicKey ),1:私鑰( RSAPrivateKey )
 32      */
 33 
 34     private static final int DEFAULT_KEY_LEN = 2048;
 35 
 36     public static Map<String, String> genKeyPair() {
 37         return genKeyPair(DEFAULT_KEY_LEN);
 38 
 39     }
 40 
 41     /**
 42      * 指定模長生成公私鑰對
 43      * 
 44      * @param modulus
 45      * @return
 46      */
 47     public static Map<String, String> genKeyPair(int modulus) {
 48         KeyPairGenerator keyPairGen;
 49         try {
 50             keyPairGen = KeyPairGenerator.getInstance("RSA");
 51             keyPairGen.initialize(modulus);
 52             KeyPair keyPair = keyPairGen.generateKeyPair();
 53 
 54             Map<String, String> keyMaps = new HashMap<String, String>();
 55             RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
 56             keyMaps.put("publicKey", new String(Base64.encode(publicKey.getEncoded())));
 57             RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
 58             keyMaps.put("privateKey", new String(Base64.encode(privateKey.getEncoded())));
 59 
 60             return keyMaps;
 61         } catch (NoSuchAlgorithmException e) {
 62             throw new RuntimeException(e);
 63         }
 64     }
 65 
 66     /**
 67      * 公鑰加密
 68      * 
 69      * @param publicKeyBytes
 70      * @param data
 71      * @param modulus
 72      *            公鑰模長,範圍512-2048。
 73      * @return
 74      */
 75     public static byte[] encryptByPublicKey(byte[] publicKeyBytes, byte[] data, int modulus) {
 76         try {
 77             // RSA最大加密明文大小
 78             int maxEncryptBlock = modulus / 8 - 11;
 79 
 80             X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyBytes);
 81             KeyFactory keyFactory = KeyFactory.getInstance("RSA");
 82             Key publicK = keyFactory.generatePublic(x509KeySpec);
 83             Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
 84             cipher.init(Cipher.ENCRYPT_MODE, publicK);
 85             int inputLen = data.length;
 86             ByteArrayOutputStream out = new ByteArrayOutputStream();
 87             int offSet = 0;
 88             byte[] cache;
 89             int i = 0;
 90             while (inputLen - offSet > 0) {
 91                 if (inputLen - offSet > maxEncryptBlock) {
 92                     cache = cipher.doFinal(data, offSet, maxEncryptBlock);
 93                 } else {
 94                     cache = cipher.doFinal(data, offSet, inputLen - offSet);
 95                 }
 96                 out.write(cache, 0, cache.length);
 97                 i++;
 98                 offSet = i * maxEncryptBlock;
 99             }
100             byte[] encryptedData = out.toByteArray();
101             out.close();
102             return encryptedData;
103         } catch (Exception e) {
104             throw new RuntimeException(e);
105         }
106 
107     }
108 
109     /**
110      * 公鑰加密,密鑰模長使用預設長度1024。
111      * 
112      * @param publicKeyBytes
113      *            公鑰RSAPublicKey getEncoded()
114      * @param data
115      *            要加密的位元組數組
116      */
117     public static byte[] encryptByPublicKey(byte[] publicKeyBytes, byte[] data) {
118         return encryptByPublicKey(publicKeyBytes, data, DEFAULT_KEY_LEN);
119     }
120 
121     /**
122      * 公鑰解密
123      * 
124      * @param publicKeyBytes
125      *            公鑰RSAPublicKey getEncoded()
126      * @param encryptedData
127      *            被(私鑰)加密過的位元組數組
128      * @param modulus
129      *            模長,範圍512-2048
130      * @return
131      */
132     public static byte[] decryptByPublicKey(byte[] publicKeyBytes, byte[] encryptedData, int modulus) {
133         // RSA最大解密密文大小
134         int maxDecryptBlock = modulus / 8;
135         try {
136             X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(publicKeyBytes);
137             KeyFactory keyFactory = KeyFactory.getInstance("RSA");
138             Key publicK = keyFactory.generatePublic(x509KeySpec);
139             Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
140             cipher.init(Cipher.DECRYPT_MODE, publicK);
141             int inputLen = encryptedData.length;
142             ByteArrayOutputStream out = new ByteArrayOutputStream();
143             int offSet = 0;
144             byte[] cache;
145             int i = 0;
146             // 對數據分段解密
147             while (inputLen - offSet > 0) {
148                 if (inputLen - offSet > maxDecryptBlock) {
149                     cache = cipher.doFinal(encryptedData, offSet, maxDecryptBlock);
150                 } else {
151                     cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
152                 }
153                 out.write(cache, 0, cache.length);
154                 i++;
155                 offSet = i * maxDecryptBlock;
156             }
157             byte[] decryptedData = out.toByteArray();
158             out.close();
159             return decryptedData;
160         } catch (Exception e) {
161             throw new RuntimeException(e);
162         }
163     }
164 
165     /**
166      * 公鑰解密,預設模長1024
167      * 
168      * @param publicKeyBytes
169      *            公鑰RSAPublicKey getEncoded()
170      * @param encryptedData
171      *            被(私鑰)加密過的位元組數組
172      */
173     public static byte[] decryptByPublicKey(byte[] publicKeyBytes, byte[] encryptedData) {
174         return decryptByPublicKey(publicKeyBytes, encryptedData, DEFAULT_KEY_LEN);
175     }
176 
177     /**
178      * 私鑰加密
179      * 
180      * @param privateKeyBytes
181      *            私鑰RSAPrivateKey getEncoded()
182      * @param data
183      *            要加密的位元組數組
184      * @param modulus
185      *            模長,範圍512-2048。
186      */
187     public static byte[] encryptByPrivateKey(byte[] privateKeyBytes, byte[] data, int modulus) {
188         try {
189             // RSA最大加密明文大小
190             int maxEncryptBlock = modulus / 8 - 11;
191 
192             PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
193             KeyFactory keyFactory = KeyFactory.getInstance("RSA");
194             Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
195             Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
196             cipher.init(Cipher.ENCRYPT_MODE, privateK);
197             int inputLen = data.length;
198             ByteArrayOutputStream out = new ByteArrayOutputStream();
199             int offSet = 0;
200             byte[] cache;
201             int i = 0;
202             while (inputLen - offSet > 0) {
203                 if (inputLen - offSet > maxEncryptBlock) {
204                     cache = cipher.doFinal(data, offSet, maxEncryptBlock);
205                 } else {
206                     cache = cipher.doFinal(data, offSet, inputLen - offSet);
207                 }
208                 out.write(cache, 0, cache.length);
209                 i++;
210                 offSet = i * maxEncryptBlock;
211             }
212             byte[] encryptedData = out.toByteArray();
213             out.close();
214             return encryptedData;
215         } catch (Exception e) {
216             throw new RuntimeException(e);
217         }
218     }
219 
220     /**
221      * 私鑰加密,預設模長1024。
222      * 
223      * @param privateKeyBytes
224      *            私鑰RSAPrivateKey getEncoded()
225      * @param data
226      *            要加密的位元組數組
227      */
228     public static byte[] encryptByPrivateKey(byte[] privateKeyBytes, byte[] data) {
229         return encryptByPrivateKey(privateKeyBytes, data, DEFAULT_KEY_LEN);
230     }
231 
232     /**
233      * 私鑰解密
234      * 
235      * @param privateKeyBytes
236      *            私鑰RSAPrivateKey getEncoded()
237      * @param encryptedData
238      *            被(公鑰)加密過的位元組數組
239      * @param modulus
240      *            模長,範圍512-2048
241      */
242     public static byte[] decryptByPrivateKey(byte[] privateKeyBytes, byte[] encryptedData, int modulus) {
243         try {
244             // RSA最大解密密文大小
245             int maxDecryptBlock = modulus / 8;
246 
247             PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
248             KeyFactory keyFactory = KeyFactory.getInstance("RSA");
249             Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
250             Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
251             cipher.init(Cipher.DECRYPT_MODE, privateK);
252             int inputLen = encryptedData.length;
253             ByteArrayOutputStream out = new ByteArrayOutputStream();
254             int offSet = 0;
255             byte[] cache;
256             int i = 0;
257             while (inputLen - offSet > 0) {
258                 if (inputLen - offSet > maxDecryptBlock) {
259                     cache = cipher.doFinal(encryptedData, offSet, maxDecryptBlock);
260                 } else {
261                     cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
262                 }
263                 out.write(cache, 0, cache.length);
264                 i++;
265                 offSet = i * maxDecryptBlock;
266             }
267             byte[] decryptedData = out.toByteArray();
268             out.close();
269             return decryptedData;
270         } catch (Exception e) {
271             throw new RuntimeException(e);
272         }
273     }
274 
275     /**
276      * 私鑰解密,預設模長1024。
277      * 
278      * @param privateKeyBytes
279      *            私鑰RSAPrivateKey getEncoded()
280      * @param encryptedData
281      *            被(公鑰)加密過的位元組數組
282      */
283     public static byte[] decryptByPrivateKey(byte[] privateKeyBytes, byte[] encryptedData) {
284         return decryptByPrivateKey(privateKeyBytes, encryptedData, DEFAULT_KEY_LEN);
285     }
286 
287     public static void main(String[] args) throws UnsupportedEncodingException {
288         // 加密原串
289         String value = "DREAMING.XIN";
290         System.out.println("加密原串 : ");
291         System.out.println(value);
292         System.out.println("------------------------------------------------------------------------------------------");
293         // 生成公私鑰對
294         Map<String, String> genKeyPair = genKeyPair();
295 
296         System.out.println("自行生成公私鑰對: ");
297         System.out.println(genKeyPair);
298         System.out.println("------------------------------------------------------------------------------------------");
299         byte[] encryptByPublicKey = encryptByPublicKey(Base64.decode(genKeyPair.get("publicKey").getBytes("utf-8")),
300                 value.getBytes());
301 
302         // 3、Base64編碼
303         byte[] encode = Base64.encode(encryptByPublicKey);
304 
305         System.out.println("最終加密結果: ");
306         String sign = new String(encode, "utf-8");
307         System.out.println(new String(encode, "utf-8"));
308         System.out.println("------------------------------------------------------------------------------------------");
309 
310         // 1、簽名密文->Base64解碼->RSA解密
311         byte[] signCipherArr = decryptByPrivateKey(Base64.decode(genKeyPair.get("privateKey").getBytes("utf-8")),
312                 Base64.decode(sign.getBytes("utf-8")));
313         System.out.println("解密結果: ");
314         System.out.println(new String (signCipherArr));
315         System.out.println("------------------------------------------------------------------------------------------");
316 
317     }
318 }

輸出結果:

加密原串 : 
DREAMING.XIN
------------------------------------------------------------------------------------------
自行生成公私鑰對: 
{publicKey=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkmRw1oug/LBmpkRsubsKoeEBQvGeRfUTMX8fTEuLJqKuWfHkB6HJ/08xf/BYhbL+GrUFk5DR/lbJdnD9SEx0ZDZHecrjj262T67izwf7d+rB3o7z5w/3Pk3p3Ye6Ns7SdGM6D8O6InUK4mQFSBKQhw25BqPzUQKb4DY/S+I2OAx1/qVB56Na+if5H9ttP8nhVVnQZXheTPh5Say0+ySFEBb1i2sxJQuwFLbtA9RkKNFSSB2+4sBrn5fRmemu6OGToR/WQ8KFa96+u9X2t41HPxa7dTF+g9btkEMWwbiXkPatjD9JaNXKKrueIQoDt/FKonUZQ0AafSs8r/xsrb4pfwIDAQAB, privateKey=MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCSZHDWi6D8sGamRGy5uwqh4QFC8Z5F9RMxfx9MS4smoq5Z8eQHocn/TzF/8FiFsv4atQWTkNH+Vsl2cP1ITHRkNkd5yuOPbrZPruLPB/t36sHejvPnD/c+Tendh7o2ztJ0YzoPw7oidQriZAVIEpCHDbkGo/NRApvgNj9L4jY4DHX+pUHno1r6J/kf220/yeFVWdBleF5M+HlJrLT7JIUQFvWLazElC7AUtu0D1GQo0VJIHb7iwGufl9GZ6a7o4ZOhH9ZDwoVr3r671fa3jUc/Frt1MX6D1u2QQxbBuJeQ9q2MP0lo1coqu54hCgO38UqidRlDQBp9Kzyv/Gytvil/AgMBAAECggEAWWoJ1bExIkYoXHO8qPDKfLduytHDZ11aXMgVeMdHddC1h3CMY/D47P0U8dz+ZKNAO1XH0ysIaD3gDXzT5z3zdWYF4CkBNxFbP25FUEjC2qrDwUk1RjNlQ2PZbRrCrUlEGBynUQuue+9bN435/9x+9E54bcrkCd37EUZxAMtpbG+bZ8/sizBsIQYfiKlGV3FJ68OTnkCzvjltYmzWn4q1a6CDqN40G6IfBJD1g1ENkkKJvi4hu6U7LhkpI3oil4+zZuxdGNphICz6L5CQVn01MahnfJlNszQD1H0sq/G9ymHtzYyvq6Fu8URjksw4doaqYVRuGuZL58qP33BNSzilwQKBgQDHZDC5YgViTmqAC9/GGnm1Cwhi8SkbsG0j6jCRx4e6nYgux4TOg9V6MdzXrm/w6X5ZtTTDPoB4vn+l2pX8SGyO1c2JfaL3w+iMahSAee6CFDbBzmiF5b+PiiKmYKzrNTtjPNkcDsrwErIhiyplgkj/+gsiVAepliJRUVTVeApvHwKBgQC79EUDck2kwSMsw3kXb/ZUIG6BPH0j/A0xn7SqcsVc/Rt3WFzfUJV9qCsN9TwGm3lk8fIsdXYoLrm96MlNOU3uNUzwwYwqespkdJ5R6iniWA+LAVuGgHhDYk84VFDxcldMLlG16O7uuIoUSeXdVwCChx1OllKFxsEj1z6X4mPZoQKBgQCy883zI/FXGK/m+kE9aFehUCSXwH+3lTFvEWnD/MNpjqdB7NnaC2JWiFf/z1QycS1wT/zp2retJrQj47nHMi0USPluk67nFhIpq69423ZfksrOSHVw7xFtP3n3vz6S3zTMzTjCQNiMfQsYpfFIJ5VjAERr6+TwpIlqWEd+S3152wKBgH+t6FP3ChepvCNkhpYNUODFR0wzsy8Gwk+7lhdT8A7DQi1IsY5iR6sc2mKY/TXf2A9i7IiXIrUZSMRhpp33F6GCQ8opMPaKg4LKVeJ/mARSnfxn56zvCMN9vSMe4/2hFvyBWrCgk+9HHUW7DZPWzlndP2NrapPF+N5IEhVLjVkBAoGABqIvu4Vpgg3viiE6PRmlA0iAnAz2ZnaqPS7Xk8+Ua44rCxTE62Vhm5ZbfQQzxlqFL/32NnJ3+zG/ONnWqdkGkvE5N/7NZg5CNzTPVqn/PbUAQ1L01yzcAETqr1dMLhGqlMMLkdbLO8VzoagVRuE+jSOwl3a+5Yq/cu0TMKLhrAE=}
------------------------------------------------------------------------------------------
最終加密結果: 
YmGXP+nSAY23ENUryid4zdE6KRAfFGhQWPJ4NAM1odZIEZCh5BbOtw437E85TdzABNE+NTDVogq+AI8WfAiD0yUpDukdRrZMb/IwG5k7xCgsVo0Tgt2SiH9bZFkvMaIIWH6d90muVtA/dyGHPSk/WmdgSl3QCcsZ3JAzMeadZwtL685eBhJD6hwXwKLfQj1OQBlLH3R9D5gBNGf36RHyi20LteTOKIR9lvMQPGbsnvspqi7t3xo5ajLpeuCr9azEovP0UFiiaxrkGLYMG2YM91r7JXUCn2gtVuDnXPFVVfOj84mN51229UJwQWBZe0BGPLSpROmOUZeWj2gjvuyqGg==
------------------------------------------------------------------------------------------
解密結果: 
DREAMING.XIN
------------------------------------------------------------------------------------------

2.5 java代碼實現加簽驗簽

  1 package xin.dreaming.rsa;
  2 
  3 import org.apache.commons.codec.binary.Base64;
  4 
  5 import javax.crypto.Cipher;
  6 import java.io.ByteArrayInputStream;
  7 import java.security.KeyFactory;
  8 import java.security.PrivateKey;
  9 import java.security.PublicKey;
 10 import java.security.Signature;
 11 import java.security.cert.Certificate;
 12 import java.security.cert.CertificateFactory;
 13 import java.security.spec.PKCS8EncodedKeySpec;
 14 
 15 /**
 16  * 
 17  * @author DREAMING.XIN
 18  *
 19  */
 20 public class RSAUtil {
 21 
 22     private static final String CHARSET = "UTF-8";
 23 
 24     private static final String algorithm = "SHA256withRSA";
 25 
 26     /**
 27      * 網聯請求報文簽名
 28      * 
 29      * @param privateKey
 30      *            機構私鑰字元串
 31      * @param content
 32      *            簽名原文
 33      * @return 簽名密文
 34      * @throws Exception
 35      */
 36     public static String sign(String privateKey, String content) throws Exception {
 37         Signature signature = Signature.getInstance(algorithm);
 38         signature.initSign(convertPrivateKey(privateKey));
 39         signature.update(content.getBytes(CHARSET));
 40         return Base64.encodeBase64String(signature.sign());
 41     }
 42 
 43     /**
 44      * 網聯返回報文驗簽
 45      * 
 46      * @param publicKey
 47      *            網聯公鑰字元串
 48      * @param content
 49      *            驗簽原文報文
 50      * @param signStr
 51      *            網聯返回簽名字元串
 52      * @return 驗簽結果
 53      * @throws Exception
 54      */
 55     public static boolean vertify(String publicKey, String content, String signStr) throws Exception {
 56         Signature signature = Signature.getInstance(algorithm);
 57         signature.initVerify(convertPublicKey(publicKey));
 58         signature.update(content.getBytes(CHARSET));
 59         return signature.verify(Base64.decodeBase64(signStr.getBytes(CHARSET)));
 60     }
 61 
 62     /**
 63      * 對稱密鑰公鑰加密
 64      * 
 65      * @param publicKey
 66      *            網聯公鑰字元串
 67      * @param content
 68      *            密鑰原文
 69      * @return 加密密文
 70      * @throws Exception
 71      */
 72     public static String encryptByPublicKey(String publicKey, String content) throws Exception {
 73         String result = null;
 74         try {
 75             Cipher cipher = cipher = Cipher.getInstance("RSA");
 76             cipher.init(Cipher.ENCRYPT_MODE, convertPublicKey(publicKey));
 77             byte[] encoded = cipher.doFinal(content.getBytes(CHARSET));
 78             result = Base64.encodeBase64String(encoded);
 79         } catch (Exception e) {
 80         
 81         }
 82         return result;
 83     }
 84 
 85     /**
 86      * 對稱密鑰密文解密
 87      * 
 88      * @param privateKey
 89      *            機構私鑰字元串
 90      * @param content
 91      *            網聯對稱密鑰密文
 92      * @return 對稱密鑰明文
 93      * @throws Exception
 94      */
 95     public static String decryptByPrivateKey(String privateKey, String content) throws Exception {
<

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...