About The Sign

When you integrate page mode, you need to make the sign for passing parameters. There are two steps for generating the sign

Step One: Confirm the string participating in the signature

You need to sort all parameters in ascending order according to parameter names to generate the signature string.

Sign demo with appId:
appId=jcudotl1hwyvxhdp&sign=e2UZuWKiuxApgQ15wRrfowq5ikX8S8AJwLr%2Bg3ttd44%3D

Sign demo with appId and callbackUrl:
appId=jcudotl1hwyvxhdp&callbackUrl=https://www.amazon.com&
sign=e2UZuWKiuxApgQ15wRrfo1Ps%2BQ%2BNHn%2Bwz6jfKD5VqcYb1l87WDDQnwtcALpd3ZfGPCvSSvPNjPoMj%2BlBBvne1A%3D%3D

Sign demo with appId and address:
address=0xEd04915c23f00A313a544955524EB7DBD823143d&appId=jcudotl1hwyvxhdp&
sign=pDZv9gpreYXn%2F04yMTw3UTyNXFjhs%2FHAguZOZfRNxV2vM5aqvTTUtqByY%2BpZkN0GZe0jqGKvMq76LkGs6R4kw3StSdVxSXu%2FRD3wHVRQ6CA%3D

Sign demo with appId, address and callbackUrl
address=0xEd04915c23f00A313a544955524EB7DBD823143d& appId=jcudotl1hwyvxhdp&
callbackUrl=https://www.amazon.com&
sign=pDZv9gpreYXn%2F04yMTw3UTyNXFjhs%2FHAguZOZfRNxV2vM5aqvTTUtqByY%2BpZkN0GZe0jqGKvMq76LkGs6R4kw%2FyVf9qTLdXO9N8K%2FFaj6eziblI%2FpsQz9lOIT5ZdZDJXGOUPptbXH2buUy9kAN5EGA%3D%3D

Step Two: Generate Your Sign

Please refer these methods to sign

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESUtil {
    public static String encrypt(String plainText, String secretKeyData)  {
        try {
            byte[] plainTextData = plainText.getBytes(StandardCharsets.UTF_8);
            byte[] secretKey = secretKeyData.getBytes(StandardCharsets.UTF_8);
            String iv = new String(secretKey).substring(0, 16);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");

            byte[] dataBytes = plainTextData;
            int plaintextLength = dataBytes.length;
            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);

            SecretKeySpec keyspec = new SecretKeySpec(secretKey, "AES");
            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());

            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
            byte[] encrypted = cipher.doFinal(plaintext);

            return new String(Base64.getEncoder().encode(encrypted));

        } catch (Exception e) {
            System.out.println("AES encrypting exception , msg is {}" + e.toString());
        }
        return null;
    }

    public static String decrypt(String cipherText, String secretKeyData) {
        try {

            byte[] cipherTextData = cipherText.getBytes(StandardCharsets.UTF_8);
            byte[] secretKey = secretKeyData.getBytes(StandardCharsets.UTF_8);
            String iv = new String(secretKey).substring(0, 16);

            byte[] encrypted = Base64.getDecoder().decode(cipherTextData);

            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
            SecretKeySpec keyspec = new SecretKeySpec(secretKey, "AES");
            IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());

            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);

            byte[] original = cipher.doFinal(encrypted);
            String originalString = new String(original);
            return originalString;
        } catch (Exception e) {
            System.out.println("AES decrypting exception: msg is {}" + e.toString());
        }
        return null;
    }


public static void main(String[] args) throws UnsupportedEncodingException {
    String rawData = "address=0x755CA9224E613252c06ae9C20825113Dda1971aa11660287337793&appId=f83Is2**********;
    String sign = encrypt(rawData, "4Yn*************");
    System.out.println("sign is: " + sign);
    System.out.println("\n");
    String urlEncodeData = URLEncoder.encode(sign, "UTF-8");
    System.out.println("encode sign is: " +urlEncodeData);

}


}
//node v14.15.1
const crypto = require('crypto');

