2013-05-09 144 views
0

我正在为VNC协议(RFB)做客户端。从我连接到服务器的部分到我从服务器接收'挑战'的部分,一切都在发挥作用。挑战是一个16字节的随机数,应该使用用户提供的密码作为DES算法中的密钥加密。我试着用这个项目使用2个单位进行DES加密,其中一个是完全失败的,另一个是this one ...我应该得到一个16字节的加密字符串发送,当我调试时,我看到我的AnsiString有16个字节(我相信对于AnsiStrings我们有LENGTH = BYTES)......无论如何,我的代码很简单,我会在这里粘贴涉及这个问题的最重要的部分。VNC DES认证算法

Challenge: array[0..15] of AnsiChar; 
PasswdDES: AnsiString; 
Result: array[0..3] of AnsiChar; 
    begin 
     MySocket:= TClientSocket.Create(Nil); 
     .... 
     MySocket.Socket.ReceiveBuf(Challenge, SizeOf(Challenge)); 
     PasswdDES:= EncryStr(AnsiString(Challenge), AnsiString('123')); 
     MySocket.Socket.SendText(PasswdDES); 
     MySocket.Socket.ReceiveBuf(Result, SizeOf(Result)); 

我总是收到'结果'值#1什么意思认证失败... EncryStr是单位的一个功能。我试用了this link并试图在Delphi中实现该解决方案,但仍然无法正常工作。

注:我已经尝试过使用挑战的字节数组,和不喜欢的东西:

PasswdDES:= EncryStr(LPCSTR(Challenge[0]), '123'); 

但没有成功。由于我使用德尔福2010年,我使用AnsiString类型...感谢的为您的关注!

的Java解决方案我想在德尔福实现是这样的:

Function BitFlip(B: Byte): Byte; //stackoverflow 
const 
    N: array[0..15] of Byte = (0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15); 
begin 
    Result := N[B div 16] or N[B mod 16] shl 4; 
End; 

Function Invert(input: PAnsiChar): AnsiString; 
var 
    I : int32; 
Begin 
    Result := ''; 
    for I := 0 to length(input)-1 do 
    Result := Result + AnsiChar(BitFlip(Byte(Input[I]))); 
End; 
+0

既然你不会将您链接到,没有人比你可以调试它的VNC代码的翻译。以下是如何做到这一点。运行一系列输入的原始代码。然后运行相同系列输入的翻译。然后调试差异。 – 2013-05-09 20:02:37

+0

对不起,但我没有得到你。我正在使用该单位,我在这里链接的单位,没有差异... – user1526124 2013-05-09 20:11:37

+0

我的意思是:http://www.vidarholen.net/contents/junk/vnc.html – 2013-05-09 20:36:58

回答

0

这是鸟哥的项目des.c文件的Free Pascal转换。

unit pasd3des; 

{$mode objfpc}{$H+} 

interface 

const 
    EN0 = 0; (* MODE == encrypt *) 
    DE1 = 1; (* MODE == decrypt *) 

procedure des(inblock, outblock: PChar); 
procedure deskey(key: PChar; edf: ShortInt); 

implementation 

