我在做VNC协议的客户端(RFB)。从我连接到服务器的部分到我从服务器接收“challenge”的部分,一切都在工作。该challenge是一个16字节的随机数,应该用用户提供的密码作为DES算法中的密钥进行加密。我尝试使用2个单元对该项目进行DES加密,一个完全失败,另一个是this one...我应该得到一个16字节的加密字符串来发送,当我调试时,我看到我的AnsiString有16个长度(我相信对于AnsiString,我们有LENGTH = BYTES)...总之,我的代码很简单,我将在这里粘贴涉及这个问题的最重要的部分。
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 中实现该解决方案,但仍然不起作用。
注意:我已经尝试过使用Challenge作为字节数组,并做了如下操作:
PasswdDES:= EncryStr(LPCSTR(Challenge[0]), '123');
但是没有成功...因为我用 Delphi 2010,我用的是AnsiString...谢谢大家的关注!
我尝试在 Delphi 上实现的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;
2条答案
按热度按时间ifsvaxew1#
VNC使用远程帧缓冲协议
一些重要的事情 * 没有在文档中描述 *。
但我们需要从doc开始:https://www.rfc-editor.org/rfc/rfc6143.html
其中有一些重要项目:
7.1.2.安全握手
一旦决定了协议版本,服务器和客户端必须就连接上要使用的安全类型达成一致。
本文档中定义的安全类型包括:
存在其他安全类型,但未公开记录。
7.2.2. VNC认证
将使用VNC身份验证。服务器发送一个随机的16字节质询:
客户端使用用户提供的密码作为密钥,通过DES对质询进行加密。为了形成密钥,密码被截断为八个字符,或者在右侧填充空字节。然后客户端发送生成的16字节响应:
未记录的重要信息:
1.当您从源密码生成8字节密码时,您应该反转位顺序以字节为单位。例如,“00100111”字节应该反转为“11100100”。如果没有这种反转,您将无法通过VNC认证。
1.查看https://www.iana.org/assignments/rfb/rfb.xhtml中的“远程帧缓冲区安全类型”,并检查您是否用途:2 -“VNC身份验证”?
af7jpaap2#
这是UltraVNC项目中des.c文件的免费Pascal转换。
和函数来加密密码