免登说明
一、免登流程说明
- 1、获取免登token
- 一个token只能用一次,30分钟有效
- 2、免登到员工系统
二、请求规则
获取免登token、员工手机端免登、员工PC端免登这三个接口的参数处理情况较为复杂,故在此举例说明。
假设:
当前应用信息
appKey:app123456
appSecret:123456
接口参数
mobile:19411001100
employeeId:123456
redirectUrlType:1
其中mobile、employeeId需要单独加密
公共参数
timestamp:1573012409123
首先,按照单独加密算法对需要单独加密的字段进行加密
mobile加密后的值为:S3Jw9QE5QVzYeXhaYa9I8A==
emoployeeId加密后的值为:3f8i8tfW7+I5BOG+N8xMrQ==
然后,开始计算签名(详见:开发流程中的访问流程和签名计算)
employee=3f8i8tfW7+I5BOG+N8xMrQ==
mobile=S3Jw9QE5QVzYeXhaYa9I8A==
redirectUrlType=1
timestamp=1573012409123
appKey=app123456
参数键值对按照字典排序、&连接后的签名明文如下:
appKey=app123456&employee=3f8i8tfW7+I5BOG+N8xMrQ==&mobile=S3Jw9QE5QVzYeXhaYa9I8A==&redirectUrlType=1×tamp=1573012409123
签名结果
sing:Yb3ufDXyvF5D/C9YFRh+o8YxDZg=
最后,由于加密后的数据和签名,可能会存在被http协议自动转义的字符,需要进行URLencoding处理之后再请求
三、单独加密算法
加密算法
- 假设需要加密的内容为content
- 对content使用AES加密算法进行加密。加密算法/工作模式/填充方式:AES/ECB/PKCS5Padding。
- 将加密结果通过base64编码转换为加密后的字符串。
- 加密密钥需要使用应用密钥appSecret通过如下转换获得
- 将appSecret通过SHA-1加密,得到一个byte[]数组keys
- 遍历keys,将二进制转换为十六进制字符,拼接字符,最终得到一个字符串keyStr
- 截取keyStr前16位字符串,并转换为小写字母,最终为加密密钥
java版Demo
/**
* 薪人薪事参数单独加密
*
* @param content 加密内容
* @param appSecret 密钥
* @return 加密后的结果
* @throws Exception
*/
public static String encrypt(String content, String appSecret) throws Exception {
String key = genKey(appSecret);
return aesEncrypt(content, key);
}
/**
* 生成加密时密钥key
*
* @param appSecret 应用密钥
* @return 加密时密钥
* @throws Exception
*/
private static String genKey(String appSecret) throws Exception {
byte[] keys = sha1Encrypt(appSecret);
StringBuilder keyStr = new StringBuilder();
for (byte key : keys) {
String hex = Integer.toHexString(key & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
keyStr.append(hex);
}
return keyStr.substring(0, 16).toLowerCase();
}
/**
* sha-1加密
*
* @param appSecret 加密内容
* @return 加密后字节数组
* @throws Exception
*/
private static byte[] sha1Encrypt(String appSecret) throws Exception {
byte[] bytes = appSecret.getBytes(StandardCharsets.UTF_8);
MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
return messageDigest.digest(bytes);
}
/**
* ase加密
*
* @param content 加密内容
* @param key 密钥
* @return 加密后的字符串
* @throws Exception
*/
private static String aesEncrypt(String content, String key) throws Exception {
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] contentBytes = content.getBytes(StandardCharsets.UTF_8);
byte[] resultBytes = cipher.doFinal(contentBytes);
return Base64.encodeBase64String(resultBytes);
}