Skip to content

Commit

Permalink
Everything for V2.5.0 Node.js
Browse files Browse the repository at this point in the history
  • Loading branch information
SheepChef committed Nov 19, 2024
1 parent 2b5c0fa commit c626871
Show file tree
Hide file tree
Showing 9 changed files with 2,615 additions and 798 deletions.
80 changes: 62 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

**Abracadabra** 是一个多表加密之小项目,使用汉字作为密文,支持自定义密文映射和关键词映射,你正在查阅其基于 Node.js 的分支。
**Abracadabra** 是一个文本即时加密/脱敏工具,也可用于加密文件,你正在查阅其基于 Node.js 的分支。

Abracadabra 是表演魔术 (施魔法) 时所念的咒语。

Expand All @@ -14,9 +14,12 @@ C++ 版本和 Node.js 版本完全等效,密文可以互相交叉解密。

**查阅 C++ 实现**: [**dev_c Branch**](https://github.com/SheepChef/Abracadabra/tree/dev_c)

Telegram: [@abracadabra_cn](https://t.me/abracadabra_cn)

## 特性

- 方便,密文可以描述自身。
- 简短,密文简短方便传播。
- 随机,加密结果具有随机性。
- 无序,加密的文本如咒语般不可阅读。
- 安心,密码表中已剔除敏感汉字。
Expand All @@ -41,7 +44,7 @@ import { Abracadabra } from 'abracadabra-cn'
你可以用以下文本来测试,请使用默认密钥(不要输入密钥)。

```
家他你烃瞐雨峦心夕心已千迷心斋处非了青褔十第个濑总春办硼图客理明到当所分奏汐挽项更动处那上硫雨高分于硫因第部能名协要山每笋雨缬冰设呢位页一坤数琉敬心当作啊雫赴呢心能
边难全您事二起住协踵先铭碘个版赴沢月及务褔集咫氧檀银绮铭学叫涧于路以白盈种四通重都俟沥困栀裳间烯化所德即园湍
```

## 部署说明
Expand Down Expand Up @@ -75,32 +78,33 @@ import { Abracadabra } from 'abracadabra-cn'
let Abra = new Abracadabra(); //不附带参数,

/*
Abracadabra.LINK = "LINK";
强制以链接模式加密
MODES:
Abracadabra.ENCRYPT = "ENCRYPT";
强制加密
Abracadabra.DECRYPT = "DECRYPT";
强制解密(一定条件下)
强制解密
Abracadabra.AUTO = "AUTO";
自动(遵循自动逻辑)
Abracadabra.NORMAL = "NORMAL";
强制普通加密
*/
Abra.Input(input,mode,key)
Abra.Input(input,mode,key,q)
```

第一个参数 `input` 接受两种类型的输入,分别是 `String``Uint8Array`,这是此前在实例化的时候指定的输入类型。

如果你指定了 `UINT8` 却传入 `String`,将抛出错误,反之亦然。

第二个参数 `mode` 接受特定字符串的输入,任何其他输入都将被视为 `AUTO` 并被忽略。
第二个参数 `mode` 接受上文中特定字符串的输入,任何其他输入都将被视为 `AUTO` 并被忽略。

第三个参数 `key` 接受字符串类型的密钥输入,如果不提供,则默认使用内置密钥 `ABRACADABRA`

如果指定了错误的密码,那么在解码/解密数据校验过程中会抛出错误。

第四个参数 `q` 接受布尔值的输入,如果传入 `true`,则加密结果中将不含标志位,更加隐蔽,但解密时需要强制解密。

在无错误的情况下, `Input()` 函数的返回值通常是 `0`

### Output()
Expand All @@ -110,7 +114,7 @@ import { Abracadabra } from 'abracadabra-cn'

let Abra = new Abracadabra(); //不附带参数,

Abra.Input(input,mode,key)
Abra.Input(input,mode,key,q)

let Result = Abra.Output() //获取输出
```
Expand All @@ -129,27 +133,39 @@ Abracadabra 还在积极开发中,这里是一些注意事项。

此分支不存在平台兼容性问题。

### 文件处理速度

鱼与熊掌不可兼得,本算法由于需要频繁查表,故对大文件(>3MB)处理速度较低。

本项目之目的并不是加密大文件,故不会采取积极措施优化大文件的处理速度。

### 标志位污染

加密选择的标志位尽可能地排除了日常情况下出现碰撞的可能。

但有些极其特殊的时候,例如你正在尝试加密日语和中文夹杂的文本/文件,此时有可能出现污染现象。

你可以选择强制加密来解决此问题。

## 加密细节

### 加密过程

```
原数据 -> AES-256-CTR -> Base64 -> 三重转轮 / 映射汉字 -> 密文
原数据 -> 压缩 -> AES-256-CTR -> Base64 -> 三重转轮 / 映射汉字 -> 密文
```

### 映射表

Abracadabra 使用古老的多表加密,以最常用的 3000 个汉字(剔除了可能随机组成敏感词的汉字)为密本,对大小写拉丁字母,阿拉伯数字和部分符号进行映射。

大写字母的映射方式为在小写字母前添加一个汉字的标志位。

你可以自行修改映射表,制造独属于你的加密程序。

### AES-256-CTR

核心安全性由久经考验的 AES 加密算法提供,我们不打算重新发明密码学。

AES 加密密钥和转轮密钥是同一个。
AES 加密密钥和转轮密钥是同一个,均采用哈希值

### 三重转轮

Expand All @@ -159,15 +175,15 @@ AES 加密密钥和转轮密钥是同一个。

这个数组中的每个数字,都会决定三重转轮中每个转轮每次迭代的转动方向和转动距离,其复杂程度堪比甚至胜过 Enigma 机。

数字,字母和符号分别拥有一套转轮,即总共九个转轮,改变密钥相当于更换一套完全不同的转轮。
数字/符号,字母分别拥有一套转轮,即总共六个转轮,改变密钥相当于更换一套完全不同的转轮。

转轮显著增加了 Base64 密文的安全性,可以有效抵抗多种攻击,如果你对具体实现方法感兴趣,欢迎查阅代码。

### 随机性

在映射为汉字的时候,每个字母/数字/符号均有多种可能性,完全随机选择。

这进一步降低了密文的规律性,让它看起来像毫无逻辑的乱码
这进一步降低了密文的规律性,让它看起来像毫无意义的汉字字符串

### 标志位

Expand All @@ -179,10 +195,38 @@ AES 加密密钥和转轮密钥是同一个。

Abracadabra 的灵感来源于网络上曾流行过的熊曰加密。

## Abracadabra VS 与熊论道

```
愿青空的祝福,与我的羽翼同在
Abracadabra(等效密文,默认密钥):
靛让每菁选名氘添硫业纽定妃祉们间檀飒蛟建去菁畔坞店只玖不班走欲办泉玊靠益登很更雫砥浇惦服谜曳经描芳贮类座钒件
氖霞上铂赛些夕给锗所片奖过达侃五霞裕化鸠带萌芳留欤智请鲤花锻千悟羟短好要铁年萤萤祁莺间营桅无琼氮经店完沢添局
本好房咨至浣理雅茶夏前缬赴款谜玊每客着舒事方何也欣茶在闪图带仅钠祥没沃汨锡鸭院个氘大座去莉纽北款桜氧闭泉描本
与熊论道(唯一密文):
呋食食嘍嗡吖物吃訴吖物嗅喜達拙達發怎嘍襲現嗷既歡嚄類捕歡達哞呆麼出啽吃堅和吖既森寶蜂眠森告發沒破吖歡嘶盜達告爾取襲
```

| 特性 \ 工具 | Abracadabra | 与熊论道 |
| ------------ | ----------------- | --------------- |
| 易用性 | 🟡 稍弱 | ✅ 傻瓜化 |
| 加密文本体积 | ✅ 更短 | 🟡 较短 |
| 加密方式 | ✅ AES-256 / 转轮 | ❌ 非公开算法 |
| 加密过程 | ✅ 密钥参与 | ❌ 无用户密钥 |
| 算法安全 | ✅ 抗多种攻击 | ❌ 易受攻击 |
| 随机性 | ✅ 密文多变 | ❌ 密文固定 |
| 隐私性 | ✅ 完全本地加密 | ❌ 上传到服务器 |
| 密文构成 | ✅ 常见字 | 🟡 罕见字 |
| 密文特征 | ✅ 无明显特征 | ❌ 特征明显 |
| 文件加密 | ✅ 支持(较慢) | ❌ 不支持 |
| 开源 | ✅ 开源 | ❌ 不开源 |

## Todo

- [x] ~~实现更规范地解析命令参数~~
- [x] ~~实现加密任意文件,输出文本文档~~
- [x] ~~用 Node.js 完整实现 Abracadabra 的轮子~~
- [x] ~~实现让嵌入自定义密本更具灵活性~~
- [ ] 数据的可靠压缩
- [x] ~~数据的可靠压缩~~
544 changes: 544 additions & 0 deletions docs/assets/index-Co398iAN.js

Large diffs are not rendered by default.

541 changes: 0 additions & 541 deletions docs/assets/index-xgQKxEIX.js

This file was deleted.

2 changes: 1 addition & 1 deletion docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Abracadabra Demo</title>
<script type="module" crossorigin src="./assets/index-xgQKxEIX.js"></script>
<script type="module" crossorigin src="./assets/index-Co398iAN.js"></script>
<link rel="stylesheet" crossorigin href="./assets/index-BmpJePLS.css">
</head>
<body>
Expand Down
44 changes: 14 additions & 30 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ export class Abracadabra {
static TEXT = "TEXT"; //常量方便调用
static UINT8 = "UINT8";

static LINK = "LINK";
static ENCRYPT = "ENCRYPT";
static DECRYPT = "DECRYPT";
static AUTO = "AUTO";
static NORMAL = "NORMAL";

#input = ""; //输入类型,可以是 BLOB 或者 TEXT
#output = ""; //输出类型,可以是 BLOB 或者 TEXT

Expand Down Expand Up @@ -38,18 +38,18 @@ export class Abracadabra {
*
* **模式定义**
*
* **DECRYPT** 强制解密,对输入执行预检,然后解密
* **ENCRYPT** 强制加密
*
* **AUTO** 自动判断输入是否是密文,然后自动执行对应操作
* **DECRYPT** 强制解密
*
* **LINK** 强制加密,使用链接模式,将输入强制转换为字符串,进行UrlEncode,再加密
* **AUTO** 自动判断输入是否是密文,然后自动执行对应操作
*
* **NORMAL** 强制加密,使用默认模式。
* @param{string | Uint8Array}input 输入的数据,根据此前指定的输入类型,可能是字符串或字节数组
* @param{string}mode 指定模式,可以是 DECRYPT AUTO LINK NORMAL 中的一种;
* @param{string}key 指定密钥,默认是 ABRADACABRA;
* @param{string}mode 指定模式,可以是 ENCRYPT DECRYPT AUTO 中的一种;
* @param{string}key 指定密钥,默认是 ABRACADABRA;
* @param{bool}q 指定是否在加密后省略标志位,默认 false/不省略;
*/
Input(input, mode, key = "ABRACADABRA") {
Input(input, mode, key = "ABRACADABRA", q = false) {
if (this.#input == Abracadabra.UINT8) {
//如果指定输入类型是UINT8
if (Object.prototype.toString.call(input) != "[object Uint8Array]") {
Expand All @@ -72,30 +72,20 @@ export class Abracadabra {
preCheckRes = Util.preCheck(inputString);

if (
(preCheckRes.isEncrypted &&
mode != Abracadabra.LINK &&
mode != Abracadabra.NORMAL) ||
(preCheckRes.isEncrypted && mode != Abracadabra.ENCRYPT) ||
mode == Abracadabra.DECRYPT
) {
//如果是加密的字符串且没有强制指定要再次加密,或者强制执行解密,自动执行解密
//注意,DEFAULT此时不可用(即使指定),在这里如果指定DEFAULT,也会自动执行解密
//如果是加密的字符串,指定AUTO在此处会自动解密
this.#res = Util.deMap(preCheckRes, key);
} else {
this.#res = Util.enMap(
preCheckRes,
mode == Abracadabra.LINK ? true : false,
key
); //在字符串可解码的情况下,加密时不采用文件模式
this.#res = Util.enMap(preCheckRes, key, q); //在字符串可解码的情况下,加密时不采用文件模式
}
} else {
//如果给定的数据不可预检(不可能是密文,此时强制解密无效),直接对数据传递给加密函数
preCheckRes = new Util.PreCheckResult(input, true, false);
this.#res = Util.enMap(
preCheckRes,
mode == Abracadabra.LINK ? true : false,
key
);
this.#res = Util.enMap(preCheckRes, key, q);
}
} else if (this.#input == Abracadabra.TEXT) {
//如果指定输入类型是TEXT
Expand All @@ -104,20 +94,14 @@ export class Abracadabra {
}
let preCheckRes = Util.preCheck(input);
if (
(preCheckRes.isEncrypted &&
mode != Abracadabra.LINK &&
mode != Abracadabra.NORMAL) ||
(preCheckRes.isEncrypted && mode != Abracadabra.ENCRYPT) ||
mode == Abracadabra.DECRYPT
) {
//如果是加密的字符串且没有强制指定要再次加密,或者强制执行解密,自动执行解密
//如果是加密的字符串,指定AUTO在此处会自动解密
this.#res = Util.deMap(preCheckRes, key);
} else {
this.#res = Util.enMap(
preCheckRes,
mode == Abracadabra.LINK ? true : false,
key
); //在字符串可解码的情况下,加密时不采用文件模式
this.#res = Util.enMap(preCheckRes, key, q); //在字符串可解码的情况下,加密时不采用文件模式
}
}
return 0;
Expand Down
12 changes: 9 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "abracadabra-cn",
"description": "Use Chinese to Encode Everything",
"private": false,
"version": "2.0.0",
"version": "2.5.0",
"main": "./dist/abracadabra-cn.js",
"type": "module",
"scripts": {
Expand All @@ -16,7 +16,8 @@
},
"dependencies": {
"crypto-js": "^4.2.0",
"js-base64": "^3.7.7"
"js-base64": "^3.7.7",
"pako": "^2.1.0"
},
"files": [
"dist"
Expand Down
Loading

0 comments on commit c626871

Please sign in to comment.