1

我收到了一个加密文件,其中明文的格式是“常见的(但现在不是很常见)”。~80000 字节
它已使用我将描述为带有修改加密表的 Vigenere 密码进行加密。一个字节的密钥和一个字节的明文映射到一个字节的密文。密钥串具有一定的长度,因此用于加密的密钥字符在密钥串中循环。
密钥仅包含字母数字字符。

到目前为止,我通过找到密文中重复三元组​​的起始位置的最小公约数来确定密钥长度为 30/60。Vigenere 的标准。

现在,我一直在猜测密钥的可能字符,方法是观察解密的字节是什么,并消除它们超出可接受范围的可能性(因为 32-126 是可见的,没有 16-31 之间的值等)
这个第一部分工作,它有一个小密钥,明文是直接的 ASCII。

当我尝试使用较大的文件和“新文件格式”时,它会拒绝所有可能的字符。
这消除了 ASCII、Ascii85、Base64、windows-1252、utf-7、QP 和 uuencode,因为它们都依赖于 ASCII 字符集。我还为拒绝所有密钥的 EBCDIC 和 ISO8859-1 制作了过滤器。Utf-8 也失败了,因为没有密钥会使所有字节都以 0、10、110、1110、11110、111110 或 1111110 开头。

我没有尝试过的其余字符编码我怀疑是 UTF-16,32,1,我不确定如何过滤。

我的问题是:

  • 还有其他我忘记的字符编码吗?
  • 是否有可能我过滤掉了太多并且应该允许一些超出范围的字符滑过?
  • 文件格式可能意味着字符编码以外的东西吗?如果是这样,我该如何协调它与过滤器仍然破坏 ASCII 字符?
  • 如果文件格式意味着压缩或存档怎么办?

这是我使用的过滤代码,过滤器是可变的,具体取决于我要筛选的内容。

void guessCrypt(string fileName, int keyLength, int index)
{
    byte[] file = cast(byte[])read(fileName);
    foreach(key;ValidKeyChars)
    {
        bool work = true;
        for(int x = index; x < file.length-10; x+=keyLength)
        {
            byte single = file[x];
            int res = sdecrypt(single,key);
            if ((res < 32 && res > 15) || res > 126) //FILTER - this one ASCII
            {
                work = false;
                break;
            }
        }
        if (work == true)
        {
            writefln("\nwork: %s",key);
        }
    }

}
4

1 回答 1

3

我建议甚至不要打扰现有的编码;将其视为替代密码的另一层,并根据字母频率计算出什么映射到什么。如果字符实际上是连续的,那只会有助于您的分析。一旦你知道它们真正映射到什么,你就可以从那里找到它实际上是什么字符集。

于 2011-09-22T00:49:36.393 回答