RSA签名和验签(加解密)
解析pfx证书,进行签名和验签
1 package cn.swiftpass.action.weixinbank.mobile; 2 import it.sauronsoftware.base64.Base64; 3 import java.io.FileInputStream; 4 import java.net.URLEncoder; 5 import java.security.KeyStore; 6 import java.security.PrivateKey; 7 import java.security.PublicKey; 8 import java.util.Map; 9 import javax.crypto.Cipher; 10 import org.apache.commons.io.IOUtils; 11 import org.springframework.util.ResourceUtils; 12 import play.libs.Json; 13 import cn.swiftpass.helper.weixinbank.Base64Utils; 14 import cn.swiftpass.helper.weixinbank.New; 15 import cn.swiftpass.helper.weixinbank.RSAUtils; 16 17 public class TestPfx { 18 static Cipher cipher; 19 static PrivateKey prikey;//私钥 20 static PublicKey pubkey;//公钥 21 static String path = "E://credit_u_plan.pfx";//证书存放路径 22 static char[] password = "qwer1234".toCharArray();//证书密码 23 //解析 pfx证书,获取公私钥 24 static { 25 try { 26 cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 27 KeyStore ks = KeyStore.getInstance("PKCS12"); 28 FileInputStream fis = new FileInputStream(ResourceUtils.getFile(path)); 29 ks.load(fis, password); 30 IOUtils.closeQuietly(fis); 31 String keyAlias = ks.aliases().nextElement(); 32 prikey = (PrivateKey) ks.getKey(keyAlias, password);//私钥 33 pubkey = ks.getCertificate(keyAlias).getPublicKey();//公钥 34 } catch (Exception e) { 35 e.printStackTrace(); 36 } 37 } 38 39 public static void main(String[] args) { 40 try { 41 Map<String, String> hashMap = New.lmap(); 42 hashMap.put("email", "");// 电子邮件地址 43 hashMap.put("mobile", "");// 手机号码 44 hashMap.put("signCertId", "888");// 签名证书ID 45 String sendStr = Json.toJson(hashMap).toString();// 加密参数 46 byte[] encodeBase64 = Base64.encode(sendStr.getBytes("UTF-8")); 47 System.out.println("data=" + new String(encodeBase64)); 48 //公钥 49 String publicKey = Base64Utils.encode(pubkey.getEncoded()); 50 System.out.println("publicKey=" + publicKey); 51 //私钥 52 String privateKey = Base64Utils.encode(prikey.getEncoded()); 53 System.out.println("privateKey=" + privateKey); 54 //签名 55 String signature = RSAUtils.sign256(encodeBase64, privateKey); 56 System.out.println("私钥加密后的参数:signature=" + signature); 57 //验签 58 System.out.println("验证签名结果:" + RSAUtils.verify2(encodeBase64, publicKey, signature)); 59 //URLEncoder 60 signature = URLEncoder.encode(signature, "UTF-8"); 61 System.out.println("signature-urlencode=" + signature); 62 } catch (Exception e) { 63 e.printStackTrace(); 64 } 65 } 66 }
证书加密类RSAUtils,RSA工具类:RSAUtils
1 package cn.swiftpass.helper.weixinbank; 2 import java.io.ByteArrayOutputStream; 3 import java.security.Key; 4 import java.security.KeyFactory; 5 import java.security.KeyPair; 6 import java.security.KeyPairGenerator; 7 import java.security.PrivateKey; 8 import java.security.PublicKey; 9 import java.security.Signature; 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 import javax.crypto.Cipher; 17 18 /** 19 * RSA公钥/私钥/签名工具包 20 * 罗纳德·李维斯特(Ron [R]ivest)、阿迪·萨莫尔(Adi [S]hamir)和伦纳德·阿德曼(Leonard [A]dleman) 21 * 字符串格式的密钥在未在特殊说明情况下都为BASE64编码格式<br/> 22 * 由于非对称加密速度极其缓慢,一般文件不使用它来加密而是使用对称加密,<br/> 23 * 非对称加密算法可以用来对对称加密的密钥加密,这样保证密钥的安全也就保证了数据的安全 24 * @author IceWee 25 * @date 2012-4-26 26 * @version 1.0 27 */ 28 public class RSAUtils { 29 30 /** 31 * 加密算法RSA 32 */ 33 public static final String KEY_ALGORITHM = "RSA"; 34 35 /** 36 * 签名算法 37 */ 38 public static final String SIGNATURE_ALGORITHM = "MD5withRSA"; 39 /** 40 * 签名算法 41 */ 42 public static final String SIGNATURE_SHA256WithRSA = "SHA256WithRSA"; 43 44 /** 45 * 获取公钥的key 46 */ 47 private static final String PUBLIC_KEY = "RSAPublicKey"; 48 49 /** 50 * 获取私钥的key 51 */ 52 private static final String PRIVATE_KEY = "RSAPrivateKey"; 53 54 /** 55 * RSA最大加密明文大小 56 */ 57 private static final int MAX_ENCRYPT_BLOCK = 117; 58 59 /** 60 * RSA最大解密密文大小 61 */ 62 private static final int MAX_DECRYPT_BLOCK = 128; 63 64 /** 65 * 生成密钥对(公钥和私钥) 66 * @return 67 * @throws Exception 68 */ 69 public static Map<String, Object> genKeyPair() throws Exception { 70 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); 71 keyPairGen.initialize(1024); 72 KeyPair keyPair = keyPairGen.generateKeyPair(); 73 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); 74 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); 75 Map<String, Object> keyMap = new HashMap<String, Object>(2); 76 keyMap.put(PUBLIC_KEY, publicKey); 77 keyMap.put(PRIVATE_KEY, privateKey); 78 return keyMap; 79 } 80 81 /** 82 * 用私钥对信息生成数字签名,签名算法:MD5withRSA 83 * @param data 已加密数据 84 * @param privateKey 私钥(BASE64编码) 85 * @return 86 * @throws Exception 87 */ 88 public static String sign(byte[] data, String privateKey) throws Exception { 89 byte[] keyBytes = Base64Utils.decode(privateKey); 90 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); 91 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 92 PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); 93 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); 94 signature.initSign(privateK); 95 signature.update(data); 96 return Base64Utils.encode(signature.sign()); 97 } 98 99 /** 100 * 用私钥对信息生成数字签名,签名算法:SHA256WithRSA 101 * @param data 已加密数据 102 * @param privateKey 私钥(BASE64编码) 103 * @return 104 * @throws Exception 105 */ 106 public static String sign256 (byte[] data, String privateKey) throws Exception { 107 byte[] keyBytes = Base64Utils.decode(privateKey); 108 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); 109 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 110 PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec); 111 Signature signature = Signature.getInstance(SIGNATURE_SHA256WithRSA); 112 signature.initSign(privateK); 113 signature.update(data); 114 return Base64Utils.encode(signature.sign()); 115 } 116 117 /** 118 * 校验数字签名,签名算法:MD5withRSA 119 * @param data 已加密数据 120 * @param publicKey 公钥(BASE64编码) 121 * @param sign 数字签名 122 * @return 123 * @throws Exception 124 */ 125 public static boolean verify(byte[] data, String publicKey, String sign)throws Exception { 126 byte[] keyBytes = Base64Utils.decode(publicKey); 127 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); 128 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 129 PublicKey publicK = keyFactory.generatePublic(keySpec); 130 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); 131 signature.initVerify(publicK); 132 signature.update(data); 133 return signature.verify(Base64Utils.decode(sign)); 134 } 135 /** 136 * 校验数字签名,签名算法:SHA256WithRSA 137 * @param data 已加密数据 138 * @param publicKey 公钥(BASE64编码) 139 * @param sign 数字签名 140 * @return 141 * @throws Exception 142 */ 143 public static boolean verify2(byte[] data, String publicKey, String sign)throws Exception { 144 byte[] keyBytes = Base64Utils.decode(publicKey); 145 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); 146 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 147 PublicKey publicK = keyFactory.generatePublic(keySpec); 148 Signature signature = Signature.getInstance(SIGNATURE_SHA256WithRSA); 149 signature.initVerify(publicK); 150 signature.update(data); 151 return signature.verify(Base64Utils.decode(sign)); 152 } 153 154 /** 155 * 私钥解密 156 * @param encryptedData 已加密数据 157 * @param privateKey 私钥(BASE64编码) 158 * @return 159 * @throws Exception 160 */ 161 public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey)throws Exception { 162 byte[] keyBytes = Base64Utils.decode(privateKey); 163 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); 164 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 165 Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); 166 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); 167 cipher.init(Cipher.DECRYPT_MODE, privateK); 168 int inputLen = encryptedData.length; 169 ByteArrayOutputStream out = new ByteArrayOutputStream(); 170 int offSet = 0; 171 byte[] cache; 172 int i = 0; 173 // 对数据分段解密 174 while (inputLen - offSet > 0) { 175 if (inputLen - offSet > MAX_DECRYPT_BLOCK) { 176 cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); 177 } else { 178 cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); 179 } 180 out.write(cache, 0, cache.length); 181 i++; 182 offSet = i * MAX_DECRYPT_BLOCK; 183 } 184 byte[] decryptedData = out.toByteArray(); 185 out.close(); 186 return decryptedData; 187 } 188 189 /** 190 * 公钥解密 191 * @param encryptedData 已加密数据 192 * @param publicKey 公钥(BASE64编码) 193 * @return 194 * @throws Exception 195 */ 196 public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey)throws Exception { 197 byte[] keyBytes = Base64Utils.decode(publicKey); 198 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); 199 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 200 Key publicK = keyFactory.generatePublic(x509KeySpec); 201 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); 202 cipher.init(Cipher.DECRYPT_MODE, publicK); 203 int inputLen = encryptedData.length; 204 ByteArrayOutputStream out = new ByteArrayOutputStream(); 205 int offSet = 0; 206 byte[] cache; 207 int i = 0; 208 // 对数据分段解密 209 while (inputLen - offSet > 0) { 210 if (inputLen - offSet > MAX_DECRYPT_BLOCK) { 211 cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK); 212 } else { 213 cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet); 214 } 215 out.write(cache, 0, cache.length); 216 i++; 217 offSet = i * MAX_DECRYPT_BLOCK; 218 } 219 byte[] decryptedData = out.toByteArray(); 220 out.close(); 221 return decryptedData; 222 } 223 224 /** 225 * 公钥加密 226 * @param data 源数据 227 * @param publicKey 公钥(BASE64编码) 228 * @return 229 * @throws Exception 230 */ 231 public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception { 232 byte[] keyBytes = Base64Utils.decode(publicKey); 233 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); 234 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 235 Key publicK = keyFactory.generatePublic(x509KeySpec); 236 // 对数据加密 237 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); 238 cipher.init(Cipher.ENCRYPT_MODE, publicK); 239 int inputLen = data.length; 240 ByteArrayOutputStream out = new ByteArrayOutputStream(); 241 int offSet = 0; 242 byte[] cache; 243 int i = 0; 244 // 对数据分段加密 245 while (inputLen - offSet > 0) { 246 if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { 247 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); 248 } else { 249 cache = cipher.doFinal(data, offSet, inputLen - offSet); 250 } 251 out.write(cache, 0, cache.length); 252 i++; 253 offSet = i * MAX_ENCRYPT_BLOCK; 254 } 255 byte[] encryptedData = out.toByteArray(); 256 out.close(); 257 return encryptedData; 258 } 259 260 /** 261 * 私钥加密 262 * @param data 源数据 263 * @param privateKey 私钥(BASE64编码) 264 * @return 265 * @throws Exception 266 */ 267 public static byte[] encryptByPrivateKey(byte[] data, String privateKey)throws Exception { 268 byte[] keyBytes = Base64Utils.decode(privateKey); 269 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); 270 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); 271 Key privateK = keyFactory.generatePrivate(pkcs8KeySpec); 272 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); 273 cipher.init(Cipher.ENCRYPT_MODE, privateK); 274 int inputLen = data.length; 275 ByteArrayOutputStream out = new ByteArrayOutputStream(); 276 int offSet = 0; 277 byte[] cache; 278 int i = 0; 279 // 对数据分段加密 280 while (inputLen - offSet > 0) { 281 if (inputLen - offSet > MAX_ENCRYPT_BLOCK) { 282 cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK); 283 } else { 284 cache = cipher.doFinal(data, offSet, inputLen - offSet); 285 } 286 out.write(cache, 0, cache.length); 287 i++; 288 offSet = i * MAX_ENCRYPT_BLOCK; 289 } 290 byte[] encryptedData = out.toByteArray(); 291 out.close(); 292 return encryptedData; 293 } 294 295 /** 296 * 获取私钥 297 * @param keyMap 密钥对 298 * @return 299 * @throws Exception 300 */ 301 public static String getPrivateKey(Map<String, Object> keyMap)throws Exception { 302 Key key = (Key) keyMap.get(PRIVATE_KEY); 303 return Base64Utils.encode(key.getEncoded()); 304 } 305 306 /** 307 * 获取公钥 308 * @param keyMap 密钥对 309 * @return 310 * @throws Exception 311 */ 312 public static String getPublicKey(Map<String, Object> keyMap)throws Exception { 313 Key key = (Key) keyMap.get(PUBLIC_KEY); 314 return Base64Utils.encode(key.getEncoded()); 315 } 316 }
『愿你我既可以朝九晚五,又能够浪迹天涯』