Java 签名示例
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.UUID;
public class CashierSignUtil {
public static String signHmacSha256(String message, String secret) throws Exception {
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec keySpec = new SecretKeySpec(
secret.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
mac.init(keySpec);
byte[] hash = mac.doFinal(message.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(hash);
}
public static String buildSignString(String method, String uri, String timestamp,
String nonce, String body) {
return method + "\n"
+ uri + "\n"
+ timestamp + "\n"
+ nonce + "\n"
+ (body != null ? body : "") + "\n";
}
public static String buildAuthorization(String mchid, String serial,
String nonce, String timestamp, String signature) {
return "KP-CASHIER-HMAC-SHA256"
+ " mchid=\"" + mchid + "\""
+ ", serial=\"" + serial + "\""
+ ", nonce=\"" + nonce + "\""
+ ", timestamp=\"" + timestamp + "\""
+ ", signature=\"" + signature + "\"";
}
public static String buildClientHeader(String sn, String name, String ip,
String app, String version, String session) {
StringBuilder sb = new StringBuilder();
sb.append("sn=\"").append(sn).append("\"");
sb.append(", name=\"").append(name).append("\"");
sb.append(", ip=\"").append(ip).append("\"");
sb.append(", app=\"").append(app).append("\"");
sb.append(", version=\"").append(version).append("\"");
if (session != null && !session.isEmpty()) {
sb.append(", session=\"").append(session).append("\"");
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
String method = "POST";
String uri = "/open/cashier/trans/micropay";
String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
String nonce = UUID.randomUUID().toString().replace("-", "");
String body = "{\"amount\":100,\"out_trade_no\":\"TS20260507000001\",\"auth_code\":\"134567890123456789\"}";
String secret = "your_secret_key";
String signString = buildSignString(method, uri, timestamp, nonce, body);
String signature = signHmacSha256(signString, secret);
String authorization = buildAuthorization("100001", "KEY001", nonce, timestamp, signature);
String clientHeader = buildClientHeader("SN-DEVICE-001", "收银台A01", "192.168.1.100", "cashier-pos", "2.0.0", "abc123");
System.out.println("Authorization: " + authorization);
System.out.println("Ikudot-Cashier-Client: " + clientHeader);
}
}
AES 加解密
部分敏感字段(如支付密码)需使用 AES-256-CBC 加密后传输。
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;
public class AesCbcUtil {
private static final String ALGORITHM = "AES/CBC/PKCS5Padding";
private static final int IV_LENGTH = 16;
public static EncryptedData encrypt(String plaintext, String base64Key) throws Exception {
byte[] key = Base64.getDecoder().decode(base64Key);
byte[] iv = new byte[IV_LENGTH];
SecureRandom.getInstanceStrong().nextBytes(iv);
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
EncryptedData result = new EncryptedData();
result.algorithm = "AES_256_CBC";
result.ciphertext = Base64.getEncoder().encodeToString(ciphertext);
result.iv = Base64.getEncoder().encodeToString(iv);
return result;
}
public static String decrypt(String base64Ciphertext, String base64Iv, String base64Key) throws Exception {
byte[] key = Base64.getDecoder().decode(base64Key);
byte[] iv = Base64.getDecoder().decode(base64Iv);
byte[] ciphertext = Base64.getDecoder().decode(base64Ciphertext);
Cipher cipher = Cipher.getInstance(ALGORITHM);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] plaintext = cipher.doFinal(ciphertext);
return new String(plaintext, StandardCharsets.UTF_8);
}
public static class EncryptedData {
public String algorithm;
public String ciphertext;
public String iv;
}
public static void main(String[] args) throws Exception {
String aesKey = "Base64EncodedAesKey==";
String plaintext = "123456";
EncryptedData encrypted = encrypt(plaintext, aesKey);
System.out.println("加密结果: algorithm=" + encrypted.algorithm
+ ", ciphertext=" + encrypted.ciphertext
+ ", iv=" + encrypted.iv);
String decrypted = decrypt(encrypted.ciphertext, encrypted.iv, aesKey);
System.out.println("解密结果: " + decrypted);
}
}