h5收银台支付加密算法
- encryptData=AES加密(orderId,timestamp,callbackUrl,merchant)
- orderId e代驾业务订单号
- timestamp 时间戳,13位数字符串,精确到毫秒
- callbackUrl 支付成功,跳回合作方的链接
- merchant e代驾颁发给合作方的商户号
注意:AES对称加密算法的密钥由e代驾颁发给合作方,示例见AESUtils的main函数
AES算法
package com.edaijia.openservice.common.utils;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class AESUtils {
/**
* 对称加密
*
* @param input
* @param key
* @return
*/
public static String encrypt(String input, String key) {
byte[] crypted = null;
try {
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, skey);
crypted = cipher.doFinal(input.getBytes());
return new String(Base62.createInstance().encode(crypted));
} catch (Exception e) {
}
return "";
}
/**
* 对称解密
*
* @param input
* @param key
* @return
*/
public static String decrypt(String input, String key) {
byte[] output = null;
try {
SecretKeySpec skey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skey);
output = cipher.doFinal(Base62.createInstance().decode(input.getBytes()));
return new String(output);
} catch (Exception e) {
}
return "";
}
public static void main(String[] args) {
String key = "1234567890abcdef";
String data = "973423656,1567934187864,https://www.baidu.com,01051234dijfejfo09";
String encrypt = encrypt(data, key);
//1lzxghGaXExtA9q2HsG3CAwE7kYM15NtPacuk3PAQk08oQYQdFXrjq0YOeReEngkwSxjyIA9Km3InjOqMhMqvsjzNcgqRRehUMhJLYx5RSaO
System.out.println("加密数据为:" + encrypt);
String decrypt = decrypt(encrypt, key);
System.out.println("解密数据为:" + decrypt);
}
}
Base62编码
package com.edaijia.openservice.common.utils;
import java.io.ByteArrayOutputStream;
public class Base62 {
private static final int STANDARD_BASE = 256;
private static final int TARGET_BASE = 62;
private final byte[] alphabet;
private byte[] lookup;
private Base62(final byte[] alphabet) {
this.alphabet = alphabet;
createLookupTable();
}
/**
* Creates a {@link Base62} instance. Defaults to the GMP-style character set.
*
* @return a {@link Base62} instance.
*/
public static Base62 createInstance() {
return createInstanceWithGmpCharacterSet();
}
/**
* Creates a {@link Base62} instance using the GMP-style character set.
*
* @return a {@link Base62} instance.
*/
public static Base62 createInstanceWithGmpCharacterSet() {
return new Base62(CharacterSets.GMP);
}
/**
* Creates a {@link Base62} instance using the inverted character set.
*
* @return a {@link Base62} instance.
*/
public static Base62 createInstanceWithInvertedCharacterSet() {
return new Base62(CharacterSets.INVERTED);
}
/**
* Encodes a sequence of bytes in Base62 encoding.
*
* @param message a byte sequence.
* @return a sequence of Base62-encoded bytes.
*/
public byte[] encode(final byte[] message) {
final byte[] indices = convert(message, STANDARD_BASE, TARGET_BASE);
return translate(indices, alphabet);
}
/**
* Decodes a sequence of Base62-encoded bytes.
*
* @param encoded a sequence of Base62-encoded bytes.
* @return a byte sequence.
*/
public byte[] decode(final byte[] encoded) {
final byte[] prepared = translate(encoded, lookup);
return convert(prepared, TARGET_BASE, STANDARD_BASE);
}
/**
* Uses the elements of a byte array as indices to a dictionary and returns the corresponding values
* in form of a byte array.
*/
private byte[] translate(final byte[] indices, final byte[] dictionary) {
final byte[] translation = new byte[indices.length];
for (int i = 0; i < indices.length; i++) {
translation[i] = dictionary[indices[i]];
}
return translation;
}
/**
* Converts a byte array from a source base to a target base using the alphabet.
*/
private byte[] convert(final byte[] message, final int sourceBase, final int targetBase) {
/**
* This algorithm is inspired by: http://codegolf.stackexchange.com/a/21672
*/
final int estimatedLength = estimateOutputLength(message.length, sourceBase, targetBase);
final ByteArrayOutputStream out = new ByteArrayOutputStream(estimatedLength);
byte[] source = message;
while (source.length > 0) {
final ByteArrayOutputStream quotient = new ByteArrayOutputStream(source.length);
int remainder = 0;
for (int i = 0; i < source.length; i++) {
final int accumulator = (source[i] & 0xFF) + remainder * sourceBase;
final int digit = (accumulator - (accumulator % targetBase)) / targetBase;
remainder = accumulator % targetBase;
if (quotient.size() > 0 || digit > 0) {
quotient.write(digit);
}
}
out.write(remainder);
source = quotient.toByteArray();
}
// pad output with zeroes corresponding to the number of leading zeroes in the message
for (int i = 0; i < message.length - 1 && message[i] == 0; i++) {
out.write(0);
}
return reverse(out.toByteArray());
}
/**
* Estimates the length of the output in bytes.
*/
private int estimateOutputLength(int inputLength, int sourceBase, int targetBase) {
return (int) Math.ceil((Math.log(sourceBase) / Math.log(targetBase)) * inputLength);
}
/**
* Reverses a byte array.
*/
private byte[] reverse(final byte[] arr) {
final int length = arr.length;
final byte[] reversed = new byte[length];
for (int i = 0; i < length; i++) {
reversed[length - i - 1] = arr[i];
}
return reversed;
}
/**
* Creates the lookup table from character to index of character in character set.
*/
private void createLookupTable() {
lookup = new byte[256];
for (int i = 0; i < alphabet.length; i++) {
lookup[alphabet[i]] = (byte) (i & 0xFF);
}
}
private static class CharacterSets {
private static final byte[] GMP = {
(byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
(byte) '8', (byte) '9', (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
(byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L', (byte) 'M', (byte) 'N',
(byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T', (byte) 'U', (byte) 'V',
(byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd',
(byte) 'e', (byte) 'f', (byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l',
(byte) 'm', (byte) 'n', (byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't',
(byte) 'u', (byte) 'v', (byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z'
};
private static final byte[] INVERTED = {
(byte) '0', (byte) '1', (byte) '2', (byte) '3', (byte) '4', (byte) '5', (byte) '6', (byte) '7',
(byte) '8', (byte) '9', (byte) 'a', (byte) 'b', (byte) 'c', (byte) 'd', (byte) 'e', (byte) 'f',
(byte) 'g', (byte) 'h', (byte) 'i', (byte) 'j', (byte) 'k', (byte) 'l', (byte) 'm', (byte) 'n',
(byte) 'o', (byte) 'p', (byte) 'q', (byte) 'r', (byte) 's', (byte) 't', (byte) 'u', (byte) 'v',
(byte) 'w', (byte) 'x', (byte) 'y', (byte) 'z', (byte) 'A', (byte) 'B', (byte) 'C', (byte) 'D',
(byte) 'E', (byte) 'F', (byte) 'G', (byte) 'H', (byte) 'I', (byte) 'J', (byte) 'K', (byte) 'L',
(byte) 'M', (byte) 'N', (byte) 'O', (byte) 'P', (byte) 'Q', (byte) 'R', (byte) 'S', (byte) 'T',
(byte) 'U', (byte) 'V', (byte) 'W', (byte) 'X', (byte) 'Y', (byte) 'Z'
};
}
}