export type requester = 'fetch' | 'xhr' | 'wxRequest'; export const enum MODE { // 参数签名 SIGN = '1.0', // 时间限制性签名 SIGN_WITH_TIME = '1.1', // 时间限制性签名(不带盐-用户信息) SIGN_WITHOUT_SALT = '1.1.1', // 唯一限制性签名 SIGN_UUID = '1.2', // 唯一限制性签名(不带盐-用户信息) SIGN_UUID_WITHOUT_SALT = '1.2.1', // RSA参数加密 RSA = '2.0', // AES参数加密 AES = '3.0', SIGN_AES = '3.1', SIGN_UUID_AES = '3.2' } export type modeType = `${typeof MODE[keyof typeof MODE]}`; // 自定义加解密函数 type EncryptionFunctionType = (content: string, key: string, CryptoJS: CryptoJS) => string; export type fnAESEncryptType = EncryptionFunctionType; export type fnAESDecryptType = EncryptionFunctionType; export type fnGCMEncryptType = EncryptionFunctionType; export type fnGCMDecryptType = EncryptionFunctionType; export type fnRSAEncryptType = (content: string, publicKey: string, JSEncrypt: JSEncrypt) => string; export type fnRSADecryptType = (content: string, privKey: string, JSEncrypt: JSEncrypt) => string; export declare namespace encipherOptionType { interface sign { /** * 签名key */ key?: string; /** * 盐值的key(存放在cookie上字段) */ saltKey?: string; /** * 盐值,缺省时通过saltKey从cookie上获取 */ saltValue?: string | Function; /** * 签名值传递字段(后端通过在请求头或url地址获取该字段值),默认为 X-SIGN */ valueKeyName?: string; /** * 请求头需要额外进行签名的字段 */ headerKeys?: string[]; } interface aes { /** * aes加解密key */ key?: string; /** * aes自定义加密方法 */ encrypt?: fnAESEncryptType; /** * aes自定义解密方法 */ decrypt?: fnAESDecryptType; } interface gcm { /** * gcm加解密key */ key?: string; /** * gcm自定义加密方法 */ encrypt?: fnGCMEncryptType; /** * gcm自定义解密方法 */ decrypt?: fnGCMDecryptType; } interface rsa { /** * rsa私钥 */ privKey?: string; /** * rsa秘钥 */ publicKey?: string; /** * rsa自定义加密方法 */ encrypt?: fnRSAEncryptType; /** * rsa自定义解密方法 */ decrypt?: fnRSADecryptType; } } type ignoreSupportType = string | RegExp | Function; export interface configType { /** * 安全模式 */ mode?: modeType | (string & {/** */}); /** * 附加在请求上的参数,告诉后端程序,当前使用的安全模式,默认为xa-type */ securityHeaderKey?: string; /** * 自动处理请求程序类型 */ requester?: requester | requester[]; /** * 忽略规则 */ ignore?: ignoreSupportType | ignoreSupportType[]; /** * 签名配置 */ sign?: encipherOptionType.sign; /** * aes加解密配置 */ aes?: encipherOptionType.aes; /** * gcm加解密配置 */ gcm?: encipherOptionType.gcm; /** * rsa加解密配置 */ rsa?: encipherOptionType.rsa; /** * 服务器与客户端时间偏差值 */ timeDeviation?: number; /** * 是否调试模式 */ debug?: boolean; /** * 服务器时间,设置该值时会自动计算timeDeviation */ serverTime?: number | null; /** * 秘钥二次加密 */ keyEncrypt?: boolean; /** * body空值时取值 */ emptyBodyValue?: any; } export interface signHttpOptionsType { /** * 请求方法 */ method?: 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'TRACE' | 'CONNECT' | (string & {/** */}), /** * 请求头内容 */ headers?: any, /** * 请求体数据 */ body?: any, /** * 查询参数 */ search?: string | any, /** * 盐值 */ saltValue?: string, } /** * 灵犀安全对象,包含请求加签加密程序以及安全工具类方法 * @see {@link https://www.npmjs.com/package/@lingxiteam/security?activeTab=readme|api使用文档} */ export namespace security { /** * 请求安全处理程序 * @example * // 启动, 将自动处理所有请求,为请求进行加签或者加密 * security.httpEncryption.start({ mode: '1.0' }); * * // 停止,停止后后续发起的请求不再进行加签或者加密处理 * security.httpEncryption.stop(); */ export const httpEncryption: { /** * 启动请求自动加密加签处理 * @param startConfig * @returns 返回true表示开启成功; 返回false表示开启失败(配置存在问题); 返回null表示程序已启动,此次启动配置不生效,需停止后才能再启动 * @example * // 指定开启请求安全模式 * // 1.0-参数签名 * // 1.1-时间限制性签名 * // 1.2-唯一限制性签名 * // 2.0-RSA参数加密 * // 3.0-AES参数加密 * security.httpEncryption.start({ mode: '1.0' }) * * // 指定自定处理浏览器请求程序, 如只处理XMLHttpRequest * security.httpEncryption.start({ mode: '1.0', requester: ['xhr'] }); * * // 使用默认处理, 将自动从全局变量上获取模式(window.lxSecurityMode),缺省值为1.1 * security.httpEncryption.start(); */ start: (startConfig?: configType) => boolean | null; /** * 停止请求自动加密加签处理 * @returns */ stop: () => void; /** * 加密加签请求(fetch API) * 在不使用全局自动加密加签处理程序时(security.httpEncryption.start()),使用此api单独发起加密加签请求 */ fetch: typeof fetch; /** * 加密加签请求(XMLHttpRequest API) * 在不使用全局自动加密加签处理程序时(security.httpEncryption.start()),使用此api单独发起加密加签请求 */ XMLHttpRequest: new () => XMLHttpRequest; /** * 加密加签请求(微信小程序请求API) * 在不使用全局自动加密加签处理程序时(security.httpEncryption.start()),使用此api单独发起加密加签请求 */ wxRequest: (option: WechatMiniprogram.RequestOption) => WechatMiniprogram.RequestTask }; /** * 生成签名 * @param url 请求url地址 * @param options 请求配置信息(可选), method: 请求方法, headers: 头部参数, body: 请求内容数据, search: 查询参数, saltValue: 盐值 * @param version 签名版本(可选), 1.0, 1.1, 1.2, 缺省时默认取全局配置mode的值 * @returns 签名结果值 * @example * const xsign = security.createHttpSignStr('/api/user/10001', * { method: 'GET', headers: { 'app-id': '123' }, search: 'attrs=name,age' })); */ export function createHttpSignStr(url: string, options: signHttpOptionsType, version?: any) : string; /** * 将签名添加在url上 * @param url 待处理的url * @param options 请求配置信息(可选), method: 请求方法, headers: 头部参数, body: 请求内容数据, search: 查询参数, saltValue: 盐值 * @param version 签名版本(可选), 1.0, 1.1, 1.2, 缺省时默认取全局配置mode的值 * @returns 处理后的url地址,在url地址上添加X-SIGN参数和XA-TYPE参数 * @example * // 资源请求无法在header上带上签名,将签名放在url地址上 * const url = security.createHttpSignWithUrl('/file?id=123', null, '1.0') * // url -> /file?id=123&X-SIGN=xxxxxxx&XA-TYPE=1.0 * */ export function createHttpSignWithUrl(url: string, options?: signHttpOptionsType | null, version?: string) : string; /** * 将url参数进行加密处理 * @param url 待处理的url参数 * @param version 加密版本(可选), 2.0,3.0, 缺省时默认取全局配置mode的值 * @returns 处理后的url地址,url参数加密并附加XA-TYPE参数 * @example * const url = security.createEncryptedWithUrl('/file?id=123', '3.0') * // url -> /file?id=%2FSYiu5xcnYcmwlTvvBXOZk2I&XA-TYPE=3.0 * */ export function createEncryptedWithUrl(url: string, version?: '2.0' | '3.0') : string; /** * 根据配置的mode自动对url进行加密或加签处理 * @param url 待处理的url * @param options 配置项 * @returns 加签或加密后的url地址 * @example * // 简单使用 * security.autoSecurityWithUrl('/file?id=123'); * * // 避免1.1模式资源请求无法进行缓存,当是1.1模式时资源地址使用1.0模式 * security.autoSecurityWithUrl('/file?id=123', { modeRule: (currentMode) => currentMode === '1.1' ? '1.0' : currentMode }); */ export function autoSecurityWithUrl(url: string, options?: { modeRule?: (currentMode: modeType) => modeType, saltValue?: signHttpOptionsType['saltValue'] }); /** * 默认RSA加密处理函数 * @param content 待加密内容 * @param publicKey 密钥(可选) * @param handle 自定义加密函数(可选) * @returns 加密后内容 * @example * // 简单使用 * security.RSAEncrypt('test'); * * // 自定义秘钥 * security.RSAEncrypt('test', 'YourKey'); * * // 自定义加密处理(在形参上可取到JSEncrypt) * security.RSAEncrypt('test', null, (content, key, JSEncrypt) => { * const encrypt = new JSEncrypt(); * encrypt.setPublicKey(key); * return encrypt.encrypt(content); * }) */ export function RSAEncrypt(content: string, publicKey?: string | null, handle?: fnRSAEncryptType) : string; /** * 默认RSA解密处理函数 * @param content 待加密内容 * @param privKey 密钥(可选) * @param handle 自定义加密函数(可选) * @returns 解密后内容 * @example * // 简单使用 * security.RSADecrypt('securityContent'); * * // 自定义秘钥 * security.RSAEncrypt('securityContent', 'YourKey'); * * // 自定义加密处理(在形参上可取到JSEncrypt) * security.RSADecrypt('', null, (content, key, JSEncrypt) => { * const decrypt = new JSEncrypt(); * decrypt.setPrivateKey(key); * return decrypt.decrypt(content); * }) */ export function RSADecrypt(content: string, privKey?: string | null, handle?: fnRSADecryptType) : string; /** * 默认AES加密处理函数 * @param content 待加密内容 * @param aesKey 密钥(可选) * @param handle 自定义加密函数(可选) * @returns 加密后内容 * @example * // 简单使用 * security.AESEncrypt('test'); * * // 自定义秘钥 * security.AESEncrypt('test', 'YourKey'); * * // 自定义加密处理(在形参上可取到cryptoJS) * security.AESEncrypt('test', null, (content, key, cryptoJS) => { * const cipher = cryptoJS.createCipheriv('aes-256-cbc', key, Buffer.from('16bytesrandomiv')); * let encrypted = cipher.update(content); * encrypted = Buffer.concat([encrypted, cipher.final()]); * return encrypted.toString('hex'); * }) */ export function AESEncrypt(content: string, aesKey?: string | null, handle?: fnAESEncryptType) : string; /** * 默认AES解密处理函数 * @param content 待解密内容 * @param aesKey 密钥 * @param handle 自定义解密函数 * @returns 解密后内容 * @example * // AESDecrypt * security.AESEncrypt('securityContent'); * * // 自定义秘钥 * security.AESDecrypt('securityContent', 'YourKey'); * * // 自定义加密处理(在形参上可取到cryptoJS) * security.AESDecrypt('test', null, (content, key, cryptoJS) => { * const decipher = cryptoJS.createDecipheriv('aes-256-cbc', key, Buffer.from('16bytesrandomiv')); * let decrypted = decipher.update(Buffer.from(content, 'hex')); * decrypted = Buffer.concat([decrypted, decipher.final()]); * return decrypted.toString(); * }) */ export function AESDecrypt(content: string, aesKey?: string | null, handle?: fnAESDecryptType) : string; /** * 默认GCM加密处理函数 * @param content 待加密内容 * @param aesKey 密钥(可选) * @param handle 自定义加密函数(可选) * @returns 加密后内容 * @example * // 简单使用 * security.GCMEncrypt('test'); * * // 自定义秘钥 * security.GCMEncrypt('test', 'YourKey'); * * // 自定义加密处理(在形参上可取到cryptoJS) * security.GCMEncrypt('test', null, (content, key, cryptoJS) => { * const iv = cryptoJS.lib.WordArray.random(12); * const encrypted = cryptoJS.AES.encrypt(content, key, { * mode: cryptoJS.mode.GCM, * iv: iv, * padding: cryptoJS.pad.NoPadding, * }); * const result = iv.concat(encrypted.ciphertext); * return cryptoJS.enc.Base64.stringify(result); * }) */ export function GCMEncrypt(content: string, aesKey?: string | null, handle?: fnGCMEncryptType) : string; /** * 默认GCM解密处理函数 * @param content 待解密内容 * @param aesKey 密钥 * @param handle 自定义解密函数 * @returns 解密后内容 * @example * // 简单使用 * security.GCMDecrypt('securityContent'); * * // 自定义秘钥 * security.GCMDecrypt('securityContent', 'YourKey'); * * // 自定义解密处理(在形参上可取到cryptoJS) * security.GCMDecrypt('test', null, (content, key, cryptoJS) => { * const encryptedData = cryptoJS.enc.Base64.parse(content); * const iv = cryptoJS.lib.WordArray.create(encryptedData.words.slice(0, 3)); * const ciphertext = cryptoJS.lib.WordArray.create(encryptedData.words.slice(3)); * const decrypted = cryptoJS.AES.decrypt( * { ciphertext: ciphertext }, * key, * { * mode: cryptoJS.mode.GCM, * iv: iv, * padding: cryptoJS.pad.NoPadding, * } * ); * return decrypted.toString(cryptoJS.enc.Utf8); * }) */ export function GCMDecrypt(content: string, aesKey?: string | null, handle?: fnGCMDecryptType) : string; /** * 浏览器环境的异步 GCM 加密函数 * @param content 待加密内容 * @param aesKey 密钥(可选,不传则使用默认密钥) * @returns Promise 加密后内容 */ export function browserGCMEncrypt(content: string, aesKey?: string): Promise; /** * 浏览器环境的异步 GCM 解密函数 * @param content 待解密内容 * @param aesKey 密钥(可选,不传则使用默认密钥) * @returns Promise 解密后内容 */ export function browserGCMDecrypt(content: string, aesKey?: string): Promise; /** * Node.js 环境的同步 GCM 加密函数 * @param content 待加密内容 * @param aesKey 密钥 * @returns string 加密后内容 */ export function GCMEncryptSync(content: string, aesKey?: string): string; /** * Node.js 环境的同步 GCM 解密函数 * @param content 待解密内容 * @param aesKey 密钥 * @returns string 解密后内容 */ export function GCMDecryptSync(content: string, aesKey?: string): string; /** * 配置设置 * @param config 配置项 * @example * security.httpEncryption.start({ mode: '1.0' }); * // 等效于 * security.setConfig({ mode: '1.0' }); * security.httpEncryption.start(); * * setConfig的使用场景一般为工程内不使用security.httpEncryption.start方法,或后续进行调整配置项时使用。 */ export function setConfig(config: configType) : void; /** * 获取配置信息 * @param key 配置项 * @returns 配置值 * @example * // 获取当前mode值 * security.getConfig('mode'); * * // 获取当前aes秘钥值 * security.getConfig('aes').key; */ export function getConfig(key: T) : configType[T]; /** * 初始化配置项 * 将从全局上获取配置数据与默认配置项整合进行初始化设置 * 程序解析运行时将自动执行初始化,后续再次执行会重新从全局上获取配置数据进行设置 * @example * security.initConfig(); */ export function initConfig() : void; /** * 检查配置是否已初始化 * @returns 是否已初始化 * @example * if (security.isConfigInitialized()) { * console.log('配置已初始化'); * } */ export function isConfigInitialized() : boolean; /** * 检查配置是否正在初始化 * @returns 是否正在初始化 * @example * if (security.isConfigInitializing()) { * console.log('配置正在初始化中'); * } */ export function isConfigInitializing() : boolean; /** * 获取配置初始化状态 * @returns 配置状态信息 * @example * const status = security.getConfigStatus(); * console.log('配置状态:', status); */ export function getConfigStatus() : { isInitialized: boolean; isInitializing: boolean; hasConfig: boolean; configKeys: string[]; }; /** * 强制重新初始化配置 * 谨慎使用,仅在需要重置配置时调用 * @example * security.reinitConfig(); */ export function reinitConfig() : void; /** * 预置加密函数,可以使用该函数加密结果作为key * @param str 待加密字符 */ export function lxEncrypt(str: string) : string; export const html: { safeHTML: (content: string, options?: { blackList?: string[] }) => string; }; /** * 将url参数解密 * @param search url参数, 如: a=XAZYt1dl43v0gYUlNM6wEg%3D%3D&b=rbsCqzqEZvsUn41oxNsJ%2FQ%3D%3D * @param mode 加密模式 * @returns string 解密后数据 */ export function decryptedStrForSearchParams(search: string, mode: '2.0' | '3.0'): string; /** * 检查安全模式是否为加密 * @param mode 模式值 * @returns boolean */ export function checkIsEncryption(mode: string): boolean; /** * 统一解密函数 * @param str 待解密内容 * @param type 加密类型 * @param config 配置项(自定义秘钥和解密方法) * @returns string 解密后的内容 */ export function decryptedStr(str: string, type: string): string; /** * 统一加密函数 * @param str 待加密内容 * @param type 加密类型 * @returns string 加密后内容 */ export function encryptedStr(str: string, type: string): string; /** * 检查安全模式是否为加签 * @param mode 模式值 * @returns boolean */ export function checkIsSignMode(mode: string): boolean; /** * 生成待签名的内容 * @param url * @param options * @param props * @param version */ export function createHttpSignContent( url: string, options: signHttpOptionsType, props: { nowTime: number; uuid: string; }, version?: any ): [string, string]; export function SHA256(content: string): string; } /** * 预置默认aes秘钥 */ export const aesKey: string; /** * 预置默认签名秘钥 */ export const signKey: string; /** * 预置默认rsa公钥 */ export const rsaPublicKey: string; /** * 预置默认rsa私钥 */ export const rsaPrivKey: string; export default security;