【发布时间】:2015-10-21 00:48:18
【问题描述】:
我用 C# 创建了自己的非常简单的加密算法,我想知道它到底有多安全。我将算法称为“SBC”,它代表“简单字节密码”。本质上,它就像凯撒密码一样工作,除了我增加整数(相关字节的值)而不是字母。
我决定这样做有几个原因。首先,我想要一个提供精确 1:1 大小比的算法。换句话说,我希望输出加密长度等于输入文本的长度而没有任何增长。我还希望能够使用我想要的任何字母、数字、字符等,而无需将密码变成大写字母,这是本地凯撒密码无法做到的。我希望输出也主要是一堆不可打印的字符,有点像二进制文件。我也希望它快。非常快。我当前的算法能够在比我想表达的更短的时间内完全加密 Huckleberry Finn(是的,那是几分之一秒)。
但现在真正的问题摆在桌面上……我的算法有多安全?有没有办法测试它?它有什么明显的缺陷吗?请允许我先解释一下它是如何工作的,然后我将向您展示代码。
算法其实很简单,简直太简单了。我们首先采用我们想要的任意字符串,假设在这种情况下我们选择“Stackoverflow”。然后我们选择一个密码,它是“Cats Rule The Internet”,最后是一个单一的种子/盐值。让我们选择 31,因为这是我最喜欢的数字。
我的算法从遍历字符串开始,获取每个字母并使用其字节值 + 密码字节值的当前字母索引 + 种子整数值。
作为模型,它看起来像:
Input Byte | Password Byte | Seed Value|
45 + 18 + 31 = 94(this number rolls around for byte if it exceeds 255)
然后,我们有了新的字节值,它可以是数字、字母(无论是否大写)、符号,甚至是不可打印的字符。当打印到文件时,消息“这只是一个测试”。看起来像:
这是目前的代码:
/**
* Simple Byte Cipher "SBC"
* Created by Gordon Kyle Wallace, "Krythic".
*/
public static class SimpleByteCipher
{
public static byte[] EncryptStringToByteArray( string data , string password , uint seed)
{
byte[] bytes = Encoding.ASCII.GetBytes( data );
byte[] passwordBytes = Encoding.ASCII.GetBytes( password );
int passwordShiftIndex = 0;
for( int i = 0; i < bytes.Length; i++ )
{
bytes[ i ] = ( byte )( bytes[ i ] + passwordBytes[ passwordShiftIndex ] + seed );
passwordShiftIndex = ( passwordShiftIndex + 1 ) % passwordBytes.Length;
}
return bytes;
}
public static string DecryptByteArrayToString( byte[] data , string password , uint seed)
{
byte[] bytes = data;
byte[] passwordBytes = Encoding.ASCII.GetBytes( password );
int passwordShiftIndex = 0;
for( int i = 0; i < bytes.Length; i++ )
{
bytes[ i ] = ( byte )( bytes[ i ] - passwordBytes[ passwordShiftIndex ] - seed );
passwordShiftIndex = ( passwordShiftIndex + 1 ) % passwordBytes.Length;
}
return Encoding.ASCII.GetString( bytes );
}
}
我个人觉得它很安全。您不仅需要算法,还需要准确的密码,以及用于解密加密消息的种子/盐。我只是想知道你们的想法,我在这里有什么遗漏吗?
想测试你的功夫吗?尝试破解这个: Crack me if you can
【问题讨论】:
-
您错过了大约 300 年的密码学研究。
-
当您可以使用许多经过良好测试的算法实现时,您为什么要实现自定义加密方案?
-
所以答案是:很可能根本不安全。给定足够的加密文本,很容易破解。
-
...给定足够的密文,这很容易破解。基本上还是simple substitution cipher...
-
@Krythic
ASCIIEncoding.GetString(): “任何大于十六进制 0x7F 的字节都被解码为 Unicode 问号 (“?”)”。如果任何输入字符的代码点 > 127,您将不会从加密-解密往返中得到相同的字符串。
标签: c# security encryption