- Cloudflare Workers + Durable Objects - 自实现 SSH 协议引擎(ECDH-P256 + AES-256-GCM) - 前端:Vite + TypeScript + xterm.js - 支持密码认证、终端渲染、窗口自适应
62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
import { SessionKeys } from '../types';
|
|
import { concat } from './utils';
|
|
|
|
export class KeyDerivation {
|
|
static async deriveKeys(
|
|
sharedSecret: Uint8Array,
|
|
exchangeHash: Uint8Array,
|
|
sessionID: Uint8Array
|
|
): Promise<SessionKeys> {
|
|
const ivC2S = await this.expandKey(sharedSecret, exchangeHash, 'A', sessionID, 12);
|
|
const ivS2C = await this.expandKey(sharedSecret, exchangeHash, 'B', sessionID, 12);
|
|
const keyC2S = await this.expandKey(sharedSecret, exchangeHash, 'C', sessionID, 32);
|
|
const keyS2C = await this.expandKey(sharedSecret, exchangeHash, 'D', sessionID, 32);
|
|
const intKeyC2S = await this.expandKey(sharedSecret, exchangeHash, 'E', sessionID, 32);
|
|
const intKeyS2C = await this.expandKey(sharedSecret, exchangeHash, 'F', sessionID, 32);
|
|
|
|
return {
|
|
ivClientToServer: ivC2S,
|
|
ivServerToClient: ivS2C,
|
|
encKeyClientToServer: keyC2S,
|
|
encKeyServerToClient: keyS2C,
|
|
integrityKeyC2S: intKeyC2S,
|
|
integrityKeyS2C: intKeyS2C,
|
|
sessionID,
|
|
};
|
|
}
|
|
|
|
private static async expandKey(
|
|
K: Uint8Array,
|
|
H: Uint8Array,
|
|
X: string,
|
|
sessionId: Uint8Array,
|
|
needed: number
|
|
): Promise<Uint8Array> {
|
|
const hashLen = 32;
|
|
const rounds = Math.ceil(needed / hashLen);
|
|
const result = new Uint8Array(needed);
|
|
let offset = 0;
|
|
|
|
let key = new Uint8Array(
|
|
await crypto.subtle.digest('SHA-256',
|
|
concat(K, H, new TextEncoder().encode(X), sessionId)
|
|
)
|
|
);
|
|
result.set(key.slice(0, Math.min(hashLen, needed)), 0);
|
|
offset += hashLen;
|
|
|
|
for (let i = 1; i < rounds; i++) {
|
|
key = new Uint8Array(
|
|
await crypto.subtle.digest('SHA-256',
|
|
concat(K, H, key, sessionId)
|
|
)
|
|
);
|
|
const remaining = needed - offset;
|
|
result.set(key.slice(0, Math.min(hashLen, remaining)), offset);
|
|
offset += hashLen;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|