Delphi: simple string encryption

后端 未结 4 733
伪装坚强ぢ
伪装坚强ぢ 2020-12-14 23:23

I have a string - a serial number of a mother board (only numbers and letters). How to encrypt/decrypt it and have a normal view: letters only from A to Z and numbers from 0

4条回答
  •  一向
    一向 (楼主)
    2020-12-15 00:06

    The best way is encrypt and then encode the string.

    Check this sample which uses the JWSCL library to encrypt a string and Indy to encode and decode in base64.

    {$APPTYPE CONSOLE}
    
    uses
      ExceptionLog,
      Classes,
      JwaWinType,
      JwaWinCrypt,
      IdCoderMIME,
      SysUtils;
    
    function CryptString(Const  Input: string; password : AnsiString;  Encrypt: Boolean) : string;
    const
      BufferSize=1024*1024;
    var
      StreamSource  : TStringStream;
      StreamDest    : TStringStream;
      CRYPTPROV     : HCRYPTPROV;
      CRYPTHASH     : HCRYPTHASH;
      CRYPTKEY      : HCRYPTKEY;
      Buffer        : LPBYTE;
      BytesIn       : DWORD;
      Final         : Boolean;
    
      Encoder     : TIdEncoderMIME;
      Decoder     : TIdDecoderMIME;
      DestStream  : TStringStream;
    begin
      CryptAcquireContext(CRYPTPROV, nil, nil, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT);
      try
          //create a valid key  based in the password
          if not CryptCreateHash(CRYPTPROV, CALG_SHA1, 0, 0, CRYPTHASH) then RaiseLastOSError;
          try
            if not CryptHashData(CRYPTHASH, @Password[1], Length(Password), 0) then RaiseLastOSError;
            if not CryptDeriveKey(CRYPTPROV,  CALG_RC4, CRYPTHASH, 0, CRYPTKEY)  then RaiseLastOSError;
          finally
            CryptDestroyHash(CRYPTHASH);
          end;
    
          StreamSource := TStringStream.Create(Input);
          StreamSource.Position:=0;
          StreamDest   := TStringStream.Create;
          try
            GetMem(Buffer, BufferSize);
            try
    
              if not Encrypt then
              begin
                //decode the string using base64
                Decoder := TIdDecoderMIME.Create(nil);
                try
                  DestStream := TStringStream.Create;
                  try
                    StreamDest.Position:=0;
                    Decoder.DecodeBegin(DestStream);
                    Decoder.Decode(StreamSource);
                    Decoder.DecodeEnd;
                    StreamSource.Clear;
                    DestStream.Position:=0;
                    StreamSource.CopyFrom(DestStream,DestStream.Size);
                    StreamSource.Position:=0;
                  finally
                    DestStream.Free;
                  end;
                finally
                  Decoder.Free;
                end;
    
              end;
    
    
                repeat
                  BytesIn   := StreamSource.Read(Buffer^, BufferSize);
                  Final     := (StreamSource.Position >= StreamSource.Size);
                  if Encrypt then
                  begin
                   if not CryptEncrypt(CRYPTKEY, 0, Final, 0, Buffer, BytesIn, BytesIn) then RaiseLastOSError;
                  end
                  else
                  if not CryptDecrypt(CRYPTKEY, 0, Final, 0, Buffer, BytesIn) then RaiseLastOSError;
    
                  StreamDest.Write(Buffer^, BytesIn);
                until Final;
    
    
              //encode the string using base64
              if Encrypt then
              begin
                Encoder := TIdEncoderMIME.Create(nil);
                try
                  DestStream:=TStringStream.Create;
                  try
                    StreamDest.Position:=0;
                    Encoder.Encode(StreamDest,DestStream);
                    Result := DestStream.DataString;
                  finally
                    DestStream.Free;
                  end;
                finally
                  Encoder.Free;
                end;
              end
              else
              Result:= StreamDest.DataString;
    
    
            finally
             FreeMem(Buffer, BufferSize);
            end;
    
          finally
            StreamSource.Free;
            StreamDest.Free;
          end;
      finally
        CryptReleaseContext(CRYPTPROV, 0);
      end;
    end;
    
    
    var 
       plaintext : string; 
       Encrypted : string;
    begin
      try
        plaintext:='this is a plain text'; Writeln('Plain Text '+plaintext);
        Encrypted:=CryptString(plaintext,'...ThiS Is A PaSsWord...',True);
        Writeln('Encrypted/Encoded string '+Encrypted);
        plaintext:=CryptString(Encrypted,'...ThiS Is A PaSsWord...',False);
        Writeln('Original string '+plaintext);
      except
          on E: Exception do
            Writeln(E.ClassName, ': ', E.Message);
      end;
      Readln;
    end.
    

提交回复
热议问题