Get Started
Transfer APIs provide two signing methods: SHA256withRSA and SHA256. Use the method assigned to your merchant by Onerway.
Before you start
Confirm your merchant's signing method first. The signing key type, canonical string rule, and generated signature format differ between the two methods.
SHA256withRSA
Signing steps
- Obtain the
privateKey - Use the
SHA256withRSAalgorithm - Convert the canonical string into UTF-8
- Generate the signature
- Base64-encode the signature result
Canonical string rule
Remove all parameters whose values are empty, sort the remaining parameters by ASCII order of the parameter name, and concatenate them in the format key=value&key1=value1.... Do not append & after the last parameter.
Example private key
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDHaM7clWWlJNS6
ZR5ZkxSFeMMFt74YGRmYPr67UHrfc4CzFtN9sctIUqZJVv05sfOgnb0rk1G7wx97
/LqxPEGs5chc+Nq9HkNf5VopMifOQ85j1Sv1U031oEGk+Oi4MTAR4ZWlLKBQPyKV
b5pCP8aIv15GTIiIwJKS17zY5mQUrXzASTDk54DCG9eN4Lgka9xzwRvaYZvmxLg7
32GxjI5TE797kA5gxY7GxZ0wxdkWkhcee6xX6WWhAcmdHPUUS0EPcnL5wcc3wP07
vO+R/jO1XoaXczb6JRh6ApR3Y5VjSFQApqwe7AIgASGf8aSkBU4K95RfZ3QsBjof
2SX/3fkf
Example request data
{
"key": "value",
"key2": "value2",
"key1": "value2",
"sign": "RcqXuiVp1JpwJedRGzTpL8M5mUsfeHL29gV9ycaJwmDoNV21AiaQ41au2qiJ8h+jKn/KBMcrJAzHGBTO3CZ0ffGxmqNz9fKhZX+X1MTntH+MhtKTyKR4ZF8kbAtezdVgPfqT69NPQGbWo57R3KP0m4W4n2ZjgkxkcG3yYtBdAgsyxDNoT8W0wH7nK7Y0zp88O8wIMe7kfBnK59J4y0Xz2EwiFX+bNkfRhf3U5WiHIU2TdRbaYsnzndmOkYkVdFAiUH7zoXnEn8ZVqiDZkK4eFG9H1LxU55dStug1hLtwxOKlu5OYFUi4iGAiq0Vlir01eDR1++KAudOdb1gcUyH2rA=="
}
Example canonical string
key=value&key1=value2&key2=value2
Example signature result
RcqXuiVp1JpwJedRGzTpL8M5mUsfeHL29gV9ycaJwmDoNV21AiaQ41au2qiJ8h+jKn/KBMcrJAzHGBTO3CZ0ffGxmqNz9fKhZX+X1MTntH+MhtKTyKR4ZF8kbAtezdVgPfqT69NPQGbWo57R3KP0m4W4n2ZjgkxkcG3yYtBdAgsyxDNoT8W0wH7nK7Y0zp88O8wIMe7kfBnK59J4y0Xz2EwiFX+bNkfRhf3U5WiHIU2TdRbaYsnzndmOkYkVdFAiUH7zoXnEn8ZVqiDZkK4eFG9H1LxU55dStug1hLtwxOKlu5OYFUi4iGAiq0Vlir01eDR1++KAudOdb1gcUyH2rA==
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency>
package xxx;
import org.apache.commons.codec.binary.Base64;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
public class RSASecureDemo {
public static String signRSA(String privateKey, String toBeSignedData) {
try {
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(priKey);
signature.update(toBeSignedData.getBytes(StandardCharsets.UTF_8));
return Base64.encodeBase64String(signature.sign());
} catch (Exception e) {
throw new RuntimeException("rsa sign failed");
}
}
public static void main(String[] args) {
String privateKey = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDHaM7clWWlJNS6" +
"ZR5ZkxSFeMMFt74YGRmYPr67UHrfc4CzFtN9sctIUqZJVv05sfOgnb0rk1G7wx97" +
"/LqxPEGs5chc+Nq9HkNf5VopMifOQ85j1Sv1U031oEGk+Oi4MTAR4ZWlLKBQPyKV" +
"483/Axmrwea50UKLqRVH3IXzTOEJth0betqTmbefYFLETn5RXB6MOJQOdzpvvcP3" +
"05FmtT/grqqcnaeLbosT4A==";
String toBeSignedData = "key=value&key1=value2&key2=value2";
String sign = signRSA(privateKey, toBeSignedData);
System.out.println(sign);
}
}
SHA256
Signing steps
- Obtain the secret key
- Concatenate the canonical string and the secret key as strings
- Convert the result into UTF-8
- Apply the
SHA-256digest - Convert the digest into a hexadecimal string
Canonical string rule
Remove all parameters whose signing column is No and parameters whose values are empty. Sort the remaining parameters by ASCII order of the parameter name, concatenate only the parameter values, and then append the secret key.
Example secret key
3b5e10b65bff4172a5b9ca2d2ec00a6e
Example request data
{
"merchantNo": "800135",
"test": "dsaaass1dsag",
"bizContent": "yesdas1dsa",
"as": "12334567",
"bc": "098754"
}
Example canonical string
12334567098754yesdas1dsa800135dsaaass1dsag
Example signature result
0ce84cc90742e79b3af76da6b6909dc158a2e933057562639fe6a5a8e73f5350
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.6</version>
</dependency>
package xxx;
import org.apache.commons.lang3.StringUtils;
import java.security.MessageDigest;
import java.util.TreeMap;
public class SHA256SecureDemo {
public static void main(String[] args) throws Exception {
TreeMap data = new TreeMap();
data.put("merchantNo","800135");
data.put("test","yesdas1dsa");
data.put("bizContent","dsaaass1dsag");
data.put("as","12334567");
data.put("bc","098754");
String toBeSignedData = strcatValueSign(data);
String key = "3b5e10b65bff4172a5b9ca2d2ec00a6e";
String sign = signSha256(key, toBeSignedData);
System.out.println(sign);
}
private static String strcatValueSign(TreeMap treeMap) {
StringBuffer buffer = new StringBuffer();
treeMap.forEach((k, v) -> {
if (StringUtils.isNotBlank((String) v)) {
buffer.append(v);
}
});
return buffer.toString();
}
public static String signSha256(String key, String toBeSignedData) {
String str = toBeSignedData + key;
String encodestr = "";
try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(str.getBytes("UTF-8"));
encodestr = byte2Hex(messageDigest.digest());
} catch (Exception e) {
e.printStackTrace();
}
return encodestr;
}
private static String byte2Hex(byte[] bytes) {
StringBuffer stringBuffer = new StringBuffer();
String temp = null;
for (int i = 0; i < bytes.length; i++) {
temp = Integer.toHexString(bytes[i] & 0xFF);
if (temp.length() == 1) {
stringBuffer.append("0");
}
stringBuffer.append(temp);
}
return stringBuffer.toString();
}
}