gpt4 book ai didi

c - XTEA 加密在 C 和 Delphi 中给出不同的输出

转载 作者:太空狗 更新时间:2023-10-29 15:53:28 25 4
gpt4 key购买 nike

我在 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;
}

但输出完全不同:/我做错了什么?

最佳答案

首先,我没有尝试执行您的代码:我的评论完全基于检查。

怀疑您问题的根源是大端和小端数据存储之间的混淆。

C 代码中的宏(GET_ULONG_BE 和 PUT_ULONG_BE)提取原始数据并转换为 BIG-endian 格式的 uint32。

在 Delphi 中,您将原始数据从字节复制为 LongWord 格式,而无需进行小端到大端的转换。

除此之外,我不确定 S 是否声明为 Int64,但与大端/小端问题相比,这可能是次要的。

编辑:您需要在 XTeaCryptStr() 例程中进行大端转换。您需要将它应用于 key 结构的 4 个元素,以及您的数据 block - 在调用主加密例程之前(数据进入)和之后(结果出来)。

编辑:开始尝试运行 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;

有了这个(以及不包含 nul 字符的密码),我从 C 和 Delphi 代码中得到了相同的结果。

关于c - XTEA 加密在 C 和 Delphi 中给出不同的输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5132510/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com