鉴权签名&数据加密
鉴权签名
- 将代理商 ID 放入到 Header 头中。
- 将请求参数以 a 至 z 排序后,然后使用&x=y 的逻辑拼接
- 将
请求方法 + URL + 时间 + requestid + 请求参数
以|
分割,拼成字符串。 - 使用 hmac.sha256 对拼接好的字符串进行签名。
- 对签名之后的数据进行 base64
测试网站: https://www.devglan.com/online-tools/hmac-sha256-online
参数 | 类型 | 是否必须 | 示例值 | 备注 |
---|---|---|---|---|
URL | String | 是 | /api/v1/test | |
METHOD | String | 是 | POST | |
timestamp | String | 是 | 1701024967796 | 毫秒级即可。验证 60 秒请求超时 |
requestid | String | 是 | a0a47bf4-0507-4f04-894b-047d15bfeeff | 自定义,不可重复 |
params | String | 是 | key1=value1&key2=value2 |
Demo
URL: /api/v1/test
方法: POST
时间:1701024967796
requestid: a0a47bf4-0507-4f04-894b-047d15bfeeff
参数: key1=value1&key2=value2// 请求方法 + URL + 时间 + requestid + 请求参数
POST|/api/v1/test|1701024967796|a0a47bf4-0507-4f04-894b-047d15bfeeff|key1=value1&key2=value2假如 Sign 值为 a3e43e0a51ad9bf25b3fe7dbc40b88e25f1921a1a0f23a912c1c13ac7219c6ca, Base64之后为 f+B4V5buwFnDLNmMlniNPhswh15G1lwFogGjX6Yrf2I=, 将 o+Q+ClGtm/JbP+fbxAuI4l8ZIaGg8jqRLBwTrHIZxso= 放入到 X-URA-SIGN 头中
Demo Code
import hmac
import base64
from hashlib import sha256
def sign_data_sha256(data, secret):
data = data.encode('utf8')
secret = secret.encode('utf8')
signature = base64.b64encode(hmac.new(secret, data, digestmod=sha256).digest())
return signature.decode()
if __name__ == '__main__':
url = "/api/v1/test"
method = "POST"
requestid = "a0a47bf4-0507-4f04-894b-047d15bfeeff"
params = {"key1": "value1", "key2": "value2"}
time = "1701024967796"
unsign_data = "|".join([method, url, time, requestid, "&".join(["{k}={v}".format(k=k, v=params[k]) for k in sorted(params)])])
api_secret = "0a227672c20f48989b5fcdb4c00038ff"
sign_data = sign_data_sha256(unsign_data, api_secret)
print("sign data is : ", sign_data)
# print to o+Q+ClGtm/JbP+fbxAuI4l8ZIaGg8jqRLBwTrHIZxso=
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
public class HMACSHA256Signer {
public static String signDataSHA256(String data, String secret) throws Exception {
Mac sha256HMAC = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKey = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256");
sha256HMAC.init(secretKey);
byte[] hash = sha256HMAC.doFinal(data.getBytes("UTF-8"));
return Base64.getEncoder().encodeToString(hash);
}
public static void main(String[] args) throws Exception {
String url = "/api/v1/test";
String method = "POST";
String requestid = "a0a47bf4-0507-4f04-894b-047d15bfeeff";
Map<String, String> params = new TreeMap<>();
params.put("key1", "value1");
params.put("key2", "value2");
String time = "1701024967796";
String unsignData = String.join("|",
method,
url,
time,
requestid,
params.entrySet().stream()
.map(entry -> entry.getKey() + "=" + entry.getValue())
.collect(Collectors.joining("&"))
);
String apiSecret = "0a227672c20f48989b5fcdb4c00038ff";
String signData = signDataSHA256(unsignData, apiSecret);
System.out.println("sign data is : " + signData);
}
}
数据加密
加密基本信息
过程: 加密分为两对公私钥,一对是平台密钥`,一对是商户密钥。平台使用商户公钥加密商户使用私钥解密,同样,商户使用平台公钥加密,平台自己使用私钥解密。
算法: JWE RSA-OAEP-256
encrypt: A128GCM
RSA 生成规则: RSA 2048bit, 可以使用 JWK 直接生成,或者自己生成 RSA 2048 的公私钥
加密参数
{
"alg": "RSA-OAEP-256",
"enc": "A128GCM",
"kid": kid,
"typ": "JOSE",
"zip": "DEF"
}
KID 如何计算,将公钥的 PEM 格式进行 Sha256,得到指纹。
参数作用
参数 | 说明 | 算法 | 备注 |
---|---|---|---|
alg | 密钥管理算法 | RSA-OAEP-256 | |
enc | 加密算法 | A128GCM | |
typ | 加密类型 | JOSE | |
zip | 压缩类型 | DEF | 增快传输速度,降低传输内容大小 |
kid | 使用的密钥对 | sha256(public_pem).hexdigest() | 对公钥进行 hash 指纹签名,告诉对方是使用对方的哪个公钥进行签名的该套数据。 该参数为应对,当一个 Key 出现问题,但又存在多个公钥时,寻找到合适的公/私钥对加解密。 |
请求
业务私钥:用于解密响应平台的数据,确保该数据只能在业务被解密。
平台公钥:用于加密请求或响应平台的数据,该数据只能在业务方被解密。
响应
业务公钥:用于加密请求或响应平台的数据,该数据只能在业务方被解密。
平台私钥:用于解密请求平台的数据,确保该数据只能在平台被解密。
Demo
字段 | 内容 | |
---|---|---|
请求报文 | {"payload": "加密后的字符串" } | |
Header | { "alg": "RSA-OAEP-256", "enc": "A128GCM", "kid": "4B7AC601795594F8EB3C50F07E5FE4569E9B04D95A2C83F2B680BE0AA89A9E0B", "typ": "JWE", "zip": "DEF" } | |
原始报文 | { "id": "123", "hello": "world", "time": 1723976484, "tag": "UPay Encryption and decryption" } | |
加密报文 | eyJhbGciOiAiUlNBLU9BRVAtMjU2IiwgImVuYyI6ICJBMTI4R0NNIiwgImtpZCI6ICI0QjdBQzYwMTc5NTU5NEY4RUIzQzUwRjA3RTVGRTQ1NjlFOUIwNEQ5NUEyQzgzRjJCNjgwQkUwQUE4OUE5RTBCIiwgInR5cCI6ICJKV0UiLCAiemlwIjogIkRFRiJ9.vBFtYk_yN8MG_iYGA-xpU_eBnswO3e9jXimmWuuIOh54yO9umpEttC-9Ns3beJ8QKx8U37ZilRIBQZMLnBAGPvAl7v3hGx6yzSKBp3sCpbV5Ueiv4Q7CudLDbaOPk0VkGJXzSe4UidKWDs_Qzk_q7GNVHwZNYveiY28wi4hLsRc5Jzb1CQ-oLo-NnI66zs-QttPSarA-9aP_TSOSiPStNFGgRK_fP-RBwNBmx6ZrKS6WjPqc8QjaykrEgxL8FgaSgi-5C9sss8uty6kJWb6R9zecbpMpQUHvRRUefVFQqI7hcruvv2m8Yol5HHWRRGDYBNS3QFi3NPbodQT3VjxWig.Xi_RKtZ6KMmRStA9.8zXIO3mzF1XfHhUkfxqG5W4aprGR68gB_0QyyHU2nQkjBzIPHDmVWryB8-Ie_zySCOT7B-4ZqEb-n3T1untzMGD4eBaJ_87Apa8AdWBm.Sgyj_8opMH_Gj_C-EWvzhg | |
公钥 | -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvcnAzEJgN3tcyed3SayO o+2go3LrYxuNRWiYFwkDPMmcpgP4cyeasY7XjWr7dUPlwjmUf5DfG0UeasQlVu16 c/Ab8Qkj4ypopJ4hXwZUb45KVynHjcNsZVAC4fDOFBWCKSn2MJs28N4D5tZnvY9Z BQIQLMkyc0tUGl6VbSb+EOP5mZuK5lZ9yBAZioQl49rXTHQpvzz1AISmperUpsU9 oYJch5/sWS2+rkinI6cC3LZkGndSl5ruUQ1FAyLhd71JX++zVuP6EayByGnwKSg8 7RqnaSKSzPnVq4bClWE+hNlVrkuSlh1VtBXIK14qVpyNXyW01I075kbLm7zDr9LW /wIDAQAB -----END PUBLIC KEY----- | |
私钥 | -----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9ycDMQmA3e1zJ 53dJrI6j7aCjcutjG41FaJgXCQM8yZymA/hzJ5qxjteNavt1Q+XCOZR/kN8bRR5q xCVW7Xpz8BvxCSPjKmikniFfBlRvjkpXKceNw2xlUALh8M4UFYIpKfYwmzbw3gPm 1me9j1kFAhAsyTJzS1QaXpVtJv4Q4/mZm4rmVn3IEBmKhCXj2tdMdCm/PPUAhKal 6tSmxT2hglyHn+xZLb6uSKcjpwLctmQad1KXmu5RDUUDIuF3vUlf77NW4/oRrIHI afApKDztGqdpIpLM+dWrhsKVYT6E2VWuS5KWHVW0FcgrXipWnI1fJbTUjTvmRsub vMOv0tb/AgMBAAECggEABT4L7yMhkOwaCKe191IRZmBbe2obnaFhXcVIWxhQIxSM mQIH2M0f3g2awvxQ6tgIrNkLUuEwnrUM5IptQyvwBV1EQ9/ql7DXeeiZ2X24GlwV /7dd49ATRUR76a14USBCvxo6kdglEsDAGA/43CxtVB8HopJlummsp3C0LSv18sBx h8/TtUa0ttG8UodTtBdAbIwolb55lu92XV0mGHpOc9ZsgLlyn2C7o+jlujNqOhi3 YxKCkhL2jzl88qZ4mmRPGPYQQwTo1Xzd4brixwZ1Fyag2kXziE6+v9PX8s+yFsfW 3E/0ye16tfa0/qAx/4oGr9Ox4e7wXLLiN2QpR8UkEQKBgQD4W1r9y3/uKPDne/UR srt0oZQOG9OqouVNgIwzZYw8WG6fu9h+RuihRpLLLqBwCDCiPo17xyHkPufonntJ 4FkfzvL9RV2/d7FERIOPy9umsoFhv1cqD94zlf96hNj5EK1VZpHGhhZ1MCuiRr8W J/tPiCMMSOxVus3SRPw9M/IebwKBgQDDoPjR1WJb1i23uCQm9uvKXl3AgJ9ltfHA JuRR2SO5XxOkZ5HxG+QSAkd9Og4kQAN6MQ9HMh1sR8xa75ck9G5YgmAGBtzRr68L RpcWvT1MNN81hkOrq3pvkrLkepSyz174EIV3m3aTOXaqSe0TOtPN/mU57NxWgyFz QyrubvcYcQKBgQCi2VxfwHlhU+0rDIfUlAsA3hYz7iEr6WZMHHdSGEsNIrte+BBs NNjDL4B/xFIlQ+mH6VZijF93x5vPV2PmPDqUdeG1Gy/upXBSIE7YEkc0FiZqTsm7 5e3Ai6Ga19Nh9YKC1h/OOgwtyWlDHfqcb5kFPHIm0wZM7JGbR+rRwucG9wKBgFc7 JRgz5Rr8QwCD/KLfQb7IG1fmQq1Q1w6OiQqyH0reSVzqzdnMTQN2vrfpNjsVzDcl PyHJB/OrhEUcRrI0yCtxXy3wy3A4vX3yqRZ7paSggtNUHkKjQQIVUO2udzXQYBGP FGSEDviRDAfc1PjZJ27YO/z7UDjHWhgSYEdXdZkRAoGAPpHataBL9NOHZG4zSmCZ jw9yXHTe9xuZl2mkYFgMVzcoGvMjS4PFWDncpiDaVef9rvkY1SlmkMjejOb4KxyI eUkVcbUjvHQ786s4Ul+kdPJehx5B9Av0QhE1D1TVXPUxkx5Xa7usYW3HR0CmeN/1 IFK8O6Hrcn4W90kIgq86hng= -----END PRIVATE KEY----- |
Demo Code
from jwcrypto import jwk, jwe
import json
from hashlib import sha256
class JWECrypto(object):
header = {
'alg': 'RSA-OAEP-256',
'enc': 'A128GCM',
'kid': None,
"typ": "JWE",
"zip": "DEF"
}
def __init__(self, public_key=None, private_key=None):
if private_key and public_key:
self.private_key = jwk.JWK.from_pem(private_key.encode('utf-8'))
self.public_key = jwk.JWK.from_pem(public_key.encode('utf-8'))
elif private_key and public_key is None:
self.private_key = jwk.JWK.from_pem(private_key.encode('utf-8'))
self.public_key = self.private_key.public()
elif public_key and private_key is None:
self.private_key = None
self.public_key = jwk.JWK.from_pem(public_key.encode('utf-8'))
elif public_key is None and private_key is None:
# 生产上不要用,这里只是为了 Demo 而已,生产上会千万数据异常。因为 RSA Key 不可控。
self.private_key = jwk.JWK(generate='RSA')
self.public_key = self.private_key.export_public()
self.public_key = self.private_key.public()
def encrypt(self, payload: dict):
header = self.header.copy()
kid = sha256(self.public_key.export_to_pem()).hexdigest().upper()
header['kid'] = kid
jwetoken = jwe.JWE(
json.dumps(payload),
json.dumps(header)
)
jwetoken.add_recipient(self.public_key)
encrypt_token = jwetoken.serialize(True)
return encrypt_token
def decrypt(self, encrypt_token: str):
jwetoken = jwe.JWE()
jwetoken.deserialize(encrypt_token, key=self.private_key)
decrypted_payload = jwetoken.payload
payload_json = json.loads(decrypted_payload)
return payload_json
if __name__ == '__main__':
private_key = """
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9ycDMQmA3e1zJ
53dJrI6j7aCjcutjG41FaJgXCQM8yZymA/hzJ5qxjteNavt1Q+XCOZR/kN8bRR5q
xCVW7Xpz8BvxCSPjKmikniFfBlRvjkpXKceNw2xlUALh8M4UFYIpKfYwmzbw3gPm
1me9j1kFAhAsyTJzS1QaXpVtJv4Q4/mZm4rmVn3IEBmKhCXj2tdMdCm/PPUAhKal
6tSmxT2hglyHn+xZLb6uSKcjpwLctmQad1KXmu5RDUUDIuF3vUlf77NW4/oRrIHI
afApKDztGqdpIpLM+dWrhsKVYT6E2VWuS5KWHVW0FcgrXipWnI1fJbTUjTvmRsub
vMOv0tb/AgMBAAECggEABT4L7yMhkOwaCKe191IRZmBbe2obnaFhXcVIWxhQIxSM
mQIH2M0f3g2awvxQ6tgIrNkLUuEwnrUM5IptQyvwBV1EQ9/ql7DXeeiZ2X24GlwV
/7dd49ATRUR76a14USBCvxo6kdglEsDAGA/43CxtVB8HopJlummsp3C0LSv18sBx
h8/TtUa0ttG8UodTtBdAbIwolb55lu92XV0mGHpOc9ZsgLlyn2C7o+jlujNqOhi3
YxKCkhL2jzl88qZ4mmRPGPYQQwTo1Xzd4brixwZ1Fyag2kXziE6+v9PX8s+yFsfW
3E/0ye16tfa0/qAx/4oGr9Ox4e7wXLLiN2QpR8UkEQKBgQD4W1r9y3/uKPDne/UR
srt0oZQOG9OqouVNgIwzZYw8WG6fu9h+RuihRpLLLqBwCDCiPo17xyHkPufonntJ
4FkfzvL9RV2/d7FERIOPy9umsoFhv1cqD94zlf96hNj5EK1VZpHGhhZ1MCuiRr8W
J/tPiCMMSOxVus3SRPw9M/IebwKBgQDDoPjR1WJb1i23uCQm9uvKXl3AgJ9ltfHA
JuRR2SO5XxOkZ5HxG+QSAkd9Og4kQAN6MQ9HMh1sR8xa75ck9G5YgmAGBtzRr68L
RpcWvT1MNN81hkOrq3pvkrLkepSyz174EIV3m3aTOXaqSe0TOtPN/mU57NxWgyFz
QyrubvcYcQKBgQCi2VxfwHlhU+0rDIfUlAsA3hYz7iEr6WZMHHdSGEsNIrte+BBs
NNjDL4B/xFIlQ+mH6VZijF93x5vPV2PmPDqUdeG1Gy/upXBSIE7YEkc0FiZqTsm7
5e3Ai6Ga19Nh9YKC1h/OOgwtyWlDHfqcb5kFPHIm0wZM7JGbR+rRwucG9wKBgFc7
JRgz5Rr8QwCD/KLfQb7IG1fmQq1Q1w6OiQqyH0reSVzqzdnMTQN2vrfpNjsVzDcl
PyHJB/OrhEUcRrI0yCtxXy3wy3A4vX3yqRZ7paSggtNUHkKjQQIVUO2udzXQYBGP
FGSEDviRDAfc1PjZJ27YO/z7UDjHWhgSYEdXdZkRAoGAPpHataBL9NOHZG4zSmCZ
jw9yXHTe9xuZl2mkYFgMVzcoGvMjS4PFWDncpiDaVef9rvkY1SlmkMjejOb4KxyI
eUkVcbUjvHQ786s4Ul+kdPJehx5B9Av0QhE1D1TVXPUxkx5Xa7usYW3HR0CmeN/1
IFK8O6Hrcn4W90kIgq86hng=
-----END PRIVATE KEY-----
"""
public_key = """
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvcnAzEJgN3tcyed3SayO
o+2go3LrYxuNRWiYFwkDPMmcpgP4cyeasY7XjWr7dUPlwjmUf5DfG0UeasQlVu16
c/Ab8Qkj4ypopJ4hXwZUb45KVynHjcNsZVAC4fDOFBWCKSn2MJs28N4D5tZnvY9Z
BQIQLMkyc0tUGl6VbSb+EOP5mZuK5lZ9yBAZioQl49rXTHQpvzz1AISmperUpsU9
oYJch5/sWS2+rkinI6cC3LZkGndSl5ruUQ1FAyLhd71JX++zVuP6EayByGnwKSg8
7RqnaSKSzPnVq4bClWE+hNlVrkuSlh1VtBXIK14qVpyNXyW01I075kbLm7zDr9LW
/wIDAQAB
-----END PUBLIC KEY-----
"""
payload = {
"id": "123",
"hello": "world",
"time": 1723976484,
"tag": "UPay Encryption and decryption"
}
# No Key
jwe_crypto = JWECrypto()
print(jwe_crypto.private_key)
print(jwe_crypto.public_key)
encrypt_token = jwe_crypto.encrypt(payload)
print(encrypt_token)
decrypted_payload = jwe_crypto.decrypt(encrypt_token)
print(decrypted_payload)
# Just public Key, only Sign
jwe_crypto = JWECrypto(public_key=public_key)
encrypt_token = jwe_crypto.encrypt(payload)
print(encrypt_token)
# Just private key, only design
jwe_crypto = JWECrypto(private_key=private_key)
# design last encrypt token
decrypted_payload = jwe_crypto.decrypt(encrypt_token)
print(decrypted_payload)
# have both of key of rsa
jwe_crypto = JWECrypto(public_key=public_key, private_key=private_key)
encrypt_token = jwe_crypto.encrypt(payload)
print(encrypt_token)
decrypted_payload = jwe_crypto.decrypt(encrypt_token)
print(decrypted_payload)
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.*;
import com.nimbusds.jose.jwk.*;
import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jwt.JWTClaimsSet;
import com.nimbusds.jwt.SignedJWT;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
public class JWECrypto {
private static final JWEAlgorithm JWE_ALG = JWEAlgorithm.RSA_OAEP_256;
private static final EncryptionMethod ENC_METHOD = EncryptionMethod.A128GCM;
private RSAPublicKey publicKey;
private RSAPrivateKey privateKey;
public JWECrypto(String publicKeyPEM, String privateKeyPEM) throws Exception {
if (publicKeyPEM != null) {
this.publicKey = loadPublicKey(publicKeyPEM);
}
if (privateKeyPEM != null) {
this.privateKey = loadPrivateKey(privateKeyPEM);
}
}
public String encrypt(String payload) throws Exception {
String kid = generateKid(publicKey);
JWEHeader header = new JWEHeader.Builder(JWE_ALG, ENC_METHOD)
.type(JOSEObjectType.JWE)
.keyID(kid)
.compressionAlgorithm(CompressionAlgorithm.DEF)
.build();
JWEObject jweObject = new JWEObject(header, new Payload(payload));
RSAEncrypter encrypter = new RSAEncrypter(publicKey);
jweObject.encrypt(encrypter);
return jweObject.serialize();
}
public String decrypt(String jweString) throws Exception {
JWEObject jweObject = JWEObject.parse(jweString);
RSADecrypter decrypter = new RSADecrypter(privateKey);
jweObject.decrypt(decrypter);
return jweObject.getPayload().toString();
}
private RSAPublicKey loadPublicKey(String publicKeyPEM) throws Exception {
String publicKeyPEMFormatted = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----", "")
.replace("-----END PUBLIC KEY-----", "")
.replaceAll("\\s", "");
byte[] encoded = Base64.getDecoder().decode(publicKeyPEMFormatted);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(encoded);
return (RSAPublicKey) keyFactory.generatePublic(keySpec);
}
private RSAPrivateKey loadPrivateKey(String privateKeyPEM) throws Exception {
String privateKeyPEMFormatted = privateKeyPEM.replace("-----BEGIN PRIVATE KEY-----", "")
.replace("-----END PRIVATE KEY-----", "")
.replaceAll("\\s", "");
byte[] encoded = Base64.getDecoder().decode(privateKeyPEMFormatted);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);
}
private String generateKid(RSAPublicKey publicKey) throws NoSuchAlgorithmException {
byte[] publicKeyBytes = publicKey.getEncoded();
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(publicKeyBytes);
return Base64.getUrlEncoder().withoutPadding().encodeToString(hash).toUpperCase();
}
public static void main(String[] args) throws Exception {
String privateKeyPEM = """
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9ycDMQmA3e1zJ
53dJrI6j7aCjcutjG41FaJgXCQM8yZymA/hzJ5qxjteNavt1Q+XCOZR/kN8bRR5q
xCVW7Xpz8BvxCSPjKmikniFfBlRvjkpXKceNw2xlUALh8M4UFYIpKfYwmzbw3gPm
1me9j1kFAhAsyTJzS1QaXpVtJv4Q4/mZm4rmVn3IEBmKhCXj2tdMdCm/PPUAhKal
6tSmxT2hglyHn+xZLb6uSKcjpwLctmQad1KXmu5RDUUDIuF3vUlf77NW4/oRrIHI
afApKDztGqdpIpLM+dWrhsKVYT6E2VWuS5KWHVW0FcgrXipWnI1fJbTUjTvmRsub
vMOv0tb/AgMBAAECggEABT4L7yMhkOwaCKe191IRZmBbe2obnaFhXcVIWxhQIxSM
mQIH2M0f3g2awvxQ6tgIrNkLUuEwnrUM5IptQyvwBV1EQ9/ql7DXeeiZ2X24GlwV
/7dd49ATRUR76a14USBCvxo6kdglEsDAGA/43CxtVB8HopJlummsp3C0LSv18sBx
h8/TtUa0ttG8UodTtBdAbIwolb55lu92XV0mGHpOc9ZsgLlyn2C7o+jlujNqOhi3
YxKCkhL2jzl88qZ4mmRPGPYQQwTo1Xzd4brixwZ1Fyag2kXziE6+v9PX8s+yFsfW
3E/0ye16tfa0/qAx/4oGr9Ox4e7wXLLiN2QpR8UkEQKBgQD4W1r9y3/uKPDne/UR
srt0oZQOG9OqouVNgIwzZYw8WG6fu9h+RuihRpLLLqBwCDCiPo17xyHkPufonntJ
4FkfzvL9RV2/d7FERIOPy9umsoFhv1cqD94zlf96hNj5EK1VZpHGhhZ1MCuiRr8W
J/tPiCMMSOxVus3SRPw9M/IebwKBgQDDoPjR1WJb1i23uCQm9uvKXl3AgJ9ltfHA
JuRR2SO5XxOkZ5HxG+QSAkd9Og4kQAN6MQ9HMh1sR8xa75ck9G5YgmAGBtzRr68L
RpcWvT1MNN81hkOrq3pvkrLkepSyz174EIV3m3aTOXaqSe0TOtPN/mU57NxWgyFz
QyrubvcYcQKBgQCi2VxfwHlhU+0rDIfUlAsA3hYz7iEr6WZMHHdSGEsNIrte+BBs
NNjDL4B/xFIlQ+mH6VZijF93x5vPV2PmPDqUdeG1Gy/upXBSIE7YEkc0FiZqTsm7
5e3Ai6Ga19Nh9YKC1h/OOgwtyWlDHfqcb5kFPHIm0wZM7JGbR+rRwucG9wKBgFc7
JRgz5Rr8QwCD/KLfQb7IG1fmQq1Q1w6OiQqyH0reSVzqzdnMTQN2vrfpNjsVzDcl
PyHJB/OrhEUcRrI0yCtxXy3wy3A4vX3yqRZ7paSggtNUHkKjQQIVUO2udzXQYBGP
FGSEDviRDAfc1PjZJ27YO/z7UDjHWhgSYEdXdZkRAoGAPpHataBL9NOHZG4zSmCZ
jw9yXHTe9xuZl2mkYFgMVzcoGvMjS4PFWDncpiDaVef9rvkY1SlmkMjejOb4KxyI
eUkVcbUjvHQ786s4Ul+kdPJehx5B9Av0QhE1D1TVXPUxkx5Xa7usYW3HR0CmeN/1
IFK8O6Hrcn4W90kIgq86hng=
-----END PRIVATE KEY-----
""";
String publicKeyPEM = """
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvcnAzEJgN3tcyed3SayO
o+2go3LrYxuNRWiYFwkDPMmcpgP4cyeasY7XjWr7dUPlwjmUf5DfG0UeasQlVu16
c/Ab8Qkj4ypopJ4hXwZUb45KVynHjcNsZVAC4fDOFBWCKSn2MJs28N4D5tZnvY9Z
BQIQLMkyc0tUGl6VbSb+EOP5mZuK5lZ9yBAZioQl49rXTHQpvzz1AISmperUpsU9
oYJch5/sWS2+rkinI6cC3LZkGndSl5ruUQ1FAyLhd71JX++zVuP6EayByGnwKSg8
7RqnaSKSzPnVq4bClWE+hNlVrkuSlh1VtBXIK14qVpyNXyW01I075kbLm7zDr9LW
/wIDAQAB
-----END PUBLIC KEY-----
""";
String payload = "{\"id\":\"123\",\"hello\":\"world\",\"time\":1723976484,\"tag\":\"UPay Encryption and decryption\"}";
// No Key
JWECrypto jweCrypto = new JWECrypto(null, null);
System.out.println("Private Key: " + jweCrypto.privateKey);
System.out.println("Public Key: " + jweCrypto.publicKey);
String encryptToken = jweCrypto.encrypt(payload);
System.out.println("Encrypted Token: " + encryptToken);
String decryptedPayload = jweCrypto.decrypt(encryptToken);
System.out.println("Decrypted Payload: " + decryptedPayload);
// Just public Key, only Sign
jweCrypto = new JWECrypto(publicKeyPEM, null);
encryptToken = jweCrypto.encrypt(payload);
System.out.println("Encrypted Token with Public Key: " + encryptToken);
// Just private key, only design
jweCrypto = new JWECrypto(null, privateKeyPEM);
// design last encrypt token
decryptedPayload = jweCrypto.decrypt(encryptToken);
System.out.println("Decrypted Payload with Private Key: " + decryptedPayload);
// have both of key of rsa
jweCrypto = new JWECrypto(publicKeyPEM, privateKeyPEM);
encryptToken = jweCrypto.encrypt(payload);
System.out.println("Encrypted Token with Both Keys: " + encryptToken);
decryptedPayload = jweCrypto.decrypt(encryptToken);
System.out.println("Decrypted Payload with Both Keys: " + decryptedPayload);
}
}
Demo Key
Key | Value |
---|---|
CUSTOMERID | 1111111111 |
APIKEY | 51d6dc09-e641-4162-a9e9-43fd0f3cf903 |
SECRETKEY | 0a227672c20f48989b5fcdb4c00038ff |
PublicKey | -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvcnAzEJgN3tcyed3SayO o+2go3LrYxuNRWiYFwkDPMmcpgP4cyeasY7XjWr7dUPlwjmUf5DfG0UeasQlVu16 c/Ab8Qkj4ypopJ4hXwZUb45KVynHjcNsZVAC4fDOFBWCKSn2MJs28N4D5tZnvY9Z BQIQLMkyc0tUGl6VbSb+EOP5mZuK5lZ9yBAZioQl49rXTHQpvzz1AISmperUpsU9 oYJch5/sWS2+rkinI6cC3LZkGndSl5ruUQ1FAyLhd71JX++zVuP6EayByGnwKSg8 7RqnaSKSzPnVq4bClWE+hNlVrkuSlh1VtBXIK14qVpyNXyW01I075kbLm7zDr9LW /wIDAQAB -----END PUBLIC KEY----- |
PrivateKey | -----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC9ycDMQmA3e1zJ 53dJrI6j7aCjcutjG41FaJgXCQM8yZymA/hzJ5qxjteNavt1Q+XCOZR/kN8bRR5q xCVW7Xpz8BvxCSPjKmikniFfBlRvjkpXKceNw2xlUALh8M4UFYIpKfYwmzbw3gPm 1me9j1kFAhAsyTJzS1QaXpVtJv4Q4/mZm4rmVn3IEBmKhCXj2tdMdCm/PPUAhKal 6tSmxT2hglyHn+xZLb6uSKcjpwLctmQad1KXmu5RDUUDIuF3vUlf77NW4/oRrIHI afApKDztGqdpIpLM+dWrhsKVYT6E2VWuS5KWHVW0FcgrXipWnI1fJbTUjTvmRsub vMOv0tb/AgMBAAECggEABT4L7yMhkOwaCKe191IRZmBbe2obnaFhXcVIWxhQIxSM mQIH2M0f3g2awvxQ6tgIrNkLUuEwnrUM5IptQyvwBV1EQ9/ql7DXeeiZ2X24GlwV /7dd49ATRUR76a14USBCvxo6kdglEsDAGA/43CxtVB8HopJlummsp3C0LSv18sBx h8/TtUa0ttG8UodTtBdAbIwolb55lu92XV0mGHpOc9ZsgLlyn2C7o+jlujNqOhi3 YxKCkhL2jzl88qZ4mmRPGPYQQwTo1Xzd4brixwZ1Fyag2kXziE6+v9PX8s+yFsfW 3E/0ye16tfa0/qAx/4oGr9Ox4e7wXLLiN2QpR8UkEQKBgQD4W1r9y3/uKPDne/UR srt0oZQOG9OqouVNgIwzZYw8WG6fu9h+RuihRpLLLqBwCDCiPo17xyHkPufonntJ 4FkfzvL9RV2/d7FERIOPy9umsoFhv1cqD94zlf96hNj5EK1VZpHGhhZ1MCuiRr8W J/tPiCMMSOxVus3SRPw9M/IebwKBgQDDoPjR1WJb1i23uCQm9uvKXl3AgJ9ltfHA JuRR2SO5XxOkZ5HxG+QSAkd9Og4kQAN6MQ9HMh1sR8xa75ck9G5YgmAGBtzRr68L RpcWvT1MNN81hkOrq3pvkrLkepSyz174EIV3m3aTOXaqSe0TOtPN/mU57NxWgyFz QyrubvcYcQKBgQCi2VxfwHlhU+0rDIfUlAsA3hYz7iEr6WZMHHdSGEsNIrte+BBs NNjDL4B/xFIlQ+mH6VZijF93x5vPV2PmPDqUdeG1Gy/upXBSIE7YEkc0FiZqTsm7 5e3Ai6Ga19Nh9YKC1h/OOgwtyWlDHfqcb5kFPHIm0wZM7JGbR+rRwucG9wKBgFc7 JRgz5Rr8QwCD/KLfQb7IG1fmQq1Q1w6OiQqyH0reSVzqzdnMTQN2vrfpNjsVzDcl PyHJB/OrhEUcRrI0yCtxXy3wy3A4vX3yqRZ7paSggtNUHkKjQQIVUO2udzXQYBGP FGSEDviRDAfc1PjZJ27YO/z7UDjHWhgSYEdXdZkRAoGAPpHataBL9NOHZG4zSmCZ jw9yXHTe9xuZl2mkYFgMVzcoGvMjS4PFWDncpiDaVef9rvkY1SlmkMjejOb4KxyI eUkVcbUjvHQ786s4Ul+kdPJehx5B9Av0QhE1D1TVXPUxkx5Xa7usYW3HR0CmeN/1 IFK8O6Hrcn4W90kIgq86hng= -----END PRIVATE KEY----- |