duzun / cycle-crypt
可变大小的对称密钥加密算法
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-21 17:38:45 UTC
README
可变大小的 对称 密钥加密算法。
PHP & JavaScript实现,小巧、便携且快速。
密钥生成通过将输入密钥与XorShift+随机数生成器的变体进行循环。密钥大小越大,周期越长。
安装
PHP
composer require duzun/cycle-crypt
JS
npm i -S cycle-crypt
浏览器
<script src="https://unpkg.com/cycle-crypt"></script>
用法
以下是一个在服务器端加密并在客户端解密的示例,盐自动生成。
PHP
// index.php use function duzun\cycleCrypt; $key = '*** *** ***'; // any length $message = 'Lorem Ipsum is simply dummy text of the printing industry...'; $ciphered = cycleCrypt($key, $message, true); // send $ciphered to the client echo base64_encode($ciphered);
Express.js
// index.js const cycleCrypt = require('cycle-crypt'); // or // import cycleCrypt from 'cycle-crypt'; const key = '*** *** ***'; // any length // ... app.get('/', function (req, res) { // const salt = cycleCrypt.randomBytes(17); let message = 'Lorem Ipsum is simply dummy text of the printing industry...'; let ciphered = cycleCrypt(key, message, true); res.send(Buffer.from(ciphered).toString('base64')); });
浏览器
// site.js const key = '*** *** ***'; // must be the same key used for encrypting let message = await fetch('/') .then((r) => r.text()) .then(atob) .then((ciphered) => cycleCrypt(key, ciphered, false)); console.log(message.toString('utf8')); // 'hex' | 'base64'
也可以做相反的操作:在客户端加密并在服务器端解密。
您也可以使用自己的盐
// index.php // ... $salt = random_bytes(17); // any length $ciphered = cycleCrypt($key, $message, $salt); // Have to send the salt to the client too echo json_encode([ 'salt' => base64_encode($salt), 'ciphered' => base64_encode($ciphered) ]);
// site.js // fetch ciphered & salt from server and base64 decode ... let message = cycleCrypt(key, ciphered, salt);
在JS端,message
是一个具有自定义 .toString(encoding)
的 Uint8Array
实例,其中 encoding
是 'binary'、'hex'、'base64'、'utf8' 或 undefined(猜测)之一。
对于旧浏览器,您应使用 DataView polyfill。
分块加密
以下是一个将大文件分小块加密的示例,从而避免使用大量内存。
use duzun\CycleCrypt; $cc = new CycleCrypt($key/*, $salt=true*/); $salt = $cc->getSalt(); // required for decryption $chunkSize = $cc->getKeyByteSize(); $in = fopen('/path/to/file', '+r'); $out = fopen('/path/to/encrypted_file', '+w'); while(!feof($in)) { $chunk = fread($in, $chunkSize); fwrite($out, $cc($chunk)); } fclose($in); fclose($out); file_put_contents('/path/to/encrypted_file.salt', $salt)
您不需要编写加密文件的代码,因为有一个CLI工具可以做到这一点
Node.js
npm install -g cycle-crypt cycle-crypt -k '**** ****' -s 'the salt' -i /path/to/file -o /path/to/encrypted_file
PHP
composer global require duzun/cycle-crypt cycry.php -k '**** ****' -s 'the salt' -i /path/to/file -o /path/to/encrypted_file
注意:Node.js CLI版本比PHP版本快得多。
CLI用法
cycle-crypt -k <key> [-s <salt> | -si <salt_in> | -so <salt_out>] [-sr <salt_rounds>] [-i <file_in>] [-o <file_out>]
cycle-crypt -h|--help
-h, --help Show this help
-k, --key The encryption key. Could be hex if starts with '0x'.
-s, --salt Random bytes to be used as salt. Could be hex if starts with '0x'.
Can contain the salt-rounds as "0x<salt_in_hex>x<salt_rounds>".
-si, --salt-in Filename or - from where to read the salt.
-so, --salt-out Filename or - where to output the generated salt.
-sr, --salt-rounds Number of rounds of initial state generated from salt + key
-i, --in Input file to encrypt or - for STDIN
-o, --out Output file or - for STDOUT
You can not combine -s and -si, use just one of them.
-i and -o default to -
警告!
如果您处理的是安全关键型应用程序,请考虑使用NIST批准的标准加密算法之一,如AES。
如果您不信任任何加密算法,这里有一个提示
从两个或多个供应商中选择两个或多个加密算法 C1
、C2
... Cn
。
当使用 C
= M
^ C1
^ C2
^ ... ^ Cn
对消息 M
进行加密时,密文 C
的保密性不会比最佳 Ci
差。
换句话说,当对更多的独立加密算法进行异或操作时,这不会损害保密性。
这个特性的理论已经在我的硕士论文中进行了分析和证明
总和 c = r1 ⊕ r2 ⊕ ... ⊕ rm,其中 c、ri ∈ 𝔹k(长度为k的比特串),i=1,m,是一个 完美保密 如果且仅如果至少有一个 ri 是完美的保密,并且操作 ⊕ 是一个 加密安全 操作。
待办事项
JS版本使用Uint32Array和Uint8Array,它们使用小端或大端,取决于硬件。当前实现仅在little endian硬件上进行了测试!
必须实现大端端的替代方案。