const 
    Df_Key: array[0..23] of byte = (
    $01, $23, $45, $67, $89, $AB, $CD, $EF, 
    $FE, $DC, $BA, $98, $76, $54, $32, $10, 
    $89, $AB, $CD, $EF, $01, $23, $45, $67); 

    bytebit: array[0..7] of word = (1, 2, 4, 8, 16, 32, 64, 128); 

    bigbyte: array[0..23] of Longword = (
    $800000, $400000, $200000, $100000, 
    $80000, $40000, $20000, $10000, 
    $8000, $4000, $2000, $1000, 
    $800, $400, $200, $100, 
    $80,  $40,  $20,  $10, 
    $8,  $4,  $2,  $1); 

    pc1: array[0..55] of byte = (
    56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, 
    9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 
    62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 
    13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3); 

    totrot: array[0..15] of byte = (1, 2, 4, 6, 8, 10, 12, 14, 15, 17, 19, 21, 23, 25, 27, 28); 

    pc2: array[0..47] of byte = (13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, 
    22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, 
    40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, 
    43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31); 

    SP1: array[0..63] of Longword = (
    $01010400, $00000000, $00010000, $01010404, 
    $01010004, $00010404, $00000004, $00010000, 
    $00000400, $01010400, $01010404, $00000400, 
    $01000404, $01010004, $01000000, $00000004, 
    $00000404, $01000400, $01000400, $00010400, 
    $00010400, $01010000, $01010000, $01000404, 
    $00010004, $01000004, $01000004, $00010004, 
    $00000000, $00000404, $00010404, $01000000, 
    $00010000, $01010404, $00000004, $01010000, 
    $01010400, $01000000, $01000000, $00000400, 
    $01010004, $00010000, $00010400, $01000004, 
    $00000400, $00000004, $01000404, $00010404, 
    $01010404, $00010004, $01010000, $01000404, 
    $01000004, $00000404, $00010404, $01010400, 
    $00000404, $01000400, $01000400, $00000000, 
    $00010004, $00010400, $00000000, $01010004); 

    SP2: array[0..63] of Longword = (
    $80108020, $80008000, $00008000, $00108020, 
    $00100000, $00000020, $80100020, $80008020, 
    $80000020, $80108020, $80108000, $80000000, 
    $80008000, $00100000, $00000020, $80100020, 
    $00108000, $00100020, $80008020, $00000000, 
    $80000000, $00008000, $00108020, $80100000, 
    $00100020, $80000020, $00000000, $00108000, 
    $00008020, $80108000, $80100000, $00008020, 
    $00000000, $00108020, $80100020, $00100000, 
    $80008020, $80100000, $80108000, $00008000, 
    $80100000, $80008000, $00000020, $80108020, 
    $00108020, $00000020, $00008000, $80000000, 
    $00008020, $80108000, $00100000, $80000020, 
    $00100020, $80008020, $80000020, $00100020, 
    $00108000, $00000000, $80008000, $00008020, 
    $80000000, $80100020, $80108020, $00108000); 

    SP3: array[0..63] of Longword = (
    $00000208, $08020200, $00000000, $08020008, 
    $08000200, $00000000, $00020208, $08000200, 
    $00020008, $08000008, $08000008, $00020000, 
    $08020208, $00020008, $08020000, $00000208, 
    $08000000, $00000008, $08020200, $00000200, 
    $00020200, $08020000, $08020008, $00020208, 
    $08000208, $00020200, $00020000, $08000208, 
    $00000008, $08020208, $00000200, $08000000, 
    $08020200, $08000000, $00020008, $00000208, 
    $00020000, $08020200, $08000200, $00000000, 
    $00000200, $00020008, $08020208, $08000200, 
    $08000008, $00000200, $00000000, $08020008, 
    $08000208, $00020000, $08000000, $08020208, 
    $00000008, $00020208, $00020200, $08000008, 
    $08020000, $08000208, $00000208, $08020000, 
    $00020208, $00000008, $08020008, $00020200); 

    SP4: array[0..63] of Longword = (
    $00802001, $00002081, $00002081, $00000080, 
    $00802080, $00800081, $00800001, $00002001, 
    $00000000, $00802000, $00802000, $00802081, 
    $00000081, $00000000, $00800080, $00800001, 
    $00000001, $00002000, $00800000, $00802001, 
    $00000080, $00800000, $00002001, $00002080, 
    $00800081, $00000001, $00002080, $00800080, 
    $00002000, $00802080, $00802081, $00000081, 
    $00800080, $00800001, $00802000, $00802081, 
    $00000081, $00000000, $00000000, $00802000, 
    $00002080, $00800080, $00800081, $00000001, 
    $00802001, $00002081, $00002081, $00000080, 
    $00802081, $00000081, $00000001, $00002000, 
    $00800001, $00002001, $00802080, $00800081, 
    $00002001, $00002080, $00800000, $00802001, 
    $00000080, $00800000, $00002000, $00802080); 

    SP5: array[0..63] of Longword = (
    $00000100, $02080100, $02080000, $42000100, 
    $00080000, $00000100, $40000000, $02080000, 
    $40080100, $00080000, $02000100, $40080100, 
    $42000100, $42080000, $00080100, $40000000, 
    $02000000, $40080000, $40080000, $00000000, 
    $40000100, $42080100, $42080100, $02000100, 
    $42080000, $40000100, $00000000, $42000000, 
    $02080100, $02000000, $42000000, $00080100, 
    $00080000, $42000100, $00000100, $02000000, 
    $40000000, $02080000, $42000100, $40080100, 
    $02000100, $40000000, $42080000, $02080100, 
    $40080100, $00000100, $02000000, $42080000, 
    $42080100, $00080100, $42000000, $42080100, 
    $02080000, $00000000, $40080000, $42000000, 
    $00080100, $02000100, $40000100, $00080000, 
    $00000000, $40080000, $02080100, $40000100); 

    SP6: array[0..63] of Longword = (
    $20000010, $20400000, $00004000, $20404010, 
    $20400000, $00000010, $20404010, $00400000, 
    $20004000, $00404010, $00400000, $20000010, 
    $00400010, $20004000, $20000000, $00004010, 
    $00000000, $00400010, $20004010, $00004000, 
    $00404000, $20004010, $00000010, $20400010, 
    $20400010, $00000000, $00404010, $20404000, 
    $00004010, $00404000, $20404000, $20000000, 
    $20004000, $00000010, $20400010, $00404000, 
    $20404010, $00400000, $00004010, $20000010, 
    $00400000, $20004000, $20000000, $00004010, 
    $20000010, $20404010, $00404000, $20400000, 
    $00404010, $20404000, $00000000, $20400010, 
    $00000010, $00004000, $20400000, $00404010, 
    $00004000, $00400010, $20004010, $00000000, 
    $20404000, $20000000, $00400010, $20004010); 

    SP7: array[0..63] of Longword = (
    $00200000, $04200002, $04000802, $00000000, 
    $00000800, $04000802, $00200802, $04200800, 
    $04200802, $00200000, $00000000, $04000002, 
    $00000002, $04000000, $04200002, $00000802, 
    $04000800, $00200802, $00200002, $04000800, 
    $04000002, $04200000, $04200800, $00200002, 
    $04200000, $00000800, $00000802, $04200802, 
    $00200800, $00000002, $04000000, $00200800, 
    $04000000, $00200800, $00200000, $04000802, 
    $04000802, $04200002, $04200002, $00000002, 
    $00200002, $04000000, $04000800, $00200000, 
    $04200800, $00000802, $00200802, $04200800, 
    $00000802, $04000002, $04200802, $04200000, 
    $00200800, $00000000, $00000002, $04200802, 
    $00000000, $00200802, $04200000, $00000800, 
    $04000002, $04000800, $00000800, $00200002); 

    SP8: array[0..63] of Longword = (
    $10001040, $00001000, $00040000, $10041040, 
    $10000000, $10001040, $00000040, $10000000, 
    $00040040, $10040000, $10041040, $00041000, 
    $10041000, $00041040, $00001000, $00000040, 
    $10040000, $10000040, $10001000, $00001040, 
    $00041000, $00040040, $10040040, $10041000, 
    $00001040, $00000000, $00000000, $10040040, 
    $10000040, $10001000, $00041040, $00040000, 
    $00041040, $00040000, $10041000, $00001000, 
    $00000040, $10040040, $00001000, $00041040, 
    $10001000, $00000040, $10000040, $10040000, 
    $10040040, $10000000, $00040000, $10001040, 
    $00000000, $10041040, $00040040, $10000040, 
    $10040000, $10001000, $10001040, $00000000, 
    $10041040, $00041000, $00041000, $00001040, 
    $00001040, $00040040, $10000000, $10041000); 

