Skip to main content

加密解密

某NS的NPC事件加密解密

HASH_DATA // 255位的hash
KEY // 反编译得到的key
import * as crypto from 'crypto';

const HASH_DATA = Array.from({ length: 255 }, (_, i) => i);
const KEY = HASH_DATA.map((val) => String.fromCharCode(val)).join('');
const KEY_BYTES_DATA = Buffer.from(KEY, 'hex');
const IV = Buffer.alloc(8);

class NpcDataParser {
static fixDataLen(data: string, num: number = 8): Buffer {
const paddingStr = Buffer.alloc(1, 0x00);
const fixData = Buffer.from(data, 'binary');
const paddingLength = num - (fixData.length % num);
return Buffer.concat([fixData, paddingStr.repeat(paddingLength)]);
}

static calculateHash(data: string): [number, number] {
let resultData = 0;
const decryptedData = this.fixDataLen(data, 8).toString('binary');

for (let i = 0; i < decryptedData.length; i++) {
resultData = HASH_DATA[(resultData & 0xFF) ^ decryptedData.charCodeAt(i)] ^ (resultData >>> 8);
}

return [resultData & 0xFF, resultData >>> 8];
}

static encodeData(data: string): Buffer {
try {
const keyIndexEn0 = Buffer.alloc(1, 0x00);
const bytesIndex = keyIndexEn0.readUIntLE(0, 1) * 8;
const keyEn = KEY_BYTES_DATA.slice(bytesIndex, bytesIndex + 8);
const crpytor = crypto.createCipheriv('des', keyEn, IV);
const fixData = this.fixDataLen(data, 8);

const [byte1, byte2] = this.calculateHash(data);
const byte1Buffer = Buffer.alloc(1);
byte1Buffer.writeUIntLE(byte1, 0, 1);
const byte2Buffer = Buffer.alloc(1);
byte2Buffer.writeUIntLE(byte2, 0, 1);

const encryptData = Buffer.concat([keyIndexEn0, byte1Buffer, byte2Buffer, crpytor.update(fixData)]);
return encryptData;
} catch (e) {
console.error('加密数据失败: ', e);
return Buffer.alloc(0);
}
}

static decodeData(data: Buffer): string {
try {
const keyIndexDe = data.readUIntLE(0, 1);
const bytesIndex = keyIndexDe * 8;
const keyDecode = KEY_BYTES_DATA.slice(bytesIndex, bytesIndex + 8);
const crpytor = crypto.createDecipheriv('des', keyDecode, IV);
const decryptData = crpytor.update(data.slice(3));
return this.fixDataLen(decryptData.toString('binary')).toString('utf8');
} catch (e) {
console.error('解密数据失败: ', e);
return '';
}
}
}

const npcParser = new NpcDataParser();

if (require.main === module) {
// 使用
// 从数据库中读取
// const data = "xxxxxx";
// NpcDataParser.encodeData(data);
npcParser.decodeData(Buffer.from('12312', 'hex'));
}