s2w / src /services /authService.js
dvc890's picture
Upload 11 files
3c8ff75 verified
// authService.js
const { encrypt, decrypt } = require('../utils/cryptoUtils');
// 简单的内存存储用于保存会话密钥
// 在生产环境中,应该使用数据库或其他持久化存储
const sessionKeys = new Map();
/**
* 生成会话密钥
* @param {string} clientId - 客户端标识
* @returns {string} 会话密钥
*/
function generateSessionKey(clientId) {
// 生成一个随机的会话密钥
const sessionKey = require('crypto').randomBytes(32).toString('hex');
// 保存会话密钥
sessionKeys.set(clientId, sessionKey);
return sessionKey;
}
/**
* 验证客户端
* @param {string} clientId - 客户端标识
* @param {string} clientSecret - 客户端密钥
* @returns {boolean} 验证是否成功
*/
function authenticateClient(clientId, clientSecret) {
// 在实际应用中,应该从数据库或其他安全存储中获取客户端密钥
// 这里为了简化,使用硬编码的密钥
const validClientId = 'test-client';
const validClientSecret = 'test-secret';
return clientId === validClientId && clientSecret === validClientSecret;
}
/**
* 获取客户端的会话密钥
* @param {string} clientId - 客户端标识
* @returns {string|null} 会话密钥或 null
*/
function getSessionKey(clientId) {
return sessionKeys.get(clientId) || null;
}
/**
* 删除客户端的会话密钥
* @param {string} clientId - 客户端标识
*/
function removeSessionKey(clientId) {
sessionKeys.delete(clientId);
}
/**
* 加密数据包
* @param {Buffer} data - 要加密的数据
* @param {string} clientId - 客户端标识
* @returns {Buffer} 加密后的数据
*/
function encryptPacket(data, clientId) {
const sessionKey = getSessionKey(clientId);
if (!sessionKey) {
throw new Error('未找到会话密钥');
}
// 加密数据
const encrypted = encrypt(data, sessionKey);
// 将加密参数和数据组合成一个缓冲区
// 格式: salt(16) + iv(12) + authTag(16) + encryptedData(n)
const result = Buffer.concat([
encrypted.salt,
encrypted.iv,
encrypted.authTag,
encrypted.data
]);
return result;
}
/**
* 解密数据包
* @param {Buffer} encryptedData - 加密的数据
* @param {string} clientId - 客户端标识
* @returns {Buffer} 解密后的数据
*/
function decryptPacket(encryptedData, clientId) {
const sessionKey = getSessionKey(clientId);
if (!sessionKey) {
throw new Error('未找到会话密钥');
}
// 解析加密参数
const salt = encryptedData.slice(0, 16);
const iv = encryptedData.slice(16, 28);
const authTag = encryptedData.slice(28, 44);
const data = encryptedData.slice(44);
// 解密数据
return decrypt(data, salt, iv, authTag, sessionKey);
}
module.exports = {
generateSessionKey,
authenticateClient,
getSessionKey,
removeSessionKey,
encryptPacket,
decryptPacket
};