var 
    KnL: array[0..31] of Longword; 

procedure usekey(from: PLongWord); 
var 
    ato, endp: PLongWord; 
begin 
    ato := @KnL[0]; 
    endp := @KnL[31]; 
    while (ato <= endp) do 
    begin 
    ato[0] := from[0]; 
    ato := @ato[1]; 
    from := @from[1]; 
    end; 
end; 

procedure cookey(raw1: PLongWord); 
var 
    cook, raw0: PLongWord; 
    dough: array[0..31] of LongWord; 
    i: Integer; 
begin 
    cook := @dough[0]; 
    for i := 0 to 15 do 
    begin 
    raw0 := raw1; 
    raw1 := @raw1[1]; 
    cook[0] := (raw0[0] and $00fc0000) shl 6; 
    cook[0] := cook[0] or (raw0[0] and $00000fc0) shl 10; 
    cook[0] := cook[0] or (raw1[0] and $00fc0000) shr 10; 
    cook[0] := cook[0] or (raw1[0] and $00000fc0) shr 6; 
    cook := @cook[1]; 
    cook[0] := (raw0[0] and $0003f000) shl 12; 
    cook[0] := cook[0] or (raw0[0] and $0000003f) shl 16; 
    cook[0] := cook[0] or (raw1[0] and $0003f000) shr 4; 
    cook[0] := cook[0] or (raw1[0] and $0000003f); 
    cook := @cook[1]; 
    raw1 := @raw1[1]; 
    end; 
    usekey(@dough); 
