Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Below code shows the way to save the necessary secret information in Delphi. For your information, if you want to increase the size of the message, you should increase the value of CK_MAX_MSG_LEN below.

Code Block
languagedelphi
const CK_SINGATURE = '!CK!';
const CK_MAX_MSG_LEN = 1024*8;

function CKReadPassword(sFileName:string):string;
var
  sFilelenPWD: TFileStreamWORD;
  lenPWD, lenPWD_oldbuff: WORDPAnsiChar;
  sEncryptedPWDsFile: AnsiStringTFileStream;
  buffsEncryptedPWD: PAnsiCharAnsiString;
begin
  GetMem( buff, CK_MAX_MSG_LEN);
  ZeroMemory( buff, CK_MAX_MSG_LEN);

  if FileExists(sFileName) then begin
    lenPWD_old := 0;
    sFile := TFileStream.Create( sFileName, fmOpenRead);
    if sFile.Handle<>THandle(nil) then begin
      sFile.Seek( -4, soFromEnd);
      sFile.Read( PAnsiChar(buff)^, 4);
      if buff=CK_SINGATURE then
      begin
        // has master key, so need to erase it
        sFile.Seek( -6, soFromEnd);
        sFile.Read( lenPwd, 2);
        sFile.Seek( -(lenPWD + 6), soFromEnd);
        sFile.Read( PAnsIChar(buff)^, lenPWD);
        Result := trim(string(buff));
      end;
      sFile.Destroy;
    end;
  end;

  FreeMem(buff);
end;

function CKUpdatePassword(sFileName, sPWD:String):Boolean;
var
  sFile: TFileStream;
  lenPWD, lenPWD_old: WORD;
  sEncryptedPWD: AnsiString;
  buff: PAnsiChar;
begin
  GetMem( buff, CK_MAX_MSG_LEN);
  ZeroMemory( buff, CK_MAX_MSG_LEN);

  if not FileExists(sFileName) then begin
    Result := False;
  end else begin
    lenPWD_old := 0;
    sFile := TFileStream.Create( sFileName, fmOpenReadWrite);
    if sFile.Handle<>THandle(nil) then begin
      sFile.Seek( -4, soFromEnd);
      sFile.Read( PAnsiChar(buff)^, 4);
      if buff=CK_SINGATURE then
      begin
        // has master key, so need to erase it
        sFile.Seek( -6, soFromEnd);
        sFile.Read( lenPwd, 2);
        sFile.Seek( -(lenPWD + 6), soFromEnd);
        lenPWD_old := lenPWD;
      end else sFile.Seek( 0, soFromEnd);

      while Length(sPWD)<lenPWD_old do sPWD := sPWD + ' ';

      sEncryptedPWD := AnsiString(sPWD);
      lenPWD := Length(sEncryptedPWD);
      sFile.Write(if PAnsiChar(sEncryptedPWD)^, lenPWD);(lenPWD>CK_MAX_MSG_LEN) then begin
      sFile.Write( lenPWD, 2);
      sFile.Write( PAnsiChar(CK_SINGATURE)^, 4);
 // Too long encrypted password
        Result  sFile.Destroy;

:= False
      Resultend :=else True;begin
    end   else Result := False;
  end;

  FreeMem(buff);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  if not FileExists(eMasterFile.Text) then beginsFile.Write( PAnsiChar(sEncryptedPWD)^, lenPWD);
        sFile.Write( lenPWD, 2);
        sFile.Write( PAnsiChar(CK_SINGATURE)^, 4);
    ShowMessage( 'Please select program fileResult you want'):= True;
   end  else beginend;

    if (CKUpdatePassword( eMasterFile.Text, ePWD.Text)=True) then beginsFile.Destroy;

    end else ShowMessage('Successfully Changed !!')Result := False;
  end;

    CloseFreeMem(buff);
    end;

procedure  endTForm1.Button2Click(Sender: TObject);
end;
begin
  if not FileExists(eMasterFile.Text) then begin
    ShowMessage( 'Please select program file you want');
  end else begin
    if (CKUpdatePassword( eMasterFile.Text, ePWD.Text)=True) then begin
      ShowMessage('Successfully Changed !!');
      Close;
    end;
  end;
end;


Below code provides better secure way to store secret key

Code Block
languagedelphi
uses IdCoder, IdCoderMIME, IdGlobal;

.
.
.

