kil*_*ode 3 c delphi encryption delphi-7
我在C和Delphi上编写应用程序,我在两者中都有XTEA加密,它完全相同,但问题是输出是不同的,即使delta和N是相同的.我真的不知道什么是错的
这是Delphi代码
type
  TTeaMsgBlock = array[0..1] of LongWord;
  TTeaKeyBlock = array[0..3] of LongWord;
const   
  DELTA = $9e3779b9;
  N = 32;
procedure XTeaCrypt(var V: TTeaMsgBlock; const K: TTeaKeyBlock);
var
  I: LongWord;
  S: Int64;
begin
  S := 0;
  for I := 0 to N - 1 do begin
    Inc(V[0], (((V[1] shl 4) xor (V[1] shr 5)) + V[1]) xor (S + K[S and 3]));
    Inc(S, DELTA);
    Inc(V[1], (((V[0] shl 4) xor (V[0] shr 5)) + V[0]) xor (S + K[(S shr 11) and 3]));
  end;
end;
function XTeaCryptStr(const Msg, Pwd: string): string;
var
  V: TTeaMsgBlock;
  K: TTeaKeyBlock;
  I, L, N: Integer;
begin
  L := Length(Pwd); if L > SizeOf(K) then L := SizeOf(K);
  K[0] := 0; K[1] := 0; K[2] := 0; K[3] := 0; Move(Pwd[1], K[0], L);
  I := 1; L := Length(Msg);
  if L > 0 then SetLength(Result, ((L - 1) div SizeOf(V) + 1) * SizeOf(V))
           else SetLength(Result, 0);
  while I <= L do begin
    V[0] := 0; V[1] := 0;
    N := L - I + 1; if N > SizeOf(V) then N := SizeOf(V);
    Move(Msg[I], V[0], N);
    XTeaCrypt(V, K);
    Move(V[0], Result[I], SizeOf(V));
    Inc(I, SizeOf(V))
  end;
end;
//Test
const Key: array [0..15] of char = (char($00), char($01), char($02), char($03), char($04), char($05), 
                                char($06), char($07), char($08), char($09), char($0a), char($0b), 
                                char($0c), char($0d), char($0e), char($0f));
const Msg: string = 'This Is#';
begin
 WriteLn('Encrypted: ' + pChar(XTeaCryptStr(Msg, Key)));
end.
这就是C代码(取自PolarSSL)
typedef struct
{
    uint32_t k[4];       /*!< key */
} xtea_context;
#ifndef GET_ULONG_BE
#define GET_ULONG_BE(n,b,i)                             \
{                                                       \
    (n) = ( (unsigned long) (b)[(i)    ] << 24 )        \
        | ( (unsigned long) (b)[(i) + 1] << 16 )        \
        | ( (unsigned long) (b)[(i) + 2] <<  8 )        \
        | ( (unsigned long) (b)[(i) + 3]       );       \
}
#endif
#ifndef PUT_ULONG_BE
#define PUT_ULONG_BE(n,b,i)                             \
{                                                       \
    (b)[(i)    ] = (unsigned char) ( (n) >> 24 );       \
    (b)[(i) + 1] = (unsigned char) ( (n) >> 16 );       \
    (b)[(i) + 2] = (unsigned char) ( (n) >>  8 );       \
    (b)[(i) + 3] = (unsigned char) ( (n)       );       \
}
#endif
/*
 * XTEA key schedule
 */
void xtea_setup( xtea_context *ctx, unsigned char key[16] )
{
    int i;
    memset(ctx, 0, sizeof(xtea_context));
    for( i = 0; i < 4; i++ )
    {
        GET_ULONG_BE( ctx->k[i], key, i << 2 );
    }
}
/*
 * XTEA encrypt function
 */
int xtea_crypt_ecb( xtea_context *ctx, int mode, unsigned char input[8],
                     unsigned char output[8])
{
    uint32_t *k, v0, v1, i;
    k = ctx->k;
    GET_ULONG_BE( v0, input, 0 );
    GET_ULONG_BE( v1, input, 4 );
    if( mode == XTEA_ENCRYPT )
    {
        uint32_t sum = 0, delta = 0x9E3779B9;
        for( i = 0; i < 32; i++ )
        {
            v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
            sum += delta;
            v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
        }
    }
    else /* XTEA_DECRYPT */
    {
        uint32_t delta = 0x9E3779B9, sum = delta * 32;
        for( i = 0; i < 32; i++ )
        {
            v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
            sum -= delta;
            v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
        }
    }
    PUT_ULONG_BE( v0, output, 0 );
    PUT_ULONG_BE( v1, output, 4 );
    output[8] = '\0';
    return( 0 );
}
//test
int main()
{
    int i;
    unsigned char buf[8] = "This Is#";
    xtea_context ctx;
    xtea_setup( &ctx, (unsigned char *) xtea_test_key);
    xtea_crypt_ecb( &ctx, XTEA_ENCRYPT, buf, buf );
    printf("Encrypted = %s\n", buf);
    return 0;
}
但输出完全不同:/我做错了什么?
首先,我没有尝试执行您的代码:我的评论完全基于检查.
我怀疑你的问题根源是big-endian和little-endian数据存储之间的混淆.
C代码中的宏(GET_ULONG_BE和PUT_ULONG_BE)正在提取原始数据并以BIG-endian格式转换为uint32.
在Delphi中,您将原始数据从字节复制到LongWord格式,而不需要对big-endian进行小端转换.
除此之外,我不确定S作为Int64的声明,但与大端/小端问题相比,这可能是微不足道的.
编辑:您需要在XTeaCryptStr()例程中进行big-endian转换.您需要将它应用于密钥结构的4个元素以及数据块 - 在数据进入之前(数据进入)和之后(结果出来)对主加密例程的调用.
编辑:开始尝试运行Delphi代码.第一个问题是您的测试密码以空字符开头.您需要使用不同的密码(没有空字符).
又一个编辑:
我插入了对SwapEndian()的调用,如下所示:
function XTeaCryptStr(const Msg, Pwd: string): string;
    var
      V: TTeaMsgBlock;
      K: TTeaKeyBlock;
      I, L, N: Integer;
  begin
  L := Length(Pwd);
  if L > SizeOf(K) then
    L := SizeOf(K);
  K[0] := 0; K[1] := 0; K[2] := 0; K[3] := 0;
  Move(Pwd[1], K[0], L);
  for i := 0 to 3 do
    K[i] := SwapEndian( K[i] );
  I := 1; L := Length(Msg);
  if L > 0 then
    SetLength(Result, ((L - 1) div SizeOf(V) + 1) * SizeOf(V))
  else
    SetLength(Result, 0);
  while I <= L do
    begin
    V[0] := 0; V[1] := 0;
    N := L - I + 1;
    if N > SizeOf(V) then
      N := SizeOf(V);
    Move(Msg[I], V[0], N);
    V[0] := SwapEndian( V[0] );
    V[1] := SwapEndian( V[1] );
    XTeaCrypt(V, K);
    V[0] := SwapEndian( V[0] );
    V[1] := SwapEndian( V[1] );
    Move(V[0], Result[I], SizeOf(V));
    Inc(I, SizeOf(V))
    end;
  end;
有了这个(以及一个不包含空字符的密码),我从C和Delphi代码得到了相同的结果.
| 归档时间: | 
 | 
| 查看次数: | 2063 次 | 
| 最近记录: |