52 lines
1.7 KiB
JavaScript
52 lines
1.7 KiB
JavaScript
const crypto = require("crypto");
|
||
const config = require("../../config/config");
|
||
|
||
/**
|
||
* 管理端查看 Token 明文用:AES-256-GCM,密钥来自环境变量或 config.biz_token_enc_key。
|
||
*/
|
||
function get_key_32() {
|
||
const raw = process.env.BIZ_TOKEN_ENC_KEY || config.biz_token_enc_key;
|
||
if (!raw) {
|
||
return crypto.createHash("sha256").update("dev-biz-token-enc-set-BIZ_TOKEN_ENC_KEY", "utf8").digest();
|
||
}
|
||
return crypto.createHash("sha256").update(String(raw), "utf8").digest();
|
||
}
|
||
|
||
function encrypt_plain_for_storage(plain) {
|
||
if (plain == null || plain === "") return null;
|
||
const key = get_key_32();
|
||
const iv = crypto.randomBytes(12);
|
||
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
|
||
const enc = Buffer.concat([cipher.update(String(plain), "utf8"), cipher.final()]);
|
||
const tag = cipher.getAuthTag();
|
||
const payload = {
|
||
v: 1,
|
||
iv: iv.toString("base64"),
|
||
tag: tag.toString("base64"),
|
||
data: enc.toString("base64"),
|
||
};
|
||
return Buffer.from(JSON.stringify(payload), "utf8").toString("base64");
|
||
}
|
||
|
||
function decrypt_plain_from_storage(stored) {
|
||
if (stored == null || stored === "") return null;
|
||
try {
|
||
const payload = JSON.parse(Buffer.from(stored, "base64").toString("utf8"));
|
||
if (payload.v !== 1) return null;
|
||
const key = get_key_32();
|
||
const iv = Buffer.from(payload.iv, "base64");
|
||
const tag = Buffer.from(payload.tag, "base64");
|
||
const data = Buffer.from(payload.data, "base64");
|
||
const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
|
||
decipher.setAuthTag(tag);
|
||
return Buffer.concat([decipher.update(data), decipher.final()]).toString("utf8");
|
||
} catch {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
module.exports = {
|
||
encrypt_plain_for_storage,
|
||
decrypt_plain_from_storage,
|
||
};
|