- 添加API客户端、加密存储和provision/token激活逻辑 - WebSocket改用Bearer令牌认证,移除REGISTER请求 - 设备ID改为服务端下发,支持令牌刷新和强制下线处理 - 新增deviceSecret加密存储和accessToken自动刷新 - 更新设备ID获取方式为出厂SN,添加安全存储依赖
58 lines
2.0 KiB
Java
58 lines
2.0 KiB
Java
package com.ttstd.signaling.security;
|
||
|
||
import java.nio.charset.StandardCharsets;
|
||
import java.security.MessageDigest;
|
||
import java.security.NoSuchAlgorithmException;
|
||
import java.security.SecureRandom;
|
||
import java.util.Base64;
|
||
|
||
/**
|
||
* 随机 ID / 密钥生成与哈希工具。
|
||
*/
|
||
public final class TokenUtils {
|
||
|
||
private static final SecureRandom RANDOM = new SecureRandom();
|
||
private static final Base64.Encoder B64URL = Base64.getUrlEncoder().withoutPadding();
|
||
private static final char[] BASE62 =
|
||
"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
|
||
|
||
private TokenUtils() {
|
||
}
|
||
|
||
/** 生成高熵、不可枚举的 Base62 字符串。 */
|
||
public static String randomBase62(int length) {
|
||
StringBuilder sb = new StringBuilder(length);
|
||
for (int i = 0; i < length; i++) {
|
||
sb.append(BASE62[RANDOM.nextInt(BASE62.length)]);
|
||
}
|
||
return sb.toString();
|
||
}
|
||
|
||
/** 生成 URL-safe 的随机密钥(用于 deviceSecret / refreshToken)。 */
|
||
public static String randomSecret(int bytes) {
|
||
byte[] buf = new byte[bytes];
|
||
RANDOM.nextBytes(buf);
|
||
return B64URL.encodeToString(buf);
|
||
}
|
||
|
||
/** 对不可逆凭据做 SHA-256 摘要(适用于高熵随机串,无需加盐慢哈希)。 */
|
||
public static String sha256(String raw) {
|
||
try {
|
||
MessageDigest md = MessageDigest.getInstance("SHA-256");
|
||
return B64URL.encodeToString(md.digest(raw.getBytes(StandardCharsets.UTF_8)));
|
||
} catch (NoSuchAlgorithmException e) {
|
||
throw new IllegalStateException("SHA-256 不可用", e);
|
||
}
|
||
}
|
||
|
||
/** 常量时间字符串比较。 */
|
||
public static boolean constantTimeEquals(String a, String b) {
|
||
if (a == null || b == null) {
|
||
return false;
|
||
}
|
||
return MessageDigest.isEqual(
|
||
a.getBytes(StandardCharsets.UTF_8),
|
||
b.getBytes(StandardCharsets.UTF_8));
|
||
}
|
||
}
|