/** *支付宝支付 * @param orderId 订单编号 * @param actualPay 实际支付金额 * @return */ private String getOrderInfoByAliPay(String orderId,float actualPay) {
//回调页面 String ali_call_back_url = propertiesService.ALI_CALL_BACK_URL; String seller_id = propertiesService.SELLER_ID;//商户编号 String[] parameters={ "service=\"mobile.securitypay.pay\"",//固定值(手机快捷支付) "partner=\"2088421544444\"",//合作身份者ID(16位)
"_input_charset=\"utf-8\"", "notify_url=\""+ali_call_back_url+"\"",//通知地址 "out_trade_no=\""+orderId+"\"",//商户内部订单号 "subject=\"测试\"",//测试 "payment_type=\"1\"",//固定值 "seller_id=\""+seller_id+"\"",//账户邮箱 "total_fee=\""+"0.01"+"\"",//支付金额(元) "body=\"订单说明\"",//订单说明
"it_b_pay=\"30m\""(订单过期时间 30分钟过期无效) }; String signOrderUrl = signAllString(parameters); return signOrderUrl; }
/** * 支付宝签名 * @param array * @return */ private String signAllString(String [] array){ StringBuffer sb = new StringBuffer(""); for (int i = 0; i < array.length; i++) { if(i==(array.length-1)){ sb.append(array[i]); }else{ sb.append(array[i]+"&"); } } System.out.println(sb.toString()); String sign = ""; try { sign = URLEncoder.encode(RSA.sign(sb.toString(), AlipayConfig.private_key, "utf-8"), "utf-8");//private_key私钥 } catch (UnsupportedEncodingException e) { e.printStackTrace(); } sb.append("&sign=\""+sign+"\"&"); sb.append("sign_type=\"RSA\""); return sb.toString(); }
package com.alipay.sign; import javax.crypto.Cipher; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec;
public class RSA{ public static final String SIGN_ALGORITHMS = "SHA1WithRSA"; /** * RSA签名 * @param content 待签名数据 * @param privateKey 商户私钥 * @param input_charset 编码格式 * @return 签名值 */ public static String sign(String content, String privateKey, String input_charset) { try { byte[] decode = Base64.decode(privateKey); PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec(decode ); KeyFactory keyf= KeyFactory.getInstance("RSA"); PrivateKey priKey= keyf.generatePrivate(priPKCS8); java.security.Signature signature = java.security.Signature.getInstance(SIGN_ALGORITHMS); signature.initSign(priKey); signature.update( content.getBytes(input_charset) ); byte[] signed = signature.sign(); return Base64.encode(signed); } catch (Exception e) { e.printStackTrace(); } return null; } /** * RSA验签名检查 * @param content 待签名数据 * @param sign 签名值 * @param ali_public_key 支付宝公钥 * @param input_charset 编码格式 * @return 布尔值 */ public static boolean verify(String content, String sign, String ali_public_key, String input_charset) { try { KeyFactory keyFactory = KeyFactory.getInstance("RSA"); byte[] encodedKey = Base64.decode(ali_public_key); PublicKey pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey)); java.security.Signature signature = java.security.Signature .getInstance(SIGN_ALGORITHMS); signature.initVerify(pubKey); signature.update( content.getBytes(input_charset) ); boolean bverify = signature.verify( Base64.decode(sign) ); return bverify; } catch (Exception e) { e.printStackTrace(); } return false; } /** * 解密 * @param content 密文 * @param private_key 商户私钥 * @param input_charset 编码格式 * @return 解密后的字符串 */ public static String decrypt(String content, String private_key, String input_charset) throws Exception { PrivateKey prikey = getPrivateKey(private_key); Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.DECRYPT_MODE, prikey); InputStream ins = new ByteArrayInputStream(Base64.decode(content)); ByteArrayOutputStream writer = new ByteArrayOutputStream(); //rsa解密的字节大小最多是128,将需要解密的内容,按128位拆开解密 byte[] buf = new byte[128]; int bufl; while ((bufl = ins.read(buf)) != -1) { byte[] block = null; if (buf.length == bufl) { block = buf; } else { block = new byte[bufl]; for (int i = 0; i < bufl; i++) { block[i] = buf[i]; } } writer.write(cipher.doFinal(block)); } return new String(writer.toByteArray(), input_charset); } /** * 得到私钥 * @param key 密钥字符串(经过base64编码) * @throws Exception */ public static PrivateKey getPrivateKey(String key) throws Exception { byte[] keyBytes; keyBytes = Base64.decode(key); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes); KeyFactory keyFactory = KeyFactory.getInstance("RSA"); PrivateKey privateKey = keyFactory.generatePrivate(keySpec); return privateKey; } }
支付宝参数里面为什么要进行转义?主要是因为返回给移动的参数结果是springmvc进行返回的给移动端时,会认为"为结束,所以需要\"进行转义!
支付宝APP支付Java开发报错:
1 IOException : DerInputStream.getLength(): lengthTag=127, too big.
后来排查是因为没有设置私钥.