const CK_SINGATURE = '!CK!';
const CK_SINGATURE_KEY = 'ChunKang';
const CK_MAX_MSG_LEN = 1024*8;
const CK_ENC_VAR_RANGE=10;

function CKEncrypt(const Source:string; Salt:string): string;
var
  i, lenSalt, key, keyWeight: Word;
  InString: string;
begin
  Result := '';
  if (Salt = '') then begin
    Result := Source;
  end InString:else string;
begin
    ResultInString := ''; TIdEncoderMIME.EncodeString(Source, IndyTextEncoding_UTF8);

  if  (SaltlenSalt := '') then beginLength(Salt);

    ResultkeyWeight := Source0;
    for endi else:= begin
1 to lenSalt do InStringkeyWeight := TIdEncoderMIME.EncodeString(Source, IndyTextEncoding_UTF8 keyWeight + ord(Salt[i]);

    lenSaltkeyWeight := Length(Salt) keyWeight mod CK_ENC_VAR_RANGE;

    for keyWeighti := 0; 1 to Length(InString) do
    for i := 1 to lenSalt do keyWeightbegin
      key := keyWeight( + ord(Salt[(i]);
 mod lenSalt)  keyWeight := keyWeight+ 1]) mod CK_ENC_VAR_RANGE);

      Result := Result  for i := 1 to Length(InString) do+ CHAR(Byte(InString[i]) + key - keyWeight);
    beginend;
  end;
end;

function CKDecrypt(const InString:string;  key := ( ord(Salt[(i mod lenSalt) + 1]) mod CK_ENC_VAR_RANGE)Salt:string): string;
var
  i, lenSalt, key, keyWeight: Word;
  Target: string;
begin
  if Result(Salt := Result + CHAR(Byte(InString[i]) + key - keyWeight) '') then begin
    Target := InString;
  end else end;begin
     endlenSalt := Length(Salt);
end;

function CKDecrypt(const InString:string; Salt:string): string;
var
  i, lenSalt, key, keyWeight: Word;
  Target: string;
begin
  if (Salt = '') then begin
    Target := InString;
  end else begin
    lenSalt := Length(Salt);

    keyWeight := 0;
    for i := 1 to lenSalt do keyWeight := keyWeight + ord(Salt[i]);
    keyWeight := keyWeight mod CK_ENC_VAR_RANGE;

    Target := '';
    for i := 1 to Length(InString) do
    begin
      key := ( ord(Salt[(i mod lenSalt) + 1]) mod CK_ENC_VAR_RANGE);
      Target := Target + CHAR(Byte(InString[i]) - key + keyWeight);
    end;
    Result := TIdDecoderMIME.DecodeString(Target, IndyTextEncoding_UTF8);
  end;
end;

function CKReadPassword(sFileName:string):string;
var
  sFile: TFileStream;
  lenPWD, lenPWD_old: WORD;
  sEncryptedPWD: AnsiString;
  buff: PAnsiChar;
  tmp: AnsiString;
begin
  GetMem( buff, CK_MAX_MSG_LEN);
  ZeroMemory( buff, CK_MAX_MSG_LEN);

  if FileExists(sFileName) then begin
    lenPWD_old := 0;
    sFile := TFileStream.Create( sFileName, fmOpenRead);
    if sFile.Handle<>THandle(nil) then begin
    keyWeight := 0;
    for i := 1 to lenSalt do keyWeight := keyWeight + ord(Salt[i]);
    keyWeight := keyWeight mod CK_ENC_VAR_RANGE;

    Target := '';
    for i := 1 to Length(InString) do
    begin
      key := ( ord(Salt[(i mod lenSalt) + 1]) mod CK_ENC_VAR_RANGE);
      Target := Target + CHAR(Byte(InString[i]) - key + keyWeight);
    end;
    Result := TIdDecoderMIME.DecodeString(Target, IndyTextEncoding_UTF8);
  end;
end;

function CKReadPassword(sFileName:string):string;
var
  lenPWD: WORD;
  buff: PAnsiChar;
  tmp: AnsiString;
  sFile: TFileStream;
  sEncryptedPWD: AnsiString;
