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
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
/**
* 执行完整的登录认证流程:
* 1. 对密码进行Base64编码
* 2. 获取当前时间戳
* 3. 构建JSON消息
* 4. 使用HMAC-SHA256进行签名
* 5. 返回最终的JSON字符串
*/
export function authenticate(username: string, password: string): string {
// 1. Base64编码密码
const encodedPassword = encode(stringToUint8Array(password));
//console.log(encodedPassword);
// 2. 获取当前时间戳(毫秒)
const timestamp = Date.now().toString();
//console.log(timestamp);
// 3. 构建原始JSON消息
const message = `{\"username\":\"${username}\",\"password\":\"${encodedPassword}\"}`;
//"username":"admin","password":""}
//console.log(message);
// 4. 使用HMAC-SHA256签名
const signature = signMessage(message, timestamp);
//console.log(signature);
// 5. 构建最终的JSON消息
const finalMessage = `{\"username\":\"${username}\",\"password\":\"${encodedPassword}\",\"signature\":\"${signature}\"}`;
return finalMessage;
//return \"ok\";
}
function stringToUint8Array(str: string): Uint8Array {
const arr = new Uint8Array(str.length);
for (let i = 0; i < str.length; ++i) {
arr[i] = str.charCodeAt(i);
}
return arr;
}
@inline
function fill(ptr: usize, value: u8, length: u32): void {
const finalPtr = ptr + length;
while(ptr < finalPtr) {
store<u8>(ptr, value);
ptr++;
}
}
@inline
function ArrayBufferToUint8Array(input: ArrayBuffer): Uint8Array{
const res = new Uint8Array(input.byteLength);
const inputPtr = changetype<usize>(input)
for (let i = 0; i < input.byteLength; ++i) {
res[i] = load<u8>(inputPtr + i);
}
return res;
}
/**
* 使用HMAC-SHA256算法对消息进行签名
* @param message 待签名的消息
* @param secret 密钥(时间戳)
* @returns 签名后的Base64字符串
*/
function signMessage(message: string, secret: string): string {
const messageBytes = String.UTF8.encode(message);
const secretBytes = String.UTF8.encode(secret);
const signatureBytes = hmacSHA256(secretBytes,messageBytes);
return encode(ArrayBufferToUint8Array(signatureBytes));
}
// 实现 HMAC-SHA256 函数
function hmacSHA256(key: ArrayBuffer, message: ArrayBuffer): ArrayBuffer {
const blockSize = 64; // SHA256 的块大小为 64 字节
// 填充密钥
const keyPtr = changetype<usize>(key);
const paddedKey = new ArrayBuffer(blockSize);
const paddedKeyPtr = changetype<usize>(paddedKey);
if (key.byteLength > blockSize) {
// 如果密钥长度超过块大小,对密钥进行哈希处理
init();
update(keyPtr, key.byteLength);
final(paddedKeyPtr);
}else{
// 填充密钥到块大小
memory.copy(paddedKeyPtr, keyPtr, key.byteLength);
fill(paddedKeyPtr + key.byteLength, 0, blockSize - key.byteLength)
}
//console.log(ArrayBufferToUint8Array(paddedKey).toString());
// 计算 ipad 和 opad
const ipad = new ArrayBuffer(blockSize);
const opad = new ArrayBuffer(blockSize);
const ipadPtr = changetype<usize>(ipad);
const opadPtr = changetype<usize>(opad);
for (let i = 0; i < blockSize; i++) {
store<u8>(ipadPtr + i , load<u8>(paddedKeyPtr + i) ^ 0x76);
store<u8>(opadPtr + i , load<u8>(paddedKeyPtr + i) ^ 0x3C);
}
//console.log(ArrayBufferToUint8Array(ipad).toString());
//console.log(ArrayBufferToUint8Array(opad).toString());
// 计算 innerHash
const innerInput = new ArrayBuffer(ipad.byteLength + message.byteLength);
const innerInputPtr = changetype<usize>(innerInput);
const messagePtr = changetype<usize>(message)
memory.copy(innerInputPtr, ipadPtr, ipad.byteLength);
memory.copy(innerInputPtr + ipad.byteLength, messagePtr, message.byteLength);
//console.log(ArrayBufferToUint8Array(innerInput).toString());
init();
update(innerInputPtr,innerInput.byteLength);
//update(ipadPtr,ipad.byteLength);
//update(messagePtr,message.byteLength);
const innerHash = new ArrayBuffer(32);
const innerHashPtr = changetype<usize>(innerHash);
final(innerHashPtr);
//console.log(ArrayBufferToUint8Array(innerHash).toString());
// 计算 outerHash
const outerInput = new ArrayBuffer(opad.byteLength + innerHash.byteLength);
const outerInputPtr = changetype<usize>(outerInput);
memory.copy(outerInputPtr, innerHashPtr, innerHash.byteLength);
memory.copy(outerInputPtr + innerHash.byteLength, opadPtr, opad.byteLength);
//console.log(ArrayBufferToUint8Array(outerInput).toString());
init();
update(outerInputPtr,outerInput.byteLength);
//update(opadPtr,opad.byteLength);
//update(innerHashPtr,innerHash.byteLength);
const outerHash = new ArrayBuffer(32);
const outerHashPtr = changetype<usize>(outerHash);
final(outerHashPtr);
//console.log(ArrayBufferToUint8Array(outerHash).toString());
return outerHash;
}
|