Windows Credential Storage/de
From Free Pascal wiki
Jump to navigationJump to search
│ Deutsch (de) │ English (en) │
Dieser Artikel behandelt ausschließlich Windows.
Siehe auch: Multiplatform Programming Guide/de
Mit der Windows *Anmeldeinformationsverwaltung* (EN: Credential Manager) kann eine Anwendung sensible Benutzernamen und Kennworte sicher speichern ohne diese in einer offen einsehbaren Konfigurationsdatei ablegen zu müssen.
Die hier bereitgestellte Unit stellt drei Funktionen bereit um die Kennworte zu lesen, schreiben und zu löschen. Bei jedem Aufruf muss eine Identifikation der Anmeldeinformationen (Parameter *Target*) mitgegeben werden.
unit uwincred;
// Original Source https://stackoverflow.com/questions/13145112/secure-way-to-store-password-in-windows
// Angepasst für Free Pascal
{$mode ObjFPC}{$H+}
interface
uses
Classes, SysUtils, windows, JwaWinCred;
function CredReadGenericCredentials(const Target: UnicodeString; var Username, Password: UnicodeString): Boolean;
function CredWriteGenericCredentials(const Target, Username, Password: UnicodeString): Boolean;
function CredDeleteGenericCredentials(const Target: UnicodeString): Boolean;
implementation
function WideCharToWideString(s: PWideChar; UnicodeCharCount: SizeInt): UnicodeString;
begin
SetLength(Result{%H-}, UnicodeCharCount);
strmove(PWideChar(Result), s, UnicodeCharCount);
end;
function CredReadGenericCredentials(const Target: UnicodeString; var Username, Password: UnicodeString): Boolean;
var
credential: PCREDENTIALW;
le: DWORD;
s: UnicodeString;
begin
Result := False;
credential := nil;
if not CredReadW(PWideChar(Target), CRED_TYPE_GENERIC, 0, {var}credential) then
begin
le := GetLastError;
s := 'Could not get "'+Target+'" generic credentials: '+SysErrorMessage(le)+' '+IntToStr(le);
OutputDebugStringW(PWideChar(s));
Exit;
end;
try
username := Credential^.UserName;
password := WideCharToWideString(PWideChar(Credential^.CredentialBlob), Credential^.CredentialBlobSize div 2); //By convention blobs that contain strings do not have a trailing NULL.
finally
CredFree(Credential);
end;
Result := True;
end;
function CredWriteGenericCredentials(const Target, Username, Password: UnicodeString): Boolean;
var
Credentials: CREDENTIALW;
begin
ZeroMemory(@Credentials, SizeOf(Credentials));
Credentials.TargetName := PWideChar(Target); //cannot be longer than CRED_MAX_GENERIC_TARGET_NAME_LENGTH (32767) characters. Recommended format "Company_Target"
Credentials.Type_ := CRED_TYPE_GENERIC;
Credentials.UserName := PWideChar(Username);
Credentials.Persist := CRED_PERSIST_LOCAL_MACHINE;
Credentials.CredentialBlob := PByte(Password);
Credentials.CredentialBlobSize := 2*(Length(Password)); //By convention no trailing null. Cannot be longer than CRED_MAX_CREDENTIAL_BLOB_SIZE (512) bytes
Credentials.UserName := PWideChar(Username);
Result := CredWriteW(@Credentials, 0);
end;
function CredDeleteGenericCredentials(const Target: UnicodeString): Boolean;
begin
Result := CredDeleteW(PWideChar(Target), CRED_TYPE_GENERIC, 0);
end;
end.
Die Verwendung funktioniert wie folgend. Als *Target* wird der Programmname verwendet.
var
StoredUserName, StoredPassword: UnicodeString;
begin
StoredUserName := '';
StoredPassword := '';
// Anmeldeinformationen lesen
CredReadGenericCredentials(Application.ExeName, StoredUserName, StoredPassword);
// Anmeldeinformationen speichern
CredWriteGenericCredentials(Application.ExeName, StoredUserName, StoredPassword);
// Anmeldeinformationen löschen
CredDeleteGenericCredentials(Application.ExeName);
end;