function encrypt(plainText, secretKeyData) {
  try {
    const plainTextData = Buffer.from(plainText, 'utf8');
    const secretKey = Buffer.from(secretKeyData, 'utf8');
    const iv = secretKeyData.substring(0, 16);
    
    const cipher = crypto.createCipheriv('aes-128-cbc', secretKey, iv);

    let encrypted = cipher.update(plainTextData);
    encrypted = Buffer.concat([encrypted, cipher.final()]);

    return encrypted.toString('base64');
  } catch (e) {
    console.log(`AES encrypting exception, msg is ${e.toString()}`);
  }
  return null;
}

const plaintext = 'address=0x890D761D8E8c519BE37f82A15e0391B99Eb796A9&appId=f83Is2**********&fiat=USD&fiatAmount=185';
const ciphertext = encrypt(plaintext,"4Yn*************"); //appSecret
console.log("sign is ",ciphertext);
const urlEncodeText = encodeURIComponent(ciphertext)
console.log("encode sign is ",urlEncodeText);
#Python 3.7.4 

import base64
# pip install pycryptodomex
from Cryptodome.Cipher import AES
import urllib
import requests


def encrypt(plainText, secretKeyData):
    plainTextData = plainText.encode('UTF-8')
    secretKey = secretKeyData.encode('UTF-8')
    iv = secretKey[0:16]

    cipher = AES.new(secretKey, AES.MODE_CBC, iv)

    padded_plaintext = pad(plainTextData, AES.block_size)
    ciphertext = cipher.encrypt(padded_plaintext)

    return base64.b64encode(ciphertext).decode()


def pad(data, block_size):
    padding_len = block_size - (len(data) % block_size)

    return data + (bytes([padding_len]) * padding_len)


rawdata = rawData = "address=0x755CA9224E613252c06ae9C20825113Dda1971aa11660287337793&appId=f83Is2**********"
sign = encrypt(rawData, "4Yn*************")
print("sign is:", sign)
urlEncodeData = urllib.parse.quote_plus(sign)
print("encode sign is: ", urlEncodeData)
//PHP 8.0.7
<?php
function encrypt($plaintext,$secretKey){
    $plaintextData = utf8_encode($plaintext);
    $secretKeyData = utf8_encode($secretKey);
    $iv = substr($secretKey, 0, 16);
    $ciphertext = openssl_encrypt($plaintextData, 'AES-128-CBC', $secretKeyData, OPENSSL_RAW_DATA, $iv);
    return base64_encode($ciphertext);
}

$rawData = "address=0x755CA9224E613252c06ae9C20825113Dda1971aa11660287337793&appId=f83Is2**********";
$sign = encrypt($rawData,"4Yn*************");
printf("sign is: %s\n",$sign);
$urlEncodeData = urlencode($sign);
printf("encode sign is:: %s",$urlEncodeData);
?>
//go version go1.18.2
package main

import (
    "bytes"
    "crypto/aes"
    "crypto/cipher"
    "encoding/base64"
    "fmt"
    "net/url"
)

func encrypt(plainText, secretKeyData string) string {
    plainTextData := []byte(plainText)
    secretKey := []byte(secretKeyData)
    iv := secretKey[:16]

    c, err := aes.NewCipher(secretKey)
    if err != nil {
        fmt.Println("AES encrypting exception, msg is:", err)
        return ""
    }

    blockSize := c.BlockSize()
    plaintext := PKCS5Padding(plainTextData, blockSize)
    ivSpec := iv
    mode := cipher.NewCBCEncrypter(c, ivSpec)
    encrypted := make([]byte, len(plaintext))
    mode.CryptBlocks(encrypted, plaintext)

    return base64.StdEncoding.EncodeToString(encrypted)
}

func PKCS5Padding(src []byte, blockSize int) []byte {
    padding := blockSize - len(src)%blockSize
    padtext := bytes.Repeat([]byte{byte(padding)}, padding)
    return append(src, padtext...)
}

func main() {

    rawData := "address=0x755CA9224E613252c06ae9C20825113Dda1971aa11660287337793&appId=f83Is2**********"
    sign := encrypt(rawData,"4Yn*************")
    fmt.Printf("sign is %s \n", sign)
    encodeSign := url.QueryEscape(sign)
    fmt.Printf("encode sign is %s \n", encodeSign)

}