RC4在Delphi和C?

kil*_*ode 5 c delphi encryption delphi-7

我已经设法将RC4实现从PolarSSL移植到delphi,因为我需要在两个应用程序(C和Delphi)之间进行加密通信,但问题是,加密数据永远不会相同,两个代码都自己加密和解密数据成功但不是由另一个加密的数据.

以下是两个代码:

C代码(取自PolarSSL)

typedef struct
{
    int x;                      /*!< permutation index */
    int y;                      /*!< permutation index */
    unsigned char m[256];       /*!< permutation table */
}
arc4_context;

void arc4_setup(arc4_context *ctx, unsigned char *key, int keylen)
{
    int i, j, k, a;
    ctx->x = 0;
    ctx->y = 0;
    for( i = 0; i < 256; i++ ) ctx->m[i] = (unsigned char) i;
    j = k = 0;
    for( i = 0; i < 256; i++, k++ )
    {
        if( k >= keylen ) k = 0;
        a = ctx->m[i];
        j = ( j + a + key[k] ) & 0xFF;
        ctx->m[i] = ctx->m[j];
        ctx->m[j] = (unsigned char) a;
    }
    return;
}

void arc4_crypt( arc4_context *ctx, unsigned char *buf, int buflen )
{
    int i, x, y, a, b;
    unsigned char m[256];

    x = ctx->x;
    y = ctx->y;

    for (i = 0; i < 256; i++) m[i] = ctx->m[i];
    for( i = 0; i < buflen; i++ )
    {
        x = ( x + 1 ) & 0xFF; a = m[x];
        y = ( y + a ) & 0xFF; b = m[y];

        m[x] = (unsigned char) b;
        m[y] = (unsigned char) a;

        buf[i] = (unsigned char)
            ( buf[i] ^ m[(unsigned char)( a + b )] );
    }
    return;
}
Run Code Online (Sandbox Code Playgroud)

我的德尔福代码:

type
  arc4_context = packed record
    x, y: integer;
    m: array[0..255] of byte;
  end;

procedure arc4_setup(var ctx: arc4_context; key: PChar; keylen: Integer);
var
 i, j, k, a: Integer;
begin
 ctx.x := 0;
 ctx.y := 0;
 for i := 0 to 255 do ctx.m[i] := Byte(i);
 j := 0;
 k := 0;
 for i := 0 to 255 do
 begin
   if (k >= keylen) then k := 0;
   a := ctx.m[i];
   j := (j + a + Byte(key[k])) and $FF;
   ctx.m[i] := ctx.m[j];
   ctx.m[j] := a;
   Inc(k);
 end;
end;


procedure arc4_crypt(ctx:arc4_context; var buf:string; buflen:integer);
var
 i, x, y, a, b: Integer;
 m: array [0..255] of byte;
begin
 x := ctx.x;
 y := ctx.y;
 for i := 0 to 255 do m[i] := ctx.m[i];
 i := 0;
 while (i < buflen) do
 begin
  x := (x + 1) and $FF;
  a := m[x];
  y := (y + a) and $FF;
  b := m[y];

  m[x] := b;
  m[y] := a;

  buf[i+1] := Char(Byte(buf[i+1]) xor Byte(m[a + b]));
  inc(i);
 end
end;
Run Code Online (Sandbox Code Playgroud)

Dav*_*nan 10

我(最后)发现了两个代码之间的差异.

Pascal转换的以下行不正确:

buf[i+1] := Char(Byte(buf[i+1]) xor Byte(m[a + b]));
Run Code Online (Sandbox Code Playgroud)

C版读取:

buf[i] = (unsigned char) ( buf[i] ^ m[(unsigned char)( a + b )] );
Run Code Online (Sandbox Code Playgroud)

请注意,它a + b被截断为单个unsigned char,而上面的Pascal版本说m[a + b],因此索引a + b可以超过255.

您应将此行翻译为:

buf[i+1] := chr(ord(buf[i+1]) xor ord(m[Byte(a+b)]));
Run Code Online (Sandbox Code Playgroud)

我改变了使用Chr,ord这是化妆品的变化,但我觉得它们更清洁.实质性的变化在于m[Byte(a+b)]我强制a+b添加在字节数据类型的上下文中.

相反,这个错误导致数组的超出范围的数组访问m.如果您在启用范围检查的情况下运行,则会立即突出显示该错误.我不能强调Delphi的范围检查功能有多么重要.