0

编辑:

似乎错误出在ReadResource()函数内。在解密之前打印输出时,代码已经被切断。

旧文:

我在我的应用程序资源中存储了一个 RC4 加密字符串。因为 RC4 加密具有最大字符串大小,所以我将大字符串拆分为子字符串并用分隔符划分它们。

现在,我的应用程序应该从资源中读取。然后使用分隔符拆分它们,解密每个子字符串并再次组合它们。

当使用'testestestestest........test'作为字符串尝试此操作时,它可以工作,但如果我使用例如'Lorem ipsum dolor sit amet,consetetur sadipscing elitr',它会在解密期间切断部分字符串。

这是 RC4 代码:

char* rc4_crypt( char *s, size_t datalen, char *d, size_t keylen)

{
unsigned char S[SIZE];
char *data = s;
char *key = d;
int i,j,k,tmp;

  for(i = 0; i < SIZE;i++)
   S[i] = i;

  for(j = i = 0; i < SIZE;i++) {
   j = (j + S[i] + key[i%keylen]) % SIZE;
   tmp = S[i];
   S[i] = S[j];
   S[j] = tmp;   
  }

  for(i = j = k = 0; k < datalen;k++) {
   i = (i + 1) % SIZE;
   j = (j + S[i]) % SIZE;
   tmp = S[i];
   S[i] = S[j];
   S[j] = tmp;
   tmp = S[(S[i] + S[j]) % SIZE];
   data[k] ^= tmp;
  }
  return data;
}

这是处理拆分的代码:

std::vector<std::string> &split(const std::string &s, 
                                char delim, std::vector<std::string> &elems) {
    std::stringstream ss(s);
    std::string item;
    while(std::getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}


std::vector<std::string> split(const std::string &s, char delim) {
    std::vector<std::string> elems;
    return split(s, delim, elems);
}
void print (std::string &elem)
{
    //This is because somehow 'ul' is still included 
    //as an extra element, this sorts it out
    if(elem.length() !=2) { 
        cout << elem << '\n';
        char *output = rc4_crypt((char *)elem.c_str(),
            strlen(elem.c_str()),key, strlen(key));
        cout << output << '\n';
        FinalString = FinalString + output;
    }

}

这是我的主要功能:

int main() {
  char *output;
  output = ReadResource();
  std::string stringy;
  stringy = output;
  std::vector<std::string> splitted = split(stringy,'+ul+');
  for_each (splitted.begin(), splitted.end(), print);
    cout << endl;
  cout << FinalString << '\n';
}

有谁知道为什么会这样?

编辑:

我正在添加我在 vb.net 中使用的 RC4 函数来加密代码。也许这可以帮助:

Private Shared Function Proper_RC4(ByVal Input As Byte(), ByVal Key As Byte()) As Byte()

        Dim i, j, swap As UInteger
        Dim s As UInteger() = New UInteger(255) {}
        Dim Output As Byte() = New Byte(Input.Length - 1) {}

        For i = 0 To 255
            s(i) = i
        Next

        For i = 0 To 255
            j = (j + Key(i Mod Key.Length) + s(i)) And 255
            swap = s(i) 'Swapping of s(i) and s(j)
            s(i) = s(j)
            s(j) = swap
        Next

        i = 0 : j = 0
        For c = 0 To Output.Length - 1
            i = (i + 1) And 255
            j = (j + s(i)) And 255
            swap = s(i) 'Swapping of s(i) and s(j)
            s(i) = s(j)
            s(j) = swap
            Output(c) = Input(c) Xor s((s(i) + s(j)) And 255)
        Next

        Return Output
    End Function

编辑2:

这是 ReadResource() 函数:

char *ReadResource() {
    TCHAR buffer[MAX_PATH];
    GetModuleFileName(NULL,buffer,sizeof(buffer));
    HMODULE ModuleH = GetModuleHandle(buffer);
    HRSRC Res = FindResource(ModuleH, L"1", L"DATA");
    HGLOBAL GlobalH = LoadResource(ModuleH,Res);
    void * ptr = LockResource(GlobalH);
    Size = SizeofResource(ModuleH,Res);
    CHAR *m_pResourceBuffer = new CHAR[Size];
    if (m_pResourceBuffer != NULL)
    {
        memcpy(m_pResourceBuffer, ptr, Size);

    }
    return m_pResourceBuffer;
}
4

2 回答 2

2

如果我理解正确,ReadResource就是读取加密数据。如果是这样,那么该数据的中间很容易有一个零。当分配给 时,该零将被视为 NULL 终止符string。因此,它只会解密直到第一个零。可能是第一个示例在加密结果中没有以零结尾,但第二个示例确实如此。

但正如其他人已经在评论中指出的那样,RC4 应该没有必要将其分解成碎片。它应该能够在一次调用中全部加密。实际上,在每次重置 s-box 的同时继续使用相同的密钥进行加密是不好的(不安全的)。结果非常脆弱。这在此 Wikipedia 文章中有一些描述。

如果将其加密为单个流,则处理逻辑会变得简单得多。当您读取数据(例如,通过ReadResource)时,您还需要获取长度。该函数将需要返回长度。然后在调用中使用该长度来解密数据。

于 2013-02-06T00:54:57.627 回答
1

您对此代码有一些问题。

警告:多字符常量,std::getline使用一个字符分隔符。这也是ul出现在数组中的原因splitted

splitted = split(stringy,'+ul+');

您修改从返回的字符串c_str()

rc4_crypt((char *)elem.c_str(), ...);

std::string::c_str

程序不得更改此序列中的任何字符。返回的指针指向字符串对象当前用于存储符合其值的字符的内部数组。

返回的指针可能会因进一步调用修改对象的其他成员函数而失效。

最后,最有可能的截止点是

data[k] ^= tmp;

如果data[k] == tmp,那么这将给出零,并且您的字符串在此位置被截断。

于 2013-02-06T01:05:52.660 回答