上海做网站比较好的公司,建设部资质网站查询,西安霸屏推广,网站越来越难做前言#xff1a;数据安全 数据的加密解密操作在 日常网络交互中经常会用到#xff0c;现在密码的安全主要在于 秘钥的安全#xff0c;如论 DES 3DES AES 还是 RSA, 秘钥的算法#xff08;计算秘钥不固定#xff09; 和 保存#xff0c;都决定了你的数据安全#xff1b;… 前言数据安全 数据的加密解密操作在 日常网络交互中经常会用到现在密码的安全主要在于 秘钥的安全如论 DES 3DES AES 还是 RSA, 秘钥的算法计算秘钥不固定 和 保存都决定了你的数据安全但是常见的逆向操作 比如 hook 加密算法 都很容易拿到 秘钥 这个时候我们可以 回溯到 之前的 古典密码学依赖算法本身基本思路 置换 移位 编码 等等手段 来配合 加密算法一起使用提高我们应用的安全 密码学概论_在传统的密码学中,加解密基础操作包括移位置换替换编码-CSDN博客文章浏览阅读201次。密码学基础_在传统的密码学中,加解密基础操作包括移位置换替换编码https://blog.csdn.net/nicepainkiller/article/details/132978492?ops_request_misc%257B%2522request%255Fid%2522%253A%2522170902384916777224453245%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257Drequest_id170902384916777224453245biz_id0utm_mediumdistribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-132978492-null-null.nonecaseutm_term%E5%AF%86%E7%A0%81spm1018.2226.3001.4450 android frida 逆向 自吐加密算法_frida 自吐算法 教程-CSDN博客文章浏览阅读1.8k次。frida hook android Android 逆向神器_frida 自吐算法 教程https://blog.csdn.net/nicepainkiller/article/details/132554698?ops_request_misc%257B%2522request%255Fid%2522%253A%2522170902437216800182198144%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257Drequest_id170902437216800182198144biz_id0utm_mediumdistribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-132554698-null-null.nonecaseutm_termhookspm1018.2226.3001.4450 flutter 数据加密 如果是 android 原生应用可以 hook 系统加密代码来获取加密秘钥而在 flutter 中dart 是被直接编译为 .so 文件也就是汇编对于低级汇编语言 可读性大大降低。当然也是可以下断点动态调试的但是相对于难度 大大增加我们可以结合 古典密码学 主要特点 数据安全基于算法的保密算法不公开 设计繁琐的算法过程增加汇编可读性难度 有个业务需求是相当于是一个签到功能每天可以领取这里防止脚本调用使用两层 基于算法加密 和 AES加密 相结合的方式当然还用到了第三方的的安全软件 以下是我上个版本加密算法设计整体思路就是 按照规则 移动字符 替换字符阶段一主要是 按规则打乱字符密文位置阶段二主要是 指定位置密文插入无关字符 match_request_data.dart import dart:convert;
import package:crypto/crypto.dart;
import package:encrypt/encrypt.dart as encrypt;///匹配接口加密工具类
///整体加密思路按照规则 移动字符 替换字符
///阶段一主要是 按规则打乱字符位置
///阶段二主要是 指定位置插入无关字符
class MatchRequestData {final String gameId;final String chatSign;final String nickName;late Listint _gameIdSort;MatchRequestData({required this.gameId, required this.chatSign, required this.nickName});String generateCode(String datum) {String idStr ${int.parse(gameId)};Listint searchKeywords Listint.generate(idStr.length, (index) int.parse(idStr[index]));searchKeywords.sort();_gameIdSort searchKeywords;String base64 _encodeBase64(datum);String base64Step0 base64.substring(0, _gameIdSort[_gameIdSort.length - 1]) _stepOne((base64.substring(_gameIdSort[_gameIdSort.length - 1],base64.length -_gameIdSort[3] -_gameIdSort[_gameIdSort.length - 1]))) base64.substring(base64.length -_gameIdSort[3] -_gameIdSort[_gameIdSort.length - 1]);String _strHex _strToHex(base64Step0);final key encrypt.Key.fromUtf8(_generateMd5(chatSign nickName));final iv encrypt.IV.fromUtf8(_ivStepOne().substring(4, 20).toUpperCase());final encrypter encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));final encrypted encrypter.encrypt(_strHex, iv: iv);final encryptCode _stepTwo(encrypted.base64);idStr _strHex base64 base64Step0 ;return encryptCode;}String _stepOne(String str) {String res ;str _inverse(str);int lastPosition _gameIdSort[_gameIdSort.length - 1];int count 0;if (lastPosition % 2 0) {count _gameIdSort[_gameIdSort.length - 2];} else {count _gameIdSort[_gameIdSort.length - 3];}if (count 0) {count lastPosition;}int step str.length ~/ count;ListString base64Parts [];for (int i 0; i count; i) {if (i % 2 1) {base64Parts.add(_inverse(str.substring(step * i, step * (i 1))));} else {base64Parts.add(str.substring(step * i, step * (i 1)));}}if (step * count str.length) {if (lastPosition % 2 0) {base64Parts.insert(0, str.substring(step * count));} else {base64Parts.insert(base64Parts.length, str.substring(step * count));}}if (lastPosition % 2 1) {for (int i 0; i base64Parts.length; i) {res res base64Parts[i];}} else {for (int i base64Parts.length - 1; i 0; i--) {res res base64Parts[i];}}str ;lastPosition count step -1;return res;}String _stepTwo(String data) {String res ;String _strHex _strToHex(data);String _code _inverse(_strHex);final key encrypt.Key.fromUtf8(_generateMd5(gameId chatSign));final iv encrypt.IV.fromUtf8(_ivStepTwo().substring(14, 30));final encrypter encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.cbc));final encrypted encrypter.encrypt(_code, iv: iv);res encrypted.base64;int maxLength res.length;int indexSub 0;int insertPos 0;String insertStr ;for (int i 1; i _gameIdSort.length; i) {indexSub _gameIdSort[i] 1;insertPos _magic(indexSub i) i * 11 i - 1;// insertStr chatSign.substring(1,indexSub);insertStr chatSign[indexSub];//前面插入if (insertPos res.length) {insertPos maxLength;}res ${res.substring(0, insertPos)}$insertStr${res.substring(insertPos)};}_strHex _code ;return res;}String _stepThree(String str) {return str;}String _inverse(String tag) {String res ;ListString searchKeywords ListString.generate(tag.length, (index) tag[index]);IterableString array searchKeywords.reversed;for (var e in array) {res $res$e;}return res;}String _ivStepOne() {String res ;String map _generateMd5(chatSign) _generateMd5(nickName);int index _gameIdSort[_gameIdSort.length - 2];while (res.length 50) {res map[index];index;}index 0;return res;}String _ivStepTwo() {String res ;String map _generateMd5(_inverse(chatSign)) _generateMd5(chatSign);int index _gameIdSort[_gameIdSort.length - 1];while (res.length 50) {res map[index];index;}index 0;return _inverse(res);}/// 字符串转 十六进制String _strToHex(String str) {Listint charCodes str.runes.toList();return charCodes.map((code) code.toRadixString(16)).join();}/// 字符串转 base64String _encodeBase64(String data) {return base64Encode(utf8.encode(data));}/// base64转 普通字符String _decodeBase64(String data) {return String.fromCharCodes(base64Decode(data));}String _generateMd5(String str) {return md5.convert(utf8.encode(str)).toString();}int _magic(int num) {if (num 3) {return 1;} else {return _magic(num - 1) _magic(num - 2);}}
}调用的地方 MatchRequestData data MatchRequestData (gameId: userArray[i][gameID],chatSign: userArray[i][chatSign],nickName: userArray[i][nickName],
);//需要传递给后台的 内容
Map datum {inTrust: TRUE,time: DateTime.now().millisecondsSinceEpoch,GameID: userArray[i][gameID],nickName: userArray[i][nickName],MachineCode:md5.convert(utf8.encode(userArray[i][gameID])).toString(),sign: md5.convert(utf8.encode(userArray[i][gameID] userArray[i][chatSign])).toString(),
};String res data.generateCode(jsonEncode(datum)); 服务端的数据解密 服务端为 .net 框架 对应于加密算法写的解密算法 using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;namespace ToMatch
{public class MatchEncrypt{private string gameID;private string chatSign;private string nickName;private Listint idSort;/// summary/// 匹配构造函数/// /summary/// param namegameIdGameID/param/// param namechatSign签名/param/// param namenickName昵称/parampublic MatchEncrypt(string gameId, string chatSign, string nickName) {this.gameID gameId;this.chatSign chatSign;this.nickName nickName;this.idSort new Listint();string idStr int.Parse(this.gameID).ToString();for (int i 0; i idStr.Length; i){this.idSort.Add((int)Char.GetNumericValue(idStr[i]));}this.idSort.Sort();}private String IvStepOne {get {String res ;String map Md5Hash(chatSign) Md5Hash(nickName);int index idSort[idSort.Count - 2];while (res.Length 50){res map[index];index;}return res;}}private String IvStepTwo{get{String res ;String map Md5Hash(AESHelper.Inverse(chatSign),false) Md5Hash(chatSign,false);int index idSort[idSort.Count - 1];while (res.Length 50){res map[index];index;}return AESHelper.Inverse(res);}}/// summary/// 解密客户端内容/// /summary/// param namecode密文/param/// returns/returnspublic string Resolver(string code) {//第一阶段解密内容string resStepOne StepOne(code);if (resStepOne.Length 0){//Console.WriteLine(第一解密 result: resStepOne);//第二阶段解密string resSteptwo Steptwo(resStepOne);//Console.WriteLine(第二解密 result: resSteptwo);//Console.WriteLine(AESHelper.FromBase64(resSteptwo));if (resSteptwo.Length 0){return AESHelper.FromBase64(resSteptwo);}else {return 解密失败——请记录日志.Step-2;} }else {return 解密失败——请记录日志.Step-1;} }private string StepOne(string code){// 1.先移除插入的字符// 2.再进行解密操作int maxlength code.Length - idSort.Count - 1;int indexSub 0;int insertPos 0;for (int i 1; i idSort.Count; i){indexSub idSort[i] 1;insertPos magic(indexSub i) i * 11; //前面插入//Console.WriteLine(前面 索引: i);//Console.WriteLine(前面插入位置: insertPos);//Console.WriteLine(前面插入字符: insertStr );if (insertPos code.Length) {//Console.WriteLine(修正Length: code.Length);Console.WriteLine(修正insertPos: insertPos);//Console.WriteLine(----code.Length: (code.Length -maxlength ));//Console.WriteLine(----code.Length: ( idSort.Count-1 - i));//Console.WriteLine(----code.Length: ((code.Length - maxlength - (idSort.Count - 1 - i))1));insertPos maxlength -4;insertPos maxlength - ((code.Length - maxlength - (idSort.Count - 1 - i)) 1);//Console.WriteLine(*******code.Length: ((code.Length - maxlength - (idSort.Count - 1 - i)) 1));//Console.WriteLine(*******code.Length: (code.Length - maxlength - (idSort.Count - i)) );//Console.WriteLine(*******code.Length: (code.Length - maxlength - idSort.Count - i ));//Console.WriteLine(code.Length: code.Length);//Console.WriteLine(maxlength: maxlength);//Console.WriteLine(idSort.Count: idSort.Count);//Console.WriteLine(idSort.Count - i: (idSort.Count - i));//Console.WriteLine(修正插入位置i: i);//Console.WriteLine(修正插入位置: insertPos);insertPos maxlength - ((code.Length - maxlength - (idSort.Count - 1 - i)) 1);} code code.Substring(0, insertPos) code.Substring(insertPos 1);}//Console.WriteLine(整理后的: code);//Console.WriteLine(整理后的Length: code.Length);string key Md5Hash(this.gameID this.chatSign, false);string iv IvStepTwo.Substring(14, 16);//第一次解密是 16进制字符串string result AESHelper.Decrypt(code, key, iv);return AESHelper.HexStringToString(AESHelper.Inverse(result), Encoding.UTF8);}private string Steptwo(string code) {string key Md5Hash(this.chatSign this.nickName, false);string iv IvStepOne.Substring(4, 16);string base64 AESHelper.HexStringToString(AESHelper.Decrypt(code, key, iv), Encoding.UTF8);string source base64.Substring(0, idSort[idSort.Count - 1]) generateMid(base64.Substring(idSort[idSort.Count - 1], base64.Length - idSort[3] - idSort[idSort.Count - 1] * 2)) base64.Substring(base64.Length - idSort[3] - idSort[idSort.Count - 1]);//第二次解密是 base64return source ;}private string generateMid(string str) {string res ;ListString base64Parts new Liststring();int lastPosition this.idSort[this.idSort.Count - 1];string subBefore ;int count 0;if (lastPosition % 2 0){count idSort[idSort.Count - 2];}else{count idSort[idSort.Count - 3];}if (count 0) {count lastPosition;}int step str.Length / count;int subLength str.Length - step * count;if (lastPosition % 2 0){for (int i 0; i count; i){if (i % 2 1){base64Parts.Add(AESHelper.Inverse(str.Substring(step * (count - i - 1), step)));}else{//base64Parts.Add(v.Substring(step * i, step));//Console.WriteLine(i 不需要翻转原始 str.Substring(step * (count - i - 1), step));base64Parts.Add(str.Substring(step * (count - i - 1), step));}}for (int i 0; i base64Parts.Count; i){//Console.WriteLine(偶数项目 i base64Parts[i]);res res base64Parts[i];}subBefore str.Substring(step * count);res subBefore;}else{for (int i 0; i count; i){if (i % 2 1){base64Parts.Add(AESHelper.Inverse(str.Substring(step * i, step))); }else{base64Parts.Add(str.Substring(step * i, step));}}subBefore str.Substring(step * count);base64Parts.Add(subBefore);for (int i 0; i base64Parts.Count; i){//Console.WriteLine(奇数项目 i base64Parts[i]);res res base64Parts[i];}}return AESHelper.Inverse(res);}private static int magic(int num){if (num 3){return 1;}else{return magic(num - 1) magic(num - 2);}}private string Md5Hash(string sourceText, bool toUpper true){StringBuilder result new StringBuilder();using (MD5 md5 new MD5CryptoServiceProvider()){byte[] data md5.ComputeHash(Encoding.UTF8.GetBytes(sourceText));if (toUpper)for (int i 0; i data.Length; i)result.Append(data[i].ToString(X2));elsefor (int i 0; i data.Length; i)result.Append(data[i].ToString(x2));}return result.ToString();}}
}总结 数据安全不是绝对的只能说我们多设置些障碍对于逆向的难度对增大你挖的坑多远。逆向时候就越困难当然也可以借助一些第三方安全软件来增加我们数据的安全性。在数据安全的道路上 始终是此消彼长的状态