Password hash encryption and decryption unit in the Delphi-RDP File

Source: Internet
Author: User

Rdpfile is the file used by the Microsoft Remote Desktop tool mstsc.exe to record logon information. With the RDP file, you can easily connect to the Remote Desktop.
In the RDP file, the password must be encrypted before it can be used.
This Unit implements encryption and decryption of passwords. Install the producer API first.

SVN address for commit API: https://jedi-apilib.svn.sourceforge.net/svnroot/jedi-apilib/jwapi/trunk

{******************************************************************}{ Author: Remko Weijnen (r dot weijnen at gmail dot com)           }{ Version: 0.1                                                     }{ Date: 21-03-2007                                                 }{                                                                  }{ The contents of this file are subject to                         }{ the Mozilla Public License Version 1.1 (the "License"); you may  }{ not use this file except in compliance with the License. You may }{ obtain a copy of the License at                                  }{ http://www.mozilla.org/MPL/MPL-1.1.html                          }{                                                                  }{ Software distributed under the License is distributed on an      }{ "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or   }{ implied. See the License for the specific language governing     }{ rights and limitations under the License.                        }{******************************************************************}unit RDPHash;interfaceuses  Windows, Sysutils, JwaWinCrypt;function CryptRDPPassword(sPassword: string): string;function DecryptRDPPassword(sPasswordHash: string): string;function BlobDataToHexStr(P: PByte; I: Integer): string;function PasswordHashToBlobData(sPasswordHash: string): DATA_BLOB;implementation{***********************************************************}{ HexToByte: Converts Hex value to Byte                     }{ Found this somewhere on the internet                      }{***********************************************************}function HexToByte(s : String): Byte;const  cs = '0123456789ABCDEF';begin  result := 0;  if (length(s) = 2) and     //(s[1] in ['0'..'9','A'..'F']) and     CharInSet(s[1], ['0'..'9','A'..'F']) and     //(s[2] in ['0'..'9','A'..'F']) then     CharInSet(s[2], ['0'..'9','A'..'F']) then    result := ((pos(s[1],cs)-1) *16) + (pos(s[2],cs)-1)  else raise EConvertError.CreateFmt('%s is not a Hexformatstring',[s]);end;{***********************************************************}{ PasswordHashToBlobData: Converts a RDP password Hash to   }{                         a DATA_BLOB structure             }{ sPasswordHash : RDP Password Hash (HEX String             }{***********************************************************}function PasswordHashToBlobData(sPasswordHash: string): DATA_BLOB;var Buf: array of Byte;  dwBufSize: Cardinal;  i: Cardinal;  j: Cardinal;  dwHashSize: Cardinal;begin  dwBufSize := Length(sPassWordHash) DIV 2;  dwHashSize := Length(sPasswordHash);  SetLength(Buf, dwBufSize);  i := 1;  j := 0;  while i < dwHashSize do begin    Buf[j] := HexToByte(sPassWordHash[i] + sPassWordHash[i+1]);    Inc(i, 2);    Inc(j);  end;  GetMem(Result.pbData, dwBufSize);  Result.cbData := dwBufSize;  Result.pbData := PByte(Buf);end;{***********************************************************}{ BlobDataToHexStr: Converts a PByte from a DATA_BLOB       }{                   to a Hex String so it can be saved in   }{                   an RDP file                             }{ P : PByte (pbData) from DATA_BLOB                         }{ I : Integer (cbData) from DATA_BLOB                       }{***********************************************************}function BlobDataToHexStr(P: PByte; I: Integer): string;var HexStr: string;begin  HexStr := '';  while (I > 0) do begin    Dec(I);    HexStr := HexStr + IntToHex(P^, 2);    Inc(P);  end;  Result := HexStr;end;{***********************************************************}{ CryptRDPPassword: Converts a plaintext password to        }{                   encrypted password hash                 }{                   an RDP file                             }{ sPassword: plaintext password                             }{***********************************************************}function CryptRDPPassword(sPassword: string): string;var  DataIn: DATA_BLOB;  DataOut: DATA_BLOB;  pwDescription: PWideChar;  PwdHash: string;begin  PwdHash := '';  DataOut.cbData := 0;  DataOut.pbData := nil;  // RDP uses UniCode  DataIn.pbData := Pointer(WideString(sPassword));  DataIn.cbData := Length(sPassword) * SizeOf(WChar);  // RDP always sets description to psw  pwDescription := WideString('psw');  if CryptProtectData(@DataIn,                      pwDescription,                      nil,                      nil,                      nil,                      CRYPTPROTECT_UI_FORBIDDEN, // Never show interface                      @DataOut) then  begin    PwdHash := BlobDataToHexStr(DataOut.pbData, DataOut.cbData);  end;  Result := PwdHash;  // Cleanup  LocalFree(Cardinal(DataOut.pbData));  LocalFree(Cardinal(DataIn.pbData));end;{***********************************************************}{ DecryptRDPPassword: Converts an RDP Password Hash back    }{                     to it's original password.            }{                     Note that this only works for the user}{                     who encrypted the password (or on the }{                     same computer in case it was encrypted}{                     with the computerkey                  }{ sPasswordHash: Password hash (string)                     }{***********************************************************}function DecryptRDPPassword(sPasswordHash: string): string;var  DataIn: DATA_BLOB;  DataOut: DATA_BLOB;  sPassword: string;  pwDecrypted: PWideChar;  pwDescription: PWideChar;begin  DataIn := PasswordHashToBlobData(sPasswordHash);  DataOut.cbData := 0;  DataOut.pbData := nil;  if CryptUnprotectData(@DataIn,                        @pwDescription,                        nil,                        nil,                        nil,                        CRYPTPROTECT_UI_FORBIDDEN, // Never show interface                        @DataOut) then  begin    Getmem(pwDecrypted, DataOut.cbData);    lstrcpynW(pwDecrypted, PWideChar(DataOut.pbData), (DataOut.cbData DIV 2) + 1);    sPassword := pwDecrypted;    FreeMem(pwDecrypted);  end  else    raise EConvertError.CreateFmt('Error decrypting: %s',[SysErrorMessage(GetLastError)]);  Result := sPassword;  // Cleanup  if DataOut.cbData > 0 then    LocalFree(Cardinal(DataOut.pbData));end;end.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.