求救
https://www.payuni.com.tw/docs/web/#/7/29
求救JAVA加解密範例 aes-256-gcm
壓出來始終跟範例不一樣
求高手指導
Google到這篇提供參考看看
主程式不動,改改參數看看結果是否會相符
這個跟我遇到藍新金流一樣~只有PHP範例~= =...
害我只好先架好PHP後~逐筆拆解每列編碼結果~(觀察二進位編碼010)
再用找網路範例(C# 轉 VB)~再去拆解逐筆AES編碼確認~
所以JAVA範例~你也要去找網路參考範例修改~
JAVA AES加解密範例
https://www.1ju.org/article/java-aes-encryption-decryption
找到解法了 我自問自答
/*
/**
*
@author boboboom
*/
public class PayUni {
public static void main(String[] args) {
// 填入商店串接資訊
String merID = "NPPA129180793";
String hashKey = "12345678901234567890123456789012";// "uH9qCQ9rrv0aEgqxPBoqtcoWNLJb5Bpb";
String hashIV = "1234567890123456";// "5lCWfCqsn81BJ3TL";
// 建立請求參數
Map<String, String> requestData = new HashMap<>();
requestData.put("MerID" , merID);
requestData.put("Version" , "1.0");
Map<String, String> data = new LinkedHashMap<>();
data.put("MerID" , "ABC");
data.put("MerTradeNo" , "1658198662_93966");
data.put("TradeAmt" , "7017");
data.put("Timestamp" , "1658198662");
data.put("ProdDesc" , "商品說明");
data.put("UsrMail" , "a@presco.ws");
data.put("ReturnURL" , "http://lapi-epay.presco.com.tw/api/upp/return");
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, String> entry : data.entrySet()) {
sb.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), StandardCharsets.UTF_8))
.append("&");
}
sb.deleteCharAt(sb.length() - 1);
String encodedUrl = sb.toString();
System.out.println("Origin:" + encodedUrl + "\r\n");
// 產生加密字串
String encryptInfo = encrypt(encodedUrl, hashKey, hashIV);
System.out.println("EncryptInfo:" + encryptInfo + "\r\n");
requestData.put("EncryptInfo", encryptInfo);
// 產生 HashInfo
String hashInfo = getTradeSha(encryptInfo, hashKey, hashIV);
requestData.put("HashInfo", hashInfo);
System.out.println("HashInfo:" + hashInfo + "\r\n");
// 解密
String decryptInfo = decrypt(encryptInfo, hashKey, hashIV);
System.out.println("DecryptInfo:" + decryptInfo);
getHtml(requestData);
}
public static String encrypt(String text, String key, String iv) {
try {
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, iv.getBytes(StandardCharsets.UTF_8));
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, gcmParameterSpec);
byte[] encryptedBytes = cipher.doFinal(text.getBytes(StandardCharsets.UTF_8));
byte[] encryptedInfo = Arrays.copyOfRange(encryptedBytes, 0, encryptedBytes.length-16);
byte[] tagInfo = Arrays.copyOfRange(encryptedBytes, encryptedBytes.length-16, encryptedBytes.length);
String encodeText = Base64.getEncoder().encodeToString(encryptedInfo);
String encodeTag = Base64.getEncoder().encodeToString(tagInfo);
String finalString = encodeText + ":::" + encodeTag;
byte[] finalBytes = finalString.getBytes(StandardCharsets.UTF_8);
return bytesToHex(finalBytes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String decrypt(String text, String key, String iv) {
try {
// Get Cipher Instance
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
// Create SecretKeySpec
SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "AES");
// Create GCMParameterSpec
GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(128, iv.getBytes(StandardCharsets.UTF_8));
// Initialize Cipher for DECRYPT_MODE
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, gcmParameterSpec);
byte[] hexToByte = hexStringToByteArray(text);
String encryptStr = new String(hexToByte, StandardCharsets.UTF_8);
String encryptInfo = encryptStr.split(":::")[0];
byte[] encryptInfoBytes = Base64.getDecoder().decode(encryptInfo);
String tagString = encryptStr.split(":::")[1];
byte[] tagStringBytes = Base64.getDecoder().decode(tagString);
byte[] encryptData = new byte[encryptInfoBytes.length + tagStringBytes.length];
System.arraycopy(encryptInfoBytes, 0, encryptData, 0, encryptInfoBytes.length);
System.arraycopy(tagStringBytes, 0, encryptData, encryptInfoBytes.length, tagStringBytes.length);
byte[] decodeInfo = cipher.doFinal(encryptData);
String decodeInfoString = new String(decodeInfo, StandardCharsets.UTF_8);
return decodeInfoString;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static byte[] hexStringToByteArray(String hex) {
int len = hex.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4)
+ Character.digit(hex.charAt(i + 1), 16));
}
return data;
}
private static String bytesToHex(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) {
sb.append(String.format("%02x", b));
}
return sb.toString();
}
public static String getTradeSha(String data, String key, String iv) {
String sha256 = encrySha256(key + data + iv);
return sha256.trim();
}
public static String encrySha256(String value) {
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(value.getBytes());
byte byteBuffer[] = messageDigest.digest();
StringBuffer strHexString = new StringBuffer();
for (int i = 0; i < byteBuffer.length; i++) {
String hex = Integer.toHexString(0xff & byteBuffer[i]);
if (hex.length() == 1) {
strHexString.append('0');
}
strHexString.append(hex);
}
return strHexString.toString().toUpperCase();
} catch (Exception e) {
}
return null;
}
public static String getHtml(Map<String, String> data) {
StringBuilder sb = new StringBuilder();
sb.append("<form id="Unipay" action="https://api.payuni.com.tw/api/upp" method="post">");
for (Map.Entry<String, String> entry : data.entrySet()) {
String keyA = entry.getKey();
String valueA = entry.getValue();
sb.append("<input type="hidden"name="" + keyA + "" value="" + valueA + "">");
}
sb.append("<script language="JavaScript">Unipay.submit()");
sb.append("");
try {
BufferedWriter writer = new BufferedWriter(new FileWriter("payment.html"));
writer.write(sb.toString());
writer.close();
System.out.println("payment.html file generated successfully.");
} catch (IOException e) {
e.printStackTrace();
}
return sb.toString();
}
}
恩~問題解決就好唷~加油!