本加密算法是在【前端逆向】社会主义核心价值观加密方法解析+python版复现
这篇文章介绍了一种名为 社会主义核心价值观加密方法
旨在通过编程学习党的十八大提出的社会主义核心价值观。
而本文提到的加密算法灵感来自于此,但加密原理与此加密方法完全不同
算法介绍
中国红色加密是一个新型加密算法,之所以取这个名字,那是因为加密后的密文以中文汉字输出,且内容积极,阳光,向上。
例如:
原文为 "06"
则密文为 "中国"
注:支持中文汉字,英文,数字,以及特殊符号加密
算法原理
1.将原文进行URL编码
目的:将中文汉字转为使用字母+数字替代
2.转为十六进制
将上一步得到的字符串转为16进制文本(小写)
目的:将整个字符串变为只由6个字母[a-f]
和9个数字[0-9]
组成
3.转为char[]数组
将上一步得到的字符串转为由一个一个字符组成的char[]数组
例如:"123" 变成 {"1","2","3"}
目的:为下一步的索引提供准备
4.遍历char[]数组
遍历上一步得到的char[]数组,将有以下两种情况:
①遍历得到的元素为[0-9]的数字
将此数字作为索引,从 常量文本数组一
中获取元素
常量文本数组一 = {"中","华","人","民","共","和","国","万","岁","政"}
假如数字为1,则得到"华"
②遍历得到的元素为[a-f]的字母
先获取这个字母在26个英文字母表中的位置
如a为1,b为2
将获取到的数字减1作为索引。从 常量文本数组二
中获取元素
常量文本数组二 = {"富","强","文","明","平","等"}
假如字母为b,则获取到"强"
5.拼接即可
将上一步遍历char[]数组从常量文本数组中获取的元素拼接起来,最后输出即为密文
解密过程相反即可
算法代码
package xyz.wystudio.tool;
import java.util.regex.Matcher;
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.io.UnsupportedEncodingException;
import java.util.regex.Pattern;
public class EncryptUtil {
private static final String[] LIST_CODE_EN = { "富", "强", "文", "明", "平", "等" };
private static final String[] LIST_CODE_NUM = { "中", "华", "人", "民", "共", "和", "国", "万", "岁", "红" };
private static final String[] LIST_HEX = { "a", "b", "c", "d", "e", "f" };
public static String encode(String str) {
str = URLencode(str);
String hexString = StringtoHex(str);
return doInString(hexString);
}
public static String decode(String str) {
try {
StringBuffer sb = new StringBuffer();
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (findInNum(chars[i]) != -1) {
sb.append(findInNum(chars[i]));
} else {
if (findInEn(chars[i]) != -1) {
sb.append(LIST_HEX[findInEn(chars[i])]);
}
}
}
if(sb.toString().equals("") || sb.toString() == null){
return "解密失败非密文";
}
return URLdecode(HextoString(sb.toString()));
} catch (Exception e) {
return "解密失败非密文";
}
}
private static String StringtoHex(String str) {
StringBuffer sb = new StringBuffer();
//将字符串转换为字符数组
char ch[] = str.toCharArray();
for (int i = 0; i < ch.length; i++) {
String hexString = Integer.toHexString(ch[i]);
sb.append(hexString);
}
String result = sb.toString();
return result;
}
private static String HextoString(String str) {
String result = new String();
char[] charArray = str.toCharArray();
for (int i = 0; i < charArray.length; i = i + 2) {
String st = "" + charArray[i] + "" + charArray[i + 1];
char ch = (char) Integer.parseInt(st, 16);
result = result + ch;
}
return result;
}
private static String doInString(String str) {
StringBuffer sb = new StringBuffer();
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
if (isNum(chars[i])) {
sb.append(LIST_CODE_NUM[Integer.parseInt(chars[i] + "")]);
} else {
sb.append(LIST_CODE_EN[EntoInt(chars[i]) - 1]);
}
}
return sb.toString();
}
private static boolean isNum(char str) {
Pattern pattern = Pattern.compile("[0-9]*");
Matcher isNum = pattern.matcher(str + "");
if (!isNum.matches()) {
return false;
}
return true;
}
private static int EntoInt(char ch1) {
String str = ch1 + "";
char ch = str.charAt(0);
int num = 0;
if (ch >= 'a' && ch <= 'z')
num = (int) ch - 96;
if (ch >= 'A' && ch <= 'Z')
num = (int) ch - 64;
return num;
}
private static int findInEn(char ch) {
String str = ch + "";
int a = -1;
for (int i = 0; i < LIST_CODE_EN.length; i++) {
if (LIST_CODE_EN[i].equals(str)) {
a = i;
break;
}
}
return a;
}
private static int findInNum(char ch) {
String str = ch + "";
int a = -1;
for (int i = 0; i < LIST_CODE_NUM.length; i++) {
if (LIST_CODE_NUM[i].equals(str)) {
a = i;
break;
}
}
return a;
}
private static String URLencode(String str) {
try {
return URLEncoder.encode(str, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return str;
}
}
private static String URLdecode(String str) {
try {
return URLDecoder.decode(str, "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return str;
}
}
}
加密方法调用EncryptUtil.encode()
函数,并传入原文
解密方法调用EncryptUtil.decode()
函数,并传入密文
本文主要工作
去看一下按钮绑定的click事件,并打下断点,很容易就能定位这些函数:
复制代码 隐藏代码
a.shzyhxjzgEncode = function(t) {
return o(k(h(t)))
}
function h(t) {
var u = /[A-Za-z0-9\-\_\.\!\~\*\'\(\)]/g
, w = t.replace(u, function(z) {
return z.codePointAt(0).toString(16)
})
, x = encodeURIComponent(w)
, y = x.replace(/%/g, '').toUpperCase();
return y
}
function k(t) {
f('string' == typeof t);
var u = []
, _iteratorNormalCompletion2 = !0
, _didIteratorError2 = !1
, _iteratorError2 = void 0;
try {
for (var x, w = t[Symbol.iterator](); !(_iteratorNormalCompletion2 = (x = w.next()).done); _iteratorNormalCompletion2 = !0) {
var y = x.value
, z = Number.parseInt(y, 16);
10 > z ? u.push(z) : g() ? (u.push(10),
u.push(z - 10)) : (u.push(11),
u.push(z - 6))
}
} catch (A) {
_didIteratorError2 = !0,
_iteratorError2 = A
} finally {
try {
!_iteratorNormalCompletion2 && w.return && w.return()
} finally {
if (_didIteratorError2)
throw _iteratorError2
}
}
return u
}
function g() {
return 0.5 <= Math.random()
}
// p = '富强民主文明和谐自由平等公正法治爱国敬业诚信友善'
function o(t) {
return t.map(function(u) {
return p[2 * u] + p[2 * u + 1]
}).join('')
}
// h('这里输入明文') = E8BF99E9878CE8BE93E585A5E6988EE69687
这里catch块和finally块的内容都不是我们需要关注的。
o
和h
都不难。说说k
。对于10 <= v < 16
,v - 10
和v - 6
都小于10,所以解码时,读到10和11,我们可以借鉴汇编的概念,认为这是一个”opcode”,有唯一的解码方式。因此我们可以在这里加上一个巧妙的随机化,即g
函数,于是一个明文可以得到多个密文,但一个密文对应唯一的明文。
接下来看怎么decode。后两步都是小模拟,我们只看看第一步的h
函数:
复制代码 隐藏代码
function j(t) {
f('string' == typeof t, 'utfs Error');
var u = t.length;
f(0 == (1 & u));
for (var w = [], x = 0; x < u; x++)
0 == (1 & x) && w.push('%'),
w.push(t[x]);
return decodeURIComponent(w.join(''))
}
为16进制串加上'%'
再调用decodeURIComponent
即可。
完整代码
- 根据参考链接1,
decodeURIComponent
和encodeURIComponent
分别对应urllib.parse.unquote
和urllib.parse.quote
。
编码
enc.py
复制代码 隐藏代码
from typing import List
from urllib import parse
import random
import re
def step3(inp: List[int]) -> str:
VALUE = '富强民主文明和谐自由平等公正法治爱国敬业诚信友善'
return ''.join(list(map(lambda v: VALUE[v << 1] + VALUE[v << 1 | 1], inp)))
def step2(inp: str) -> List[int]:
ans = []
for c in inp:
v = int(c, 16)
if v < 10:
ans.append(v)
elif random.random() < 0.5:
ans.append(11)
ans.append(v - 6)
else:
ans.append(10)
ans.append(v - 10)
return ans
def step1(inp: str) -> str:
reg = re.compile(r'[A-Za-z0-9\-\_\.\!\~\*\'\(\)]')
tmp = reg.sub(lambda g: hex(ord(g.group(0)))[2:], inp)
return parse.quote(tmp).replace('%', '').upper()
def enc(inp: str) -> str:
return step3(step2(step1(inp)))
if __name__ == '__main__':
inps = [
'全文搜索Hans774882968', '愛してます', '这里输入明文',
'x64dbg\nIDA7.7\nuser', '%e', '我知道,我是一个美男子!'
]
for inp in inps:
e = enc(inp)
print(e)
from dec import dec
d = dec(e)
assert d == inp
解码
dec.py
复制代码 隐藏代码
from typing import List
from urllib import parse
def step3(enc: str) -> List[int]:
assert len(enc) % 2 == 0
VALUE = '富强民主文明和谐自由平等公正法治爱国敬业诚信友善'
ans = []
for i in range(0, len(enc), 2):
ans.append(VALUE.index(enc[i:i + 2]) >> 1)
return ans
def step2(enc: List[int]) -> str:
ans = ''
i = 0
while i < len(enc):
if enc[i] < 10:
ans += str(enc[i])
i += 1
elif enc[i] == 10:
ans += hex(enc[i + 1] + 10)[2:]
i += 2
elif enc[i] == 11:
ans += hex(enc[i + 1] + 6)[2:]
i += 2
else:
raise f'step2 failed. 不合法数据{enc}'
return ans
def step1(enc: str) -> str:
tmp = ''
for i in range(len(enc)):
if not i % 2:
tmp += '%'
tmp += enc[i]
return parse.unquote(tmp)
def dec(enc: str) -> str:
return step1(step2(step3(enc)))
def test1():
ans = step2([
11, 8, 8, 10, 1, 11, 9, 9, 9, 11, 8, 9, 8, 7, 8, 10, 2,
11, 8, 8, 10, 1, 10, 4, 9, 3, 11, 8, 5, 8, 5, 10, 0, 5,
10, 4, 6, 9, 8, 8, 10, 4, 11, 8, 6, 9, 6, 8, 7
])
assert ans == 'e8bf99e9878ce8be93e585a5e6988ee69687'
ans = step1(ans)
assert ans == '这里输入明文'
def test2():
encs = [
'友善爱国爱国诚信民主友善敬业敬业敬业诚信自由敬业爱国法治爱国诚信文明诚信自由爱国诚信民主诚信自由敬业和谐诚信自由平等爱国平等诚信富强平等诚信自由公正敬业爱国爱国诚信自由友善爱国公正敬业公正爱国法治',
'诚信自由爱国诚信民主友善敬业敬业敬业友善爱国敬业爱国法治爱国友善公正友善爱国爱国诚信民主友善爱国敬业和谐友善爱国平等爱国平等友善自由平等友善爱国公正敬业爱国爱国友善爱国诚信自由公正敬业公正爱国法治']
for enc in encs:
assert dec(enc) == '这里输入明文'
def test3():
encs = [
'公正爱国公正民主公正友善爱国法治和谐文明富强公正民主公正和谐公正友善法治公正平等法治文明',
'公正爱国公正民主公正诚信自由法治和谐文明富强公正民主公正和谐公正友善法治公正平等法治文明'
]
for enc in encs:
assert dec(enc) == 'hans acmer'
def test4():
encs = [
'友善爱国公正爱国爱国敬业民主友善爱国公正敬业爱国友善自由诚信平等公正爱国公正民主公正友善爱国法治和谐和谐法治和谐法治和谐自由和谐爱国和谐爱国和谐文明和谐敬业和谐公正和谐爱国',
'友善爱国公正爱国爱国敬业民主友善爱国公正敬业爱国友善自由友善敬业公正爱国公正民主公正诚信自由法治和谐和谐法治和谐法治和谐自由和谐爱国和谐爱国和谐文明和谐敬业和谐公正和谐爱国']
for enc in encs:
assert dec(enc) == '我是hans774882968'
def test5():
encs = [
'友善爱国公正爱国自由敬业诚信民主友善爱国和谐爱国民主敬业法治诚信自由和谐爱国民主诚信富强公正诚信自由和谐爱国民主友善平等诚信自由友善爱国和谐爱国民主敬业敬业',
'诚信自由公正爱国自由敬业诚信民主友善爱国和谐爱国民主敬业法治诚信自由和谐爱国民主诚信富强公正友善爱国和谐爱国民主友善平等友善爱国诚信自由和谐爱国民主敬业敬业']
for enc in encs:
assert dec(enc) == '愛してます'
if __name__ == '__main__':
test1()
test2()
test3()
test4()
test5()