熵基智联 熵基智联
首页
  • 平台介绍
  • 快速入门
  • 开发指南
  • 开通熵基智联
  • API列表
  • 附录
首页
  • 平台介绍
  • 快速入门
  • 开发指南
  • 开通熵基智联
  • API列表
  • 附录
  • 产品概述
  • 快速入门

  • 开发指南

    • 平台基本概念
    • 接口调用说明
    • 获取授权令牌
    • 推送事件加解密
      • 推送事件加解密
        • 推送事件至第三方平台
        • AES加密参数说明及各开发语言Demo
        • Java
        • Python
        • Goland
  • 开关熵基智联

  • API列表

  • 附录

  • 文档
  • 开发指南
2022-09-05
目录

推送事件加解密

# 推送事件加解密

由于数据在公开的因特网上传输,消息内容是可被截获的;如果内容未加密,则截获者可以直接阅读数据内容,存在着数据泄漏或者数据被抓包破解的风险。

数据加密

# 推送事件至第三方平台

假设开发者接收推送数据的URL设置为:http://api.3rd.com/receive (opens new window)

当用户触发回调行为时,熵基智联会发送回调消息到填写的URL。

请求内容规范如下:

请求方式: POST

请求地址: http://api.3rdcom/receive?sign=XXXXXXXX&timestamp=XXXXXXXX&nonce=XXXXXXXX

接收数据格式 :

{
    "event":"XXXXXXXXXXXXXXXXXXXXXXXX",
    "unitId": "XXXXXXXXXXXXXXXXXXXXXXX",
    "data": "XXXXXXXXXXXXXXXXXXXXXXX" 
}
1
2
3
4
5

参数说明:

参数 类型 说明
sign String 加密签名,token为开发者应用回调配置,sign = MD5-32 (token+timestamp+nonce),MD5加密。32位小写。
timestamp Long 当前Unix时间戳(毫秒),用于防止请求重放攻击(时间戳有效期为5分钟)。
nonce String 随机数。与timestamp结合使用,用于防止请求重放攻击。
unitId String 主体Id。
event String 回调事件id,唯一不重复。
data String 事件消息体加密后的字符串。

# AES加密参数说明及各开发语言Demo

sSrc: 需要加密的字串

cKey: AppKey

cIv: AppSecret
1
2
3
4
5

# Java

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AES
{
    public static void main(String args[]) throws Exception {
        // appKey
        String cKey = "DBC3KLPYUBC3KLPJ";
        // 需要加密的字串
        String cSrc = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        // appSecret;
        String cIv = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX";
        System.out.println(cSrc);
        // 加密
        long lStart = System.currentTimeMillis();
        String enString = AES.Encrypt(cSrc, cKey, cIv);
        System.out.println("加密后的字串是:" + enString);
        long lUseTime = System.currentTimeMillis() - lStart;
        System.out.println("加密耗时:" + lUseTime + "毫秒");
        // 解密
        lStart = System.currentTimeMillis();
        String DeString = AES.Decrypt(enString, cKey, cIv);
        System.out.println("解密后的字串是:" + DeString);
        lUseTime = System.currentTimeMillis() - lStart;
        System.out.println("解密耗时:" + lUseTime + "毫秒");

    }

    public static String Encrypt(String sSrc, String sKey, String sIv) throws Exception {
        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
        int blockSize = cipher.getBlockSize();
        byte[] dataBytes = sSrc.getBytes();
        int plaintextLength = dataBytes.length;
        if (plaintextLength % blockSize != 0) {
            plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
        }
        byte[] plaintext = new byte[plaintextLength];
        System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);
        SecretKeySpec keyspec = new SecretKeySpec(sKey.getBytes(), "AES");
        IvParameterSpec ivspec = new IvParameterSpec(sIv.getBytes());
        cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
        byte[] encrypted = cipher.doFinal(plaintext);
        return byte2hex(encrypted).toLowerCase();
    }

    public static String Decrypt(String sSrc, String sKey, String sIv) throws Exception {
        byte[] encrypted1      = hex2byte(sSrc);
        Cipher cipher          = Cipher.getInstance("AES/CBC/NoPadding");
        SecretKeySpec keyspec  = new SecretKeySpec(sKey.getBytes(), "AES");
        IvParameterSpec ivspec = new IvParameterSpec(sIv.getBytes());
        cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
        byte[] original = cipher.doFinal(encrypted1);
        // 去除填充
        String originalString = new String(original).replaceAll("\\u0000","");
        return originalString;
    }

    public static byte[] hex2byte(String strhex) {
        if (strhex == null) {
            return null;
        }
        int l = strhex.length();
        if (l % 2 == 1) {
            return null;
        }
        byte[] b = new byte[l / 2];
        for (int i = 0; i != l / 2; i++) {
            b[i] = (byte) Integer.parseInt(strhex.substring(i * 2, i * 2 + 2),
                    16);
        }
        return b;
    }

    public static String byte2hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

# Python

import hashlib
from Crypto import Random
from Crypto.Cipher import AES
import binascii

class AESCipher(object):

    def __init__(self):
        self.bs = 16
        self.iv = '0123456789123456'
        self.key = '1234567890123456'

    def encrypt(self, raw):
        raw = self._pad(raw)
        cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
        return binascii.hexlify(cipher.encrypt(raw))

    def decrypt(self, enc):
        enc = binascii.unhexlify(enc)
        cipher = AES.new(self.key, AES.MODE_CBC, self.iv)
        return cipher.decrypt(enc).decode('utf-8').rstrip("\0")

    def _pad(self, s):
        return s + (self.bs - len(s) % self.bs) * '\0'


crypt = AESCipher()

print crypt.encrypt('12345')
print crypt.decrypt('90b2c15e84cb78e5161f42867807c4bc')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

# Goland

// AesEncrypt 加密函数
func AesEncrypt(text []byte, key, iv []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        fmt.Println(err)
    }
    // 填充
    blockSize := block.BlockSize()
    paddText := ZeroPadding(text)
    blockMode := cipher.NewCBCEncrypter(block, iv[:blockSize])

    // 加密
    result := make([]byte, len(paddText))
    blockMode.CryptBlocks(result, paddText)
    // 返回密文
    return result, nil
}

// AesDecrypt 解密函数
func AesDecrypt(encrypter []byte, key, iv []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        fmt.Println(err)
    }
    blockSize := block.BlockSize()
    blockMode := cipher.NewCBCDecrypter(block, iv[:blockSize])
    result := make([]byte, len(encrypter))
    blockMode.CryptBlocks(result, encrypter)
    // 去除填充
    result = NullUnPadding(result)
    return result, nil
}

func ZeroPadding(in []byte) []byte {
    length := len(in)
    if length%16 == 0 {
        return in
    } else {
        blockCount := length / 16
        out := make([]byte, (blockCount+1)*16)
        var i int
        for i = 0; i < length; i++ {
            out[i] = in[i]
        }
        return out
    }
}

func NullUnPadding(in []byte) []byte {
    return bytes.TrimRight(in, string([]byte{0}))
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
获取授权令牌
开通主体

← 获取授权令牌 开通主体→

最近更新
01
记录快照管理
09-28
02
请假外出记录管理
06-14
03
教职工管理
09-14
更多文章>
Theme by Vdoing | Copyright © -2025 熵基智联 | Copyright © 2021 ZKTECO CO., LTD. All rights reserved.
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式