我正在用C和Delphi编写一个应用程序,我在这两种语言中都使用了XTEA加密,它是完全相同的,但问题是输出是不同的,即使增量和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;
}但是输出是完全不同的:/我做错了什么?
发布于 2011-02-27 19:31:56
首先,我没有试图执行你的代码:我的评论纯粹是基于检查。
我怀疑问题的根源在于大端和小端数据存储之间的混淆。
C代码中的宏(GET_ULONG_BE和PUT_ULONG_BE)提取原始数据并转换为大端格式的uint32。
在Delphi中,您可以将原始数据从字节复制到LongWord格式,而无需执行从小端到大端的转换。
除此之外,我不确定是否将S声明为Int64,但与大端/小端问题相比,这可能是次要的。
编辑:您需要在XTeaCryptStr()例程中进行大端转换。您需要将其应用于密钥结构的4个元素,以及您的数据块-在调用main加密例程之前(数据传入)和(结果传出)。
编辑:开始尝试运行Delphi代码。第一个问题是您的测试密码以nul字符开头。您需要使用不同的密码(不含nul字符)。
又一次编辑:
我将调用插入到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代码中得到了相同的结果。
发布于 2012-12-19 13:38:36
我不知道为什么我之前的答案是downvotedm然后又被删除了。
让我们再试一次。
如果您在Windows应用程序和微处理器上使用相同的C代码,那么任何标准加密都应该有效,只需选择一个即可。
看见
http://www.drbob42.com/examines/examin92.htm
http://www.hflib.gov.cn/e_book/e_book_file/bcb/ch06.htm (在Delphi中使用C++代码)
http://edn.embarcadero.com/article/10156#H11
看起来您需要使用DLL,但如果您不想分发它,则可以静态链接它
发布于 2016-10-28 13:20:34
以下是工作代码。我已经从C++代码进行了转换。干杯..;)
unit SuatXTEA;
interface
uses SysUtils;
function EncryptXTEA(Data, Key:AnsiString):AnsiString;
function DecryptXTEA(Data, Key:AnsiString):AnsiString;
implementation
function FourCharsToLong(const V: AnsiString):LongWord;
var j, k:Integer;
begin
Result:=0;
for j:=0 to Length(V)-1 do
begin
k:=(3-(j mod 4))*8;
Result:=Result or ((Ord(V[j+1]) shl k));
end;//for j...
end;//FourCharsToLong
function LongToFourChars(const V: Longword):AnsiString;
var j, k:Integer;
begin
Result:='';
for j:=0 to 3 do
begin
k:=(3-(j mod 4))*8;
Result:=Result+AnsiChar(V shr k);
end;//for j...
end;//LongToFourChars
function HexToDec(Hex:AnsiString):LongWord;
var j:Integer;
k:Byte;
Base:LongWord;
begin
Result:=0;
Hex:=UpperCase(Hex);
Base:=1;
for j:=Length(Hex) downto 1 do
begin
k:=Ord(Hex[j])-48;
if k>9 then k:=k-7;
Result:=Result+k*Base;
Base:=Base*16;
end;
end;//HexToDec
function EncryptXTEA(Data, Key:AnsiString):AnsiString;
const
Delta = $9e3779b9;
NumRounds=32;
var j:Integer;
B_Key:array [0..3] of LongWord;
Sum, v0, v1: LongWord;
B_Result:AnsiString;
begin
B_Result:='';
//--- Set Key --------------
FillChar(B_Key, SizeOf(B_Key), 0);
j:=0;
while Key<>'' do
begin
B_Key[j]:=FourCharsToLong(Copy(Key, 1, 4));
Key:=Copy(Key, 5, 1024);
inc(j);
end;//while
//-----
while Data<>'' do
begin
v0:=FourCharsToLong(Copy(Data, 1, 4));
v1:=FourCharsToLong(Copy(Data, 5, 4));
Data:=Copy(Data, 9, 1024);
//---
Sum:=0;
for j:= 0 to NumRounds-1 do
begin
Inc(v0, (((v1 shl 4) xor (v1 shr 5)) + v1) xor (Sum + B_Key[Sum and 3]));
Inc(Sum, Delta);
Inc(v1, (((v0 shl 4) xor (v0 shr 5)) + v0) xor (Sum + B_Key[Sum shr 11 and 3]));
end;//for j...
B_Result:=B_Result+LongToFourChars(v0)+LongToFourChars(v1);
end;//while Data<>''
//---
Result:='';
for j:=0 to Length(B_Result)-1 do
begin
Result:=Result+IntToHex(ord(B_Result[j+1]), 2);
end;
Result:=Lowercase(Result);
end;//EncryptXTEA
function DecryptXTEA(Data, Key:AnsiString):AnsiString;
const
Delta = $9e3779b9;
NumRounds=32;
var j:Integer;
B_Key:array [0..3] of LongWord;
Sum, v0, v1: LongWord;
B_Result:AnsiString;
begin
//--- Set Key --------------
FillChar(B_Key, SizeOf(B_Key), 0);
j:=0;
while Key<>'' do
begin
B_Key[j]:=FourCharsToLong(Copy(Key, 1, 4));
Key:=Copy(Key, 5, 1024);
inc(j);
end;//while
//-----
B_Result:='';
for j:=0 to (Length(Data) div 2)-1 do
begin
B_Result:=B_Result+AnsiChar(HexToDec(Copy(Data, (j*2)+1, 2)));
end;
//----
Result:='';
while B_Result<>'' do
begin
v0:=FourCharsToLong(Copy(B_Result, 1, 4));
v1:=FourCharsToLong(Copy(B_Result, 5, 4));
B_Result:=Copy(B_Result, 9, 1024);
//---
Sum:=$C6EF3720;//Delta*NumRounds = Delta shl 5
for j:=0 to NumRounds-1 do
begin
Dec(v1, (((v0 shl 4) xor (v0 shr 5)) + v0) xor (Sum + B_Key[(Sum shr 11) and 3]));
Dec(Sum, Delta);
Dec(v0, (((v1 shl 4) xor (v1 shr 5)) + v1) xor (Sum + B_Key[Sum and 3]));
end;//for j...
Result:=Result+LongToFourChars(v0)+LongToFourChars(v1);
end;//while Data<>''
end;//DecryptXTEA
end.https://stackoverflow.com/questions/5132510
复制相似问题