RSA 數據加密和數字簽名算法

複製代碼
  1 package com.ice.webos.util.security;
2
3 import java.math.BigInteger;
4 import java.security.Key;
5 import java.security.KeyFactory;
6 import java.security.KeyPair;
7 import java.security.KeyPairGenerator;
8 import java.security.PrivateKey;
9 import java.security.PublicKey;
10 import java.security.Signature;
11 import java.security.interfaces.RSAPrivateKey;
12 import java.security.interfaces.RSAPublicKey;
13 import java.security.spec.PKCS8EncodedKeySpec;
14 import java.security.spec.X509EncodedKeySpec;
15 import java.util.HashMap;
16 import java.util.Map;
17
18 import javax.crypto.Cipher;
19
20 /**
21 * RSA 這種算法1978年就出現了,它是第一個既能用於數據加密也能用於數字簽名的算法。<br>
22 * RSA同時有兩把鑰匙,公鑰與私鑰。同時支持數字簽名。<br>
23 * 數字簽名的意義在於,對傳輸過來的數據進行校驗。確保數據在傳輸過程當中不被修改。
24 * <ul>
25 * 流程分析:
26 * <li>甲方構建密鑰對兒,將公鑰公佈給乙方,將私鑰保留。</li>
27 * <li>甲方使用私鑰加密數據,而後用私鑰對加密後的數據簽名,發送給乙方簽名以及加密後的數據;乙方使用公鑰、簽名來驗證待解密數據是否有效,若是有效使用公鑰對數據解密。</li>
28 * <li>乙方使用公鑰加密數據,向甲方發送通過加密後的數據;甲方得到加密數據,經過私鑰解密。 </li>
29 * <ul>
30 *
31 * @author Ice_Liu
32 *
33 */
34 public class RSACryptUtil {
35 public static final String KEY_ALGORITHM = "RSA";
36 public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
37 private static final String PUBLIC_KEY = "RSAPublicKey";
38 private static final String PRIVATE_KEY = "RSAPrivateKey";
39
40 /**
41 * 用私鑰對信息生成數字簽名
42 *
43 * @param data
44 * 加密數據
45 * @param privateKey
46 * 私鑰
47 *
48 * @return
49 * @throws Exception
50 */
51 public static String sign(byte[] data, String privateKey) throws Exception {
52 // 解密由base64編碼的私鑰
53 byte[] keyBytes = CryptUtil.decryptBASE64(privateKey);
54 // 構造PKCS8EncodedKeySpec對象
55 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
56 // KEY_ALGORITHM 指定的加密算法
57 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
58 // 取私鑰匙對象
59 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
60 // 用私鑰對信息生成數字簽名
61 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
62 signature.initSign(priKey);
63 signature.update(data);
64 return CryptUtil.encryptBASE64(signature.sign());
65 }
66
67 /**
68 * 校驗數字簽名
69 *
70 * @param data
71 * 加密數據
72 * @param publicKey
73 * 公鑰
74 * @param sign
75 * 數字簽名
76 *
77 * @return 校驗成功返回true 失敗返回false
78 * @throws Exception
79 *
80 */
81 public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
82 // 解密由base64編碼的公鑰
83 byte[] keyBytes = CryptUtil.decryptBASE64(publicKey);
84 // 構造X509EncodedKeySpec對象
85 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
86 // KEY_ALGORITHM 指定的加密算法
87 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
88 // 取公鑰匙對象
89 PublicKey pubKey = keyFactory.generatePublic(keySpec);
90 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
91 signature.initVerify(pubKey);
92 signature.update(data);
93 // 驗證簽名是否正常
94 return signature.verify(CryptUtil.decryptBASE64(sign));
95 }
96
97 /**
98 * 解密<br>
99 * 用私鑰解密
100 *
101 * @param data
102 * @param key
103 * @return
104 * @throws Exception
105 */
106 public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception {
107 // 對密鑰解密
108 byte[] keyBytes = CryptUtil.decryptBASE64(key);
109 // 取得私鑰
110 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
111 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
112 Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
113 // 對數據解密
114 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
115 cipher.init(Cipher.DECRYPT_MODE, privateKey);
116 return cipher.doFinal(data);
117 }
118
119 /**
120 * 解密<br>
121 * 用私鑰解密
122 *
123 * @param data
124 * @param key
125 * @return
126 * @throws Exception
127 */
128 public static byte[] decryptByPublicKey(byte[] data, String key) throws Exception {
129 // 對密鑰解密
130 byte[] keyBytes = CryptUtil.decryptBASE64(key);
131 // 取得公鑰
132 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
133 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
134 Key publicKey = keyFactory.generatePublic(x509KeySpec);
135 // 對數據解密
136 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
137 cipher.init(Cipher.DECRYPT_MODE, publicKey);
138 return cipher.doFinal(data);
139 }
140
141 /**
142 * 加密<br>
143 * 用公鑰加密
144 *
145 * @param data
146 * @param key
147 * @return
148 * @throws Exception
149 */
150 public static byte[] encryptByPublicKey(byte[] data, String key) throws Exception {
151 // 對公鑰解密
152 byte[] keyBytes = CryptUtil.decryptBASE64(key);
153 // 取得公鑰
154 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
155 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
156 Key publicKey = keyFactory.generatePublic(x509KeySpec);
157 // 對數據加密
158 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
159 cipher.init(Cipher.ENCRYPT_MODE, publicKey);
160 return cipher.doFinal(data);
161 }
162
163 /**
164 * 加密<br>
165 * 用私鑰加密
166 *
167 * @param data
168 * @param key
169 * @return
170 * @throws Exception
171 */
172 public static byte[] encryptByPrivateKey(byte[] data, String key) throws Exception {
173 // 對密鑰解密
174 byte[] keyBytes = CryptUtil.decryptBASE64(key);
175 // 取得私鑰
176 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
177 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
178 Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
179 // 對數據加密
180 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
181 cipher.init(Cipher.ENCRYPT_MODE, privateKey);
182 return cipher.doFinal(data);
183 }
184
185 /**
186 * 取得私鑰
187 *
188 * @param keyMap
189 * @return
190 * @throws Exception
191 */
192 public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
193 Key key = (Key) keyMap.get(PRIVATE_KEY);
194 return CryptUtil.encryptBASE64(key.getEncoded());
195 }
196
197 /**
198 * 取得公鑰
199 *
200 * @param keyMap
201 * @return
202 * @throws Exception
203 */
204 public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
205 Key key = (Key) keyMap.get(PUBLIC_KEY);
206 return CryptUtil.encryptBASE64(key.getEncoded());
207 }
208
209 /**
210 * 初始化密鑰
211 *
212 * @return
213 * @throws Exception
214 */
215 public static Map<String, Object> initKey() throws Exception {
216 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
217 keyPairGen.initialize(1024);
218 KeyPair keyPair = keyPairGen.generateKeyPair();
219 // 公鑰
220 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
221 // 私鑰
222 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
223 Map<String, Object> keyMap = new HashMap<String, Object>(2);
224 keyMap.put(PUBLIC_KEY, publicKey);
225 keyMap.put(PRIVATE_KEY, privateKey);
226 return keyMap;
227 }
228
229 /**
230 * @param args
231 */
232 public static void main(String[] args) {
233 try {
234 PBECryptUtil.main(args);
235 System.out.println("****************************************");
236 System.out.println("=====RSA加密與解密=====");
237 // 初始化公鑰,私鑰
238 Map<String, Object> keyMap = initKey();
239 String publicKey = RSACryptUtil.getPublicKey(keyMap);
240 String privateKey = RSACryptUtil.getPrivateKey(keyMap);
241 System.out.println("公鑰: \n\r" + publicKey);
242 System.out.println("私鑰: \n\r" + privateKey);
243 System.out.println("公鑰加密——私鑰解密");
244 String inputStr = "阿伯才的覆蓋";
245 byte[] data = inputStr.getBytes("UTF-8");
246 // 公鑰加密
247 byte[] encodedData = RSACryptUtil.encryptByPublicKey(data, publicKey);
248 System.out.println("公鑰加密後:" + new BigInteger(encodedData).toString(32));
249 // 私鑰解密
250 byte[] decodedData = RSACryptUtil.decryptByPrivateKey(encodedData, privateKey);
251 String outputStr = new String(decodedData, "UTF-8");
252 System.out.println("加密前: " + inputStr);
253 System.out.println("解密後: " + outputStr);
254
255 System.out.println("私鑰加密——公鑰解密");
256 // 私鑰加密
257 encodedData = RSACryptUtil.encryptByPrivateKey(data, privateKey);
258 System.out.println("私鑰加密後:" + new BigInteger(encodedData).toString(32));
259 // 公鑰解密
260 decodedData = RSACryptUtil.decryptByPublicKey(encodedData, publicKey);
261 outputStr = new String(decodedData, "UTF-8");
262 System.out.println("加密前: " + inputStr);
263 System.out.println("解密後: " + outputStr);
264
265 System.out.println("私鑰簽名——公鑰驗證簽名");
266 // 使用私鑰產生簽名
267 String sign = RSACryptUtil.sign(encodedData, privateKey);
268 System.out.println("簽名:" + sign);
269 // 使用公匙驗證簽名
270 boolean status = RSACryptUtil.verify(encodedData, publicKey, sign);
271 System.err.println("驗證簽名結果:" + status);
272 } catch (Exception e) {
273 // TODO Auto-generated catch block
274 e.printStackTrace();
275 }
276
277 }
278
279 }
複製代碼

 

轉自:http://www.cnblogs.com/liubin0509/archive/2012/01/29/2331075.html html

相關文章
相關標籤/搜索