begin
  GetMem( buff, CK_MAX_MSG_LEN);
  ZeroMemory( buff, CK_MAX_MSG_LEN);

  if FileExists(sFileName) then begin
    sFile := TFileStream.Create( sFileName, fmOpenRead);
    if sFile.Handle<>THandle(nil) then begin
      sFile.Seek( -4, soFromEnd);
      sFile.Read( PAnsiChar(buff)^, 4);
      if buff=CK_SINGATURE then
      begin
        // has master key, so need to erase it
        sFile.Seek( -6, soFromEnd);
        sFile.Read( lenPwd, 2);
        sFile.Seek( -( -4lenPWD + 6), soFromEnd);
        sFile.Read( PAnsiCharPAnsIChar(buff)^, 4lenPWD);
      if buff=CK_SINGATURE then
      begin
        // has master key, so need to erase it
 tmp := ansiString(string(buff));
        tmp := sFile.SeekCKDecrypt( -6tmp, soFromEndCK_SINGATURE_KEY);
        sFile.Read( lenPwd, 2Result := Trim(tmp);
      end;
  sFile.Seek( -(lenPWD + 6), soFromEnd) sFile.Destroy;
    end;
  end;

  sFile.Read( PAnsIChar(buff)^, lenPWD);
        tmp := ansiString(string(buff));
        tmp := CKDecrypt( tmp, CK_SINGATURE_KEYFreeMem(buff);
end;

function CKUpdatePassword(sFileName, sPWD:String):Boolean;
var
  buff: PAnsiChar;
  sFile: TFileStream;
  lenPWD, lenPWD_old: WORD;
  sEncryptedPWD: AnsiString;
begin
  GetMem( buff, CK_MAX_MSG_LEN);
  ZeroMemory(      Result := Trim(tmp);
      end;buff, CK_MAX_MSG_LEN);

  if not FileExists(sFileName) then sFile.Destroy;begin
    end;
Result := endFalse;

  FreeMem(buff);
end;

function CKUpdatePassword(sFileName, sPWD:String):Boolean;
var
  sFile: TFileStream; else begin
  lenPWD,  lenPWD_old := WORD0;
  sEncryptedPWD: AnsiString;
 sFile buff: PAnsiChar;
begin
  GetMem= TFileStream.Create( buffsFileName, CK_MAX_MSG_LENfmOpenReadWrite);
  ZeroMemory( buff, CK_MAX_MSG_LEN);

  if not FileExists(sFileNamesFile.Handle<>THandle(nil) then begin
    Result := False  sFile.Seek( -4, soFromEnd);
  end else begin
  sFile.Read(  lenPWD_old := 0;
PAnsiChar(buff)^, 4);
      sFileif := TFileStream.Create( sFileName, fmOpenReadWrite);
 buff=CK_SINGATURE then
   if sFile.Handle<>THandle(nil) then begin
        // has sFile.Seek( -4, soFromEnd);
master key, so need to erase it
        sFile.ReadSeek( PAnsiChar(buff)^-6, 4soFromEnd);
        if buff=CK_SINGATURE thensFile.Read( lenPwd, 2);
      begin
  sFile.Seek( -(lenPWD + 6), soFromEnd);
  // has master key, so need to erase itlenPWD_old := lenPWD;
      end else sFile.Seek( -60, soFromEnd);

      while Length(sPWD)<lenPWD_old do sPWD := sPWD sFile.Read( lenPwd, 2)+ ' ';

      sEncryptedPWD := sFile.Seek( -(lenPWD + 6), soFromEndCKEncrypt(sPWD, CK_SINGATURE_KEY);
        lenPWD_old := lenPWDLength(sEncryptedPWD);
      endif else sFile.Seek( 0, soFromEnd);
(lenPWD>CK_MAX_MSG_LEN) then begin
      while Length(sPWD)<lenPWD_old do sPWD := sPWD + ' ';

 // too long message length
        sEncryptedPWDResult := CKEncrypt(sPWD, CK_SINGATURE_KEY)False;
      lenPWDend := Length(sEncryptedPWD);
else begin
        sFile.Write( PAnsiChar(sEncryptedPWD)^, lenPWD);
        sFile.Write( lenPWD, 2);
        sFile.Write( PAnsiChar(CK_SINGATURE)^, 4);
        Result := sFile.DestroyTrue;

      end;
    Result := TruesFile.Destroy;
    end else Result := False;
  end;

  FreeMem(buff);
end;

procedure Test;
begin
  CKUpdatePassword( "c:\foo.exe", "hello kitty");
  ShowMessage( CKReadPassword( "c:\foo.exe"));
end;