end; 

procedure deskey(key: PChar; edf: ShortInt); 
var 
    i, j, l, m, n: Integer; 
    pc1m, pcr: array[0..55] of Byte; 
    kn: array[0..31] of LongWord; 
begin 
    for j := 0 to 55 do 
    begin 
    l := pc1[j]; 
    m := l and 07; 
    if (Byte(key[l shr 3]) and bytebit[m]) > 0 then 
     pc1m[j] := 1 
    else 
     pc1m[j] := 0; 
    end; 
    for i := 0 to 15 do 
    begin 
    if (edf = DE1) then 
     m := (15 - i) shl 1 
    else 
     m := i shl 1; 
    n := m + 1; 
    kn[m] := 0; 
    kn[n] := 0; 
    for j := 0 to 27 do 
    begin 
     l := j + totrot[i]; 
     if (l < 28) then 
     pcr[j] := pc1m[l] 
     else 
     pcr[j] := pc1m[l - 28]; 
    end; 
    for j := 28 to 55 do 
    begin 
     l := j + totrot[i]; 
     if (l < 56) then 
     pcr[j] := pc1m[l] 
     else 
     pcr[j] := pc1m[l - 28]; 
    end; 
    for j := 0 to 23 do 
    begin 
     if (pcr[pc2[j]] <> 0) then 
     kn[m] := kn[m] or bigbyte[j]; 
     if (pcr[pc2[j+24]] <> 0) then 
     kn[n] := kn[n] or bigbyte[j]; 
    end; 
    end; 
    cookey(@kn); 
end; 

procedure cpkey(into: PLongWord); 
var 
    from, endp: PLongWord; 
begin 
    from := KnL; 
    endp := @KnL[31]; 
    while (from <= endp) do 
    begin 
    into[0] := from[0]; 
    into := @into[1]; 
    from := @from[1]; 
    end; 
end; 

procedure scrunch(outof: PByte; into: PLongWord); 
begin 
    into[0] := (outof[0] and $ff) shl 24; 
    outof := @outof[1]; 
    into[0] := into[0] or (outof[0] and $ff) shl 16; 
    outof := @outof[1]; 
    into[0] := into[0] or (outof[0] and $ff) shl 8; 
    outof := @outof[1]; 
    into[0] := into[0] or (outof[0] and $ff); 
    outof := @outof[1]; 
    into := @into[1]; 
    into[0] := (outof[0] and $ff) shl 24; 
    outof := @outof[1]; 
    into[0] := into[0] or (outof[0] and $ff) shl 16; 
    outof := @outof[1]; 
    into[0] := into[0] or (outof[0] and $ff) shl 8; 
    outof := @outof[1]; 
    into[0] := into[0] or (outof[0] and $ff); 
end; 

procedure unscrun(outof: PLongWord; into: PByte); 
begin 
    into[0] := Byte((outof[0] shr 24) and $ff); 
    into := @into[1]; 
    into[0] := Byte((outof[0] shr 16) and $ff); 
    into := @into[1]; 
    into[0] := Byte((outof[0] shr 8) and $ff); 
    into := @into[1]; 
    into[0] := Byte(outof[0] and $ff); 
    outof := @outof[1]; 
    into := @into[1]; 
    into[0] := Byte((outof[0] shr 24) and $ff); 
    into := @into[1]; 
    into[0] := Byte((outof[0] shr 16) and $ff); 
    into := @into[1]; 
    into[0] := Byte((outof[0] shr 8) and $ff); 
    into := @into[1]; 
    into[0] := Byte(outof[0] and $ff); 
end; 

procedure desfunc(block, keys: PLongWord); 
var 
    fval, work, right, leftt: LongWord; 
    roundd: Integer; 
begin 
    leftt := block[0]; 
    right := block[1]; 
    work := ((leftt shr 4) xor right) and $0f0f0f0f; 
    right := right xor work; 
    leftt := leftt xor (work shl 4); 
    work := ((leftt shr 16) xor right) and $0000ffff; 
    right := right xor work; 
    leftt := leftt xor (work shl 16); 
    work := ((right shr 2) xor leftt) and $33333333; 
    leftt := leftt xor work; 
    right := right xor (work shl 2); 
    work := ((right shr 8) xor leftt) and $00ff00ff; 
    leftt := leftt xor work; 
    right := right xor (work shl 8); 
    right := ((right shl 1) or ((right shr 31) and 1)) and $ffffffff; 
    work := (leftt xor right) and $aaaaaaaa; 
    leftt := leftt xor work; 
    right := right xor work; 
    leftt := ((leftt shl 1) or ((leftt shr 31) and 1)) and $ffffffff; 
    for roundd := 0 to 7 do 
    begin 
    work := (right shl 28) or (right shr 4); 
    work := work xor keys[0]; 
    keys := @keys[1]; 
    fval := SP7[work and $3f]; 
    fval := fval or SP5[(work shr 8) and $3f]; 
    fval := fval or SP3[(work shr 16) and $3f]; 
    fval := fval or SP1[(work shr 24) and $3f]; 
    work := right xor keys[0]; 
    keys := @keys[1]; 
    fval := fval or SP8[work and $3f]; 
    fval := fval or SP6[(work shr 8) and $3f]; 
    fval := fval or SP4[(work shr 16) and $3f]; 
    fval := fval or SP2[(work shr 24) and $3f]; 
    leftt := leftt xor fval; 
    work := (leftt shl 28) or (leftt shr 4); 
    work := work xor keys[0]; 
    keys := @keys[1]; 
    fval := SP7[work and $3f]; 
    fval := fval or SP5[(work shr 8) and $3f]; 
    fval := fval or SP3[(work shr 16) and $3f]; 
    fval := fval or SP1[(work shr 24) and $3f]; 
    work := leftt xor keys[0]; 
    keys := @keys[1]; 
    fval := fval or SP8[work and $3f]; 
    fval := fval or SP6[(work shr 8) and $3f]; 
    fval := fval or SP4[(work shr 16) and $3f]; 
    fval := fval or SP2[(work shr 24) and $3f]; 
    right := right xor fval; 
    end; 
    right := (right shl 31) or (right shr 1); 
    work := (leftt xor right) and $aaaaaaaa; 
    leftt := leftt xor work; 
    right := right xor work; 
    leftt := (leftt shl 31) or (leftt shr 1); 
    work := ((leftt shr 8) xor right) and $00ff00ff; 
    right := right xor work; 
    leftt := leftt xor (work shl 8); 
    work := ((leftt shr 2) xor right) and $33333333; 
    right := right xor work; 
    leftt := leftt xor (work shl 2); 
    work := ((right shr 16) xor leftt) and $0000ffff; 
    leftt := leftt xor work; 
    right := right xor (work shl 16); 
    work := ((right shr 4) xor leftt) and $0f0f0f0f; 
    leftt := leftt xor work; 
    right := right xor (work shl 4); 
    block[0] := right; 
    block[1] := leftt; 
end; 

procedure des(inblock, outblock: PChar); 
var 
    work: array[0..1] of LongWord; 
begin 
    scrunch(PByte(inblock), @work); 
    desfunc(@work, @KnL); 
    unscrun(@work, PByte(outblock)); 
end; 

end. 

和功能隐窝密码

function CryptChal(AChal, APasswd: String): String; 
const 
    CHALLENGESIZE = 16; 
var 
    key, bytes, response: pChar; 
    i: integer; 
begin 
    key := StrAlloc((CHALLENGESIZE div 2) + 1); 
    response := StrAlloc(CHALLENGESIZE + 1); 
    try 
    for i := 0 to 7 do 
    begin 
     if (i < length(Apasswd)) then 
     key[i] := Apasswd[i + 1] 
     else 
     key[i] := #0; 
    end; 
    if length(Apasswd)>8 then 
     Key[8] := #0; 

    deskey(key, 0); 

    bytes := pChar(AChal); 
    i := 0; 
    while (i < CHALLENGESIZE) do 
    begin 
     des(bytes + i, response + i); 
     inc(i, 8); 
    end; 
    Result := response; 
    SetLength(Result, CHALLENGESIZE); 
    finally 
    StrDispose(response); 
    StrDispose(key); 
    end; 
end;