elegasoft/cipher

维吉尼尔密码的无密钥版本

v0.4.2 2024-02-29 03:41 UTC

This package is auto-updated.

Last update: 2024-09-29 05:43:22 UTC


README

Latest Version on Packagist Total Downloads GitHub Actions

这是一个多字母数字密码,非常适合混淆明文,无论是普通还是不太普通的观察者,但它不应该作为使用强加密处理敏感数据的替代方案。

安装

您可以通过composer安装此包

composer require elegasoft/cipher

基本用法

// It only encodes characters in its character base
$cipher = new Base62Cipher(config('cipher.keys.base62'));
$cipher->encipher('hide-this-string-1111');
// returns 39O8-RBeX-4ZyGD6-o8pR
$cipher->decipher('39O8-RBeX-4ZyGD6-o8pR');
// returns hide-this-message


// It can encipher symbols in its character base
$cipher = new Base96Cipher(config('cipher.keys.base96'));
$cipher->encipher('hide-this-string-1111');
// returns (3]QC+2}SsoHzRz14I<~L
$cipher->decipher('(3]QC+2}SsoHzRz14I<~L');
// returns hide-this-message

使用填充来扩展最小输出长度

$cipher = new Base96Cipher(config('cipher.keys.base96'));
// It can pad the enciphered text to a minimal output length of 6
$cipher->paddedEncipher(string: 1, minOutputLength: 6, paddingCharacter: 'a');
// returns q3sp14
$cipher->paddedDecipher(encipheredString: 'q3sp14', paddingCharacter: 'a');
// return 1

注意:使用不同的密钥将产生与这里看到的不同加密文本输出。

它是如何工作的?(简化示例)

密码使用替换字母表来用密钥字母表的替换字符替换明文字符。此密码可以为明文字符串中的每个字符使用不同的密钥字母表。

使用 Base62Cipher::encifer('Hello!') 和 3 个密钥,以下结果会发生

  1. 明文 "H" 是 Base62 字符集中的第 32 个字符,它将被替换为 第一个密钥 中的第 32 个字符
  2. 明文 "e" 是 Base62 字符集中的第 5 个字符,它将被替换为 第二个密钥 中的第 5 个字符
  3. 明文 "l" 是 Base62 字符集中的第 12 个字符,它将被替换为 第三个密钥 中的第 12 个字符
  4. 明文 "l" 是 Base62 字符集中的第 12 个字符,它将被替换为 第二个密钥 中的第 12 个字符
  5. 明文 "o" 是 Base62 字符集中的第 15 个字符,它将被替换为 第三个密钥 中的第 15 个字符
  6. 明文 "!" 不会被替换,因为它不在 Base62 字符集中,但如果它是可替换的字符,替换将发生在 第一个密钥

它真正是如何工作的?

如果你使用上面的简化示例,第一个字符将按提供的准确加密,然而,从 "e" 字符开始,并从这里继续。在将 "e" 替换为第 5 位置的字符之前,密钥将按顺序旋转,直到 "H" 字符位于 0 索引位置。然后选择第 5 位置的字符。密码将继续切换密钥流并旋转它们,直到前一个字符位于 0 索引位置之前,然后选择下一个字符,直到达到字符串的末尾。

这种行为通过很少的计算努力增加了解密的复杂性,因为以不同字符开始的字符串将产生截然不同的结果。

// For example
$cipher = new Base62Cipher(config('cipher.keys.base62'));
$cipher->encipher('bat'); // Outputs eaO
$cipher->encipher('cat'); // Outputs koB
$cipher->encipher('hat'); // Outputs 3A9
$cipher->encipher('mat'); // Outputs PX2

如果密钥不是根据前一个字符旋转,那么四个字符串的加密输出将具有相同的最后两个字符。

独特性和处理顺序输入

因为这只是一个密码,而不是哈希算法,每个输入都应产生一个单一输出。我已经运行了多达一百万个不同输入的多个模拟,并且没有发现重复。然而,如果发送连续输入,会出现明显的趋势。

例如

$cipher = new Base62Cipher(config('cipher.keys.base62'))
$cipher->encipher('aaaaaaaa') // Outputs tW7vz1pT
$cipher->encipher('aaaaaaab') // Outputs tW7vz1pu
$cipher->encipher('aaaaaaac') // Outputs tW7vz1pn
$cipher->encipher('aaaaaaad') // Outputs tW7vz1p7

如果你预计会有很多连续输入,我建议使用 reverseEncipherreverseDecipher 来减少连续相似性。

例如

$cipher = new Base62Cipher(config('cipher.keys.base62'))
$cipher->reverseEncipher('aaaaaaaa') // Outputs tW7vz1pT
$cipher->reverseEncipher('aaaaaaab') // Outputs ea5H4Kt2
$cipher->reverseEncipher('aaaaaaac') // Outputs kouIgSfE
$cipher->reverseEncipher('aaaaaaad') // Outputs r4m7jswy

显然,由于这种密码算法的特性,肯定会出现一些额外的模式,所以请用它来混淆信息,而不是用于加密。

冲突/限制

冲突是哈希算法的问题,因为它们以可变长度的字符串作为输入,并以固定长度的字符串作为输出。这个 Elegasoft\Cipher 没有固定的输出长度,也不对输入进行哈希处理。相反,它执行密码替换,所以把它想象成把从你熟悉的语言转换成你从未见过的语言,而且它并不像正常语言那样运行。当使用 Elegasoft\Cipher 时,输出长度等于输入长度。

解码/解密的可能性?

我不是密码学家,这还没有经过密码学家的审查,所以我无法计算破解密码的难度,但根据可用的信息,你不应该尝试暴力破解这个密码。

实际上,没有人能真正回答解密有多难的问题,因为我们还需要了解一些未知因素才能做出更明智的决定。

  1. 正在加密的字符串有多长?
  2. 你使用了多少个加密密钥来加密字符串?
  3. 你使用了哪种加密方法?
  4. 你的加密密钥有多随机?

为了增加解密的难度,请使用更长的字符串(即使需要填充),并增加随机性和加密密钥的数量。但最重要的是不要共享你的加密密钥。

在编写了这个密码算法之后,我试图找出它是哪种类型的密码。在我的有限研究中,我能找到的最近似的密码是一种多字母密码,它并不完全接近一次性密码,这取决于你如何共享编码内容,以及你是否保密地保留密钥。

如果你是密码学家,请随时给我留言,我很想了解更多。

这个解决什么用例问题?

我正在寻找一种缩短URL的方法,无需担心冲突,这应该是一个有趣的项目。在没有指导或研究的情况下,经过几天的破解,我发现我可能真的发明了自己的谜题机器。

测试

composer test

更新日志

请参阅 更新日志 了解最近更改的更多信息。

贡献

请参阅 贡献指南 了解详细信息。

安全

如果你发现任何安全相关的问题,请通过电子邮件 jason@elegasoft.com 而不是使用问题跟踪器。

致谢

许可证

MIT许可证(MIT)。请参阅 许可证文件 了解更多信息。

Laravel软件包模板

此软件包是使用 Laravel软件包模板 生成的。