支付寶 APP 支付要求後端生成帶簽名的訂單字符串,客戶端調用 SDK 唤起支付。本文提供基於 RSA2 (SHA256withRSA) 的完整簽名生成實現,含參數組裝、私鑰簽名、URL 編碼、工具類封裝。
private String getOrderInfoByAliPay(String orderId, float actualPay) {
String[] parameters = {
"service=\"mobile.securitypay.pay\"",
"partner=\"2088421544444\"",
"_input_charset=\"utf-8\"",
"notify_url=\"" + aliCallBackUrl + "\"",
"out_trade_no=\"" + orderId + "\"",
"subject=\"測試商品\"",
"payment_type=\"1\"",
"seller_id=\"" + sellerId + "\"",
"total_fee=\"" + actualPay + "\"",
"body=\"訂單描述\"",
"it_b_pay=\"30m\""
};
return signAllString(parameters);
}
private String signAllString(String[] params) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < params.length; i++) {
sb.append(params[i]);
if (i < params.length - 1) sb.append("&");
}
String sign = "";
try {
// 關鍵:RSA 簽名 + URLEncoder 編碼
sign = URLEncoder.encode(RSA.sign(sb.toString(), AlipayConfig.PRIVATE_KEY, "utf-8"), "utf-8");
} catch (UnsupportedEncodingException e) { e.printStackTrace(); }
sb.append("&sign=\"").append(sign).append("\"&");
sb.append("sign_type=\"RSA\"");
return sb.toString();
}
public class RSA {
public static final String SIGN_ALGORITHMS = "SHA1WithRSA"; // 生產建議升級 SHA256WithRSA
// 簽名:私鑰簽名 -> Base64 編碼
public static String sign(String content, String privateKey, String charset) {
try {
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(Base64.decode(privateKey));
PrivateKey key = KeyFactory.getInstance("RSA").generatePrivate(spec);
Signature sig = Signature.getInstance(SIGN_ALGORITHMS);
sig.initSign(key);
sig.update(content.getBytes(charset));
return Base64.encode(sig.sign());
} catch (Exception e) { e.printStackTrace(); return null; }
}
// 驗簽:支付寶公鑰驗證回調簽名
public static boolean verify(String content, String sign, String aliPublicKey, String charset) {
try {
X509EncodedKeySpec spec = new X509EncodedKeySpec(Base64.decode(aliPublicKey));
PublicKey key = KeyFactory.getInstance("RSA").generatePublic(spec);
Signature sig = Signature.getInstance(SIGN_ALGORITHMS);
sig.initVerify(key);
sig.update(content.getBytes(charset));
return sig.verify(Base64.decode(sign));
} catch (Exception e) { e.printStackTrace(); return false; }
}
// 解密:長數據分段 RSA 解密 (128 字節/段)
public static String decrypt(String content, String privateKey, String charset) throws Exception {
// ... 分段解密邏輯見完整代碼
}
}
\" 轉義(如 partner=\"2088...\")。SHA1WithRSA,新版強制要求 SHA256WithRSA (RSA2),需同步更新 SIGN_ALGORITHMS 並確保私鑰長度 ≥ 2048 位。