1

所以我实现了 ciphersaber-1。它几乎可以工作,我可以解密cstest1.cs1。但我无法让 cstest2.cs1 工作。

输出是:

The Fourth Amendment to the Constitution of the Unite ▀Stat→s of America

"The right o☻ the people to be secure in their persons, houses, papers, and
effects, against unreasonab→e searches an╚A)┤Xx¹▼☻dcðþÈ_#­0Uc.?n~J¿|,lómsó£k░7╠▄
íuVRÊ ╣├xð"↕(Gû┤.>!{³♫╚Tƒ}Àõ+»~C;ÔÙ²÷g.qÏø←1ß█yÎßsÈ÷g┐ÅJÔÞ┘Îö║AÝf╔ìêâß╗È;okn│CÚê
õ&æÄ[5&Þ½╔s╦Nå1En♂☻♫ôzÓ9»Á╝ÐÅ├ðzÝÎòeØ%W¶]¤▲´Oá╗e_Ú)╣ó0↑ï^☻P>ù♂­¥¯▄‗♦£mUzMצվ~8å
ì½³░Ùã♠,H-tßJ!³*²RóÅ

所以我在初始化状态时一定有一个错误。奇怪的是我可以毫无问题地加密和解密长文本,所以这个错误是对称的。

正如您在rc4.c中看到的那样,我将 rc4 密码实现为可重入单字节算法。

状态存储在 rc4_state 结构中:

typedef unsigned char rc4_byte;

struct rc4_state_
{
    rc4_byte i;
    rc4_byte j;
    rc4_byte state[256];
};
typedef struct rc4_state_ rc4_state;

使用rc4_init初始化状态:

void rc4_init(rc4_state* state, rc4_byte* key, size_t keylen)
{
    rc4_byte i, j, n;

    i = 0;
    do
    {
        state->state[i] = i;
        i++;
    }    
    while (i != 255);

    j = 0;
    i = 0;
    do
    {
        n = i % keylen;
        j += state->state[i] + key[n];
        swap(&state->state[i], &state->state[j]);
        i++;
    }    
    while (i != 255);

    state->i = 0;
    state->j = 0;
}

实际的加密/解密在rc4中完成:

rc4_byte rc4(rc4_state* state, rc4_byte in)
{
    rc4_byte n;

    state->i++;
    state->j += state->state[state->i];
    swap(&state->state[state->i], &state->state[state->j]);
    n = state->state[state->i] + state->state[state->j];

    return in ^ state->state[n];
}

为了完整起见,交换:

void swap(rc4_byte* a, rc4_byte* b)
{
    rc4_byte t = *a;
    *a = *b;
    *b = t;
}

我已经为此烦恼了两天多……状态,至少对于“asdfg”键是正确的。你能帮忙的话,我会很高兴。

整个事情可以在我的 github reopsitory 中找到:https ://github.com/rioki/ciphersaber/

4

3 回答 3

3

我在网上搜索时偶然发现了你的问题,但是由于你还没有在 GitHub 上更新你的代码,我想你可能仍然想知道问题是什么。

它在这段代码中:

i = 0;
do
{
    state->state[i] = i;
    i++;
}    
while (i != 255);

在此循环迭代 255 次后,i其值为 255,循环将终止。结果,状态缓冲区的最后一个字节未初始化。

这很容易解决。只需更改while (i != 255);while (i);.

于 2014-03-25T13:03:23.987 回答
1

抱歉,您没有得到反馈,我今天终于在 Python 3 中完成了这个,但对 C 的了解不够,无法调试您的代码。

ciphersaber 主页面上的某些链接已损坏(指向“.com”而不是“.org”),因此您可能没有找到常见问题解答:

http://ciphersaber.gurus.org/faq.html

它包括以下调试提示:

  • 确保您没有以文本文件的形式读取或写入加密文件。您必须对文件 I/O 使用二进制模式。
  • 如果您使用 C 语言编写,请确保将字节存储为无符号字符。
  • 注意经典的索引问题。您选择的编程语言中的数组是以 0 还是 1 开头的?
  • 确保在加密时写出随机的 10 字节 IV,并在解密时从文件开头读取 IV。
  • 如果您的程序仍然无法运行,请在关键设置步骤之后输入一些语句以打印出 S 数组。然后运行您的程序以使用 asdfg 作为密钥解密文件 cstest1.cs1。以下是 S 数组的外观:

文件:cstest1.cs1

关键字:asdfg

176 32 49 160 15 112 58 8 186 19 50 161 60 17 82 153 37 141 131 131 127 59 59 2 165 103 98 53 98 53 9 57 41 150 174 64 64 366 62 191 154 44 154 136 149 149 158 163 95 128 219 1 181 2011 146 88 204 213 80 143 143 164 145 234 134 134 134 248 100 77 188 235 76 217 194 35 75 99 126 126 126 126 92 243 177 52 180 83 140 83 140 198 42 198 42 124 72 139 218 142 118 81 84 31 29 195 68 209 172 200 214 93 240 61 22 206 123 152 7 203 10 119 171 79 250 109 137 199 167 11 104 211 129 208 216 178 207 242 162 30 120 65 115 87 170 47 69 244 212 45 85 73 222 225 185 63 0 179 210 108 245 202 46 96 96 148 51 173 24 182 89 116 3 67 205 94 205 94 231 231 1315 1315 190 215 190 241 241 241 228 132 228 132 252 252 252 433 56 105 26 1235 26 12 135 223 135 223 13526666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666662135235202352023.2352352A352A35AN性范表238 229 246 138 239 54 5 130 159 236 66 175 189 147 193 237 43 40 117 157 86 249 74 27 156 14 133 251 196 187 197 102 106 39232 255 121 122 253 111 90 38 55 70 184 78 224 25 6 107 168 254 144 28 183 71

我还发现“难忘的测试用例”在这里很有帮助: http ://www.cypherspace.org/adam/csvec/

其中:key="Al"+ct="Al Dakota buys"(iv="Al Dakota"): pt = "mead"

尽管令人难忘的测试用例需要 cs2,但从 cs1 升级到 cs2 相当简单,即使没有完全调试程序的其余部分,您也可以自信地将程序从 cs1 转换为 cs2。

另请注意,常见问题解答声称网站上曾经有一个文件无法解码,请确保您的目标文件不以“0e e3 f9 b2 40 11 fc 3e ...”开头(尽管我认为那是较小的测试文件,而不是证书。)

哦,而且还知道该网站并没有真正了解 RC4 及其衍生产品的最新研究。除非一切都失败了,否则将其保留为玩具程序。

于 2013-08-17T02:05:18.740 回答
1

Python

这是我用 Python 写的一个问题,后来被删除了。它将文件作为流处理,因此内存使用量适中。

用法

python encrypt.py <key> <rounds> < <infile> > <outfile>
python decrypt.py <key> <rounds> < <infile> > <outfile>

rc4.py

#!/usr/bin/env python
# coding: utf-8
import psyco
from sys import stdin,stdout,argv
def rc4(K):
    R=range(256)
    S=R[:]
    T=bytearray(K*256)[:256]
    j=0
    for i in R*int(argv[2]):
        j=j+S[i]+T[i]&255
        S[i],S[j]=S[j],S[i]
    i=j=0
    while True:
        B=stdin.read(4096)
        if not B: break
        for c in B:
            i+=1&255
            j=j+S[i]&255
            S[i],S[j]=S[j],S[i]
            stdout.write(chr(ord(c)^S[S[i]+S[j]&255]))
psyco.bind(rc4)

encrypt.py

from rc4 import *
import os
V=os.urandom(10)
stdout.write(V)
rc4(argv[1]+V)

decrypt.py

from rc4 import *
V=stdin.read(10)
rc4(argv[1]+V)
于 2013-09-20T11:46:13.977 回答