客户端API报文加解密流程
客户端API的请求参数和返回值部分,需要进行加密处理
加解密流程
每次请求发起,调用客户端API的参数和返回值都是需要进行加解密处理的
- 每次加解密所使用的密钥是非固定的,参见:服务端API / 获取访问凭证 / 获取客户端API访问凭证 返回响应中的
aes_key
- 对于请求参数而言,
x-www-form-urlencoded
的value部分,需要加密处理。
```http
// 以CURL命令为例,仅参数值需要加密处理
curl --location --request POST 'http://127.0.0.1:9887/remote_control' \
--header 'Authorization: Bearer {authcode}'
--data-urlencode 'fastcode=nDXKJm64qxxL9bRJWdqIdA=='
--data-urlencode 'verifycode=rs0LfNpjsDt0kO3wC4seZg=='
- 对于响应结果而言,返回的JSON字符串中,仅data属性是需要解密处理的,举例说明:
```json
// API返回结果
{
"code": 200,
"message": "success",
"data": "GxVEtiCSdJY89wbeFjiH36jSVOhhES/RhkY+7Ssm5DbaMR1OGgsR3QOJNxF/AyPQjU/p5sIkhtYR/JmlCi0gPMy/I1XwtrsU36SWbCAXw2DtgOv1Bdrmh2kuVAstHHdALKSXpWxCQVn/OP9QiSgGrQ/FnyEBc90WFLWuIAj/wRMXyOTa7Jf27Pr5msWmKgRPKrCCmUSexmhTJt9AwHjALjEt1BN8huPFZxTNCyHOD+iqtUR11FPN4acjKj10hVBx+rEmBQbJYW4tecKJuaUDBQ=="
}
// 解密后的结果为:
{
"code": 200,
"message": "success",
"data": "{\n\t\"fastcode\" : \"612261389\",\n\t\"hostname\" : \"DESKTOP-UTNJ89K\",\n\t\"macaddress\" : \"74:86:E2:00:20:D5\",\n\t\"remoteid\" : \"1363125803\",\n\t\"sunlogincode\" : \"4032-0856-7530-0210-7592\",\n\t\"verifycode\" : \"6em94i\"\n}"
}
加密算法
加密算法采用
AES
,运算模式:ECB
,填充模式:PKCS7
,密钥长度:256bit
以Golang为例,下列代码提供了加解密的函数,可供您参考。
// SunloginApiCipher 负责对API的报文进行加解密操作
type SunloginApiCipher struct {
AesKey []byte
}
// Encrypt 执行加密操作
func (sae *SunloginApiCipher) Encrypt(src []byte) (string, error) {
block, err := aes.NewCipher(sae.AesKey)
if err != nil {
return "", err
}
blockSize := block.BlockSize()
src = pkcs7Padding(src, blockSize)
encrypted := make([]byte, len(src))
for bs, be := 0, blockSize; bs < len(src); bs, be = bs+blockSize, be+blockSize {
block.Encrypt(encrypted[bs:be], src[bs:be])
}
return base64.StdEncoding.EncodeToString(encrypted), nil
}
// Decrypt 执行解密操作
func (sae *SunloginApiCipher) Decrypt(encryptedStr string) ([]byte, error) {
encrypted, err := base64.StdEncoding.DecodeString(encryptedStr)
if err != nil {
return []byte{}, err
}
block, err := aes.NewCipher(sae.AesKey)
if err != nil {
return []byte{}, err
}
blockSize := block.BlockSize()
decrypted := make([]byte, len(encrypted))
for bs, be := 0, blockSize; bs < len(encrypted); bs, be = bs+blockSize, be+blockSize {
block.Decrypt(decrypted[bs:be], encrypted[bs:be])
}
return pkcs7UnPadding(decrypted), nil
}
// pkcs7Padding 实现PKCS#7填充
func pkcs7Padding(ciphertext []byte, blockSize int) []byte {
padding := blockSize - len(ciphertext)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(ciphertext, padtext...)
}
// pkcs7UnPadding 实现PKCS#7填充的移除(解密时使用)
func pkcs7UnPadding(origData []byte) []byte {
length := len(origData)
unpadding := int(origData[length-1])
return origData[:(length - unpadding)]
}
func TestEncryptAndDecrypt(t *testing.T) {
cipher := &SunloginApiCipher{AesKey: []byte("vflzqa8qy3fy091np1h2fewktj1yyx58")}
// 加密
encrypt, err := cipher.Encrypt([]byte("hello world"))
if err != nil {
t.Fatal(err)
}
t.Logf("encrypt = %s", encrypt)
// 解密
decrypt, err := cipher.Decrypt(encrypt)
if err != nil {
t.Fatal(err)
}
t.Logf("decrypt = %s", decrypt)
}
验证您的加密算法
使用您使用的语言进行加密算法封装,如果加密结果与下列一致,则代表加密算法一致。
- 使用密钥:
vflzqa8qy3fy091np1h2fewktj1yyx58
- 明文字符:
向日葵,国民远控,守护国民安全
- 加密结果:
YH+PAtr8YmQ+O0c5UHKAMWIS/fcIZIesNHTgDYLr07HE9FBwBPZq5aGJp/Me3ab4
修改于 6 个月前