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("公钥: " + publicKey);
242 System.out.println("私钥: " + 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 

原文地址:https://www.cnblogs.com/shz365/p/3686031.html