FlyUp/assets/Script/crypto/HttpUtil.ts
2024-06-21 18:41:20 +08:00

257 lines
7.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// import CryptoJS from "crypto-js";
import GameData from '../GameData';
import CryptoJS = require('./crypto-js.min.js'); //引用AES源码js
// import axios from 'axios'
const {ccclass, property} = cc._decorator;
@ccclass
export default class HttpUtil extends cc.Component {
//排行榜type2为获取type1为上传
static async rankData(type,callback,data): Promise<any> {
data.gameId = GameData._instance.GM_INFO.gameId;
data.userId = GameData._instance.GM_INFO.userId;
const time = Math.floor((new Date().getTime()) / 1000)
const url = apiSign(`/api/get/rank/data?gameId=${config.gameId}&dataType=${type}&time=${time}`, data)
this.httpPost(url,data,callback);
}
static async uploadUserLogData(data,callback): Promise<any> {
data.gameId = GameData._instance.GM_INFO.gameId;
data.userId = GameData._instance.GM_INFO.userId;
const url = '/log/collect/data';
this.httpPost(url,data,callback);
}
//暂时用不到
static async getUserRecord(data,callback): Promise<any> {
data.gameId = GameData._instance.GM_INFO.gameId;
data.userId = GameData._instance.GM_INFO.userId;
const time = Math.floor((new Date().getTime()) / 1000)
const url = apiSign(`/api/get/user/data?gameId=${config.gameId}&time=${time}`, data)
this.httpPost(url,data,callback);
}
static httpPost(url,data,callBack){
data.gameId = GameData._instance.GM_INFO.gameId;
data.userId = GameData._instance.GM_INFO.userId;
var urlData = "http://api.sparkus.cn" + url;
// console.log("params:",JSON.stringify(data));
let xhr = new XMLHttpRequest();
xhr.open('POST', urlData);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = xhr.responseText;
if(!data){
// console.log("初始化失败");
return;
}
var json = JSON.parse(data);
// console.log('http success:' + json);
callBack(json);
}
else{
// var json = JSON.parse(data);
// console.log('http fail:' + url);
callBack(json);
}
};
xhr.send(JSON.stringify(data));
}
static httpGet(url,callBack){
var urlData = "http://api.sparkus.cn" + url;
console.log(urlData);
let xhr = new XMLHttpRequest();
xhr.open('GET', urlData);
xhr.setRequestHeader('Content-Type', 'text/plain');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
var data = xhr.responseText;
if(data){
var json = JSON.parse(data);
console.info('http success:' + json);
callBack(json);
}
else callBack(data);
}
else{
console.info('http fail:' + url);
callBack(null);
}
};
xhr.send();
}
}
function responseHandler(response: { data: any }) {
return response.data
}
// 响应拦截器
// Rq.interceptors.response.use(responseHandler)
const config = {
gameId: "100001",
secretKey: "zDLsruVI",
EK:"hui231%1"
};
interface CrypotoType {
encryptByDES: any
decryptByDES: any
hmacSha256: any
}
class Crypoto implements CrypotoType {
// 加密的向明值,自己根据项目实际情况定,需要跟后端开发保持一致
private keyHex = this.getHetKey()
private getHetKey() {
return CryptoJS.enc.Utf8.parse(config.EK);
}
/** DES加密 */
encryptByDES(message: string, secret?: string) {
if(!message) {
return message
}
const key = secret? CryptoJS.enc.Utf8.parse(secret): this.keyHex
const encrypted = CryptoJS.DES.encrypt(message, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
return encrypted.toString()
}
/** DES解密 */
decryptByDES(message: string, secret?: string) {
const key = secret? CryptoJS.enc.Utf8.parse(secret): this.keyHex
const decrypted = CryptoJS.DES.decrypt({
ciphertext: CryptoJS.enc.Base64.parse(message)
}, key, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
})
return decrypted.toString(CryptoJS.enc.Utf8)
}
/** hmacSHA256加密 */
hmacSha256(message: string, secret?: string) {
const keyHex = secret? CryptoJS.enc.Utf8.parse(secret): this.keyHex
const hash = CryptoJS.HmacSHA256(message, keyHex);
return hash.toString()
}
/** hmacSHA256验证 */
verifyHmacSha256(message: string, signature: string) {
const hash = CryptoJS.HmacSHA256(message, this.keyHex);
return hash.toString() === signature
}
/** CBC加密 */
encryptCBC(word: string) {
if (!word) {
return word;
}
const srcs = CryptoJS.enc.Utf8.parse(word);
const encrypted = CryptoJS.AES.encrypt(srcs, this.keyHex, {
iv: this.keyHex,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
});
return encrypted.toString();
}
/** CBC解密 */
decryptCBC(word: string) {
if (!word) {
return word;
}
const encryptedHexStr = CryptoJS.enc.Hex.parse(word);
const srcs = CryptoJS.enc.Base64.stringify(encryptedHexStr);
const decrypt = CryptoJS.AES.decrypt(srcs, this.keyHex, {
iv: this.keyHex,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.ZeroPadding
});
const decryptedStr = decrypt.toString(CryptoJS.enc.Utf8);
return decryptedStr.toString();
}
}
const fxCry = new Crypoto();
function isEmpty(data) {
return data === "" || data === null || data === undefined || data.length === 0 || JSON.stringify(data) == "{}"
}
function getQueryString(obj) {
// 首先对对象的键进行排序并过滤空值
const sortedKeys = Object.keys(obj).sort();
const sortedObj = {};
for (let i = 0; i < sortedKeys.length; i++) {
if (isEmpty(obj[sortedKeys[i]])) {
continue;
}
sortedObj[sortedKeys[i]] = obj[sortedKeys[i]];
}
// 然后将排序后的对象转换为查询字符串
const params = [];
for (const key in sortedObj) {
params.push(`${encodeURIComponent(key)}=${encodeURIComponent(sortedObj[key])}`);
}
return params.join('&');
}
/**
* 组装签名字符串
* @param string url: 请求地址
* @param string postStr: post参数的a=1&b=2
* @returns
*/
function genSignStr(url: string, postStr: string): string {
let lessUrl = url.replace('?', '')
lessUrl = lessUrl + "&" + postStr
return encodeURIComponent(fxCry.hmacSha256(lessUrl))
}
// 对参数进行统一urlencode
function urlencode(url: string): string {
const [baseUrl, queryString] = url.split("?", 2);
const params = new URLSearchParams(queryString);
return `${baseUrl}?${params.toString()}`;
}
/**
*
* @param url {string} 接口地址
* @param params {object} 需要加密的参数对象
*/
function apiSign(url: string, params = {}) {
let convertUrl = url.trim()
if (convertUrl.indexOf('?') === -1) {
convertUrl += '?'
}
// 传入参数转换拼接字符串
let postStr = getQueryString(params)
const signedStr = genSignStr(convertUrl, postStr)
const encryptStr = `sign=${signedStr}`
let encryptSignStr = fxCry.encryptByDES(encryptStr, config.secretKey)
encryptSignStr = encodeURIComponent(encryptSignStr)
return `${urlencode(convertUrl)}&_p=${encryptSignStr}`
}