Delphi:简单的字符串加密 [英] Delphi: simple string encryption

查看:201
本文介绍了Delphi:简单的字符串加密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个字符串 - 母板的序列号(只有数字和字母)。如何加密/解密,并具有正常的视图:字母只能从A到Z,数字从0到9.用户必须向我发送字符串,我必须回复。



我可以加密,但不可读的字符。



谢谢!

解决方案



检查这个使用 JWSCL 加密一个字符串和Indy在base64中进行编码和解码。

  {$ APPTYPE CONSOLE} 

使用
ExceptionLog,
类,
JwaWinType,
JwaWinCrypt,
IdCoderMIME,
SysUtils;

函数CryptString(Const Input:string; password:AnsiString; Encrypt:Boolean):string;
const
BufferSize = 1024 * 1024;
var
StreamSource:TStringStream;
StreamDest:TStringStream;
CRYPTPROV:HCRYPTPROV;
CRYPTHASH:HCRYPTHASH;
CRYPTKEY:HCRYPTKEY;
缓冲区:LPBYTE;
BytesIn:DWORD;
Final:Boolean;

编码器:TIdEncoderMIME;
解码器:TIdDecoderMIME;
DestStream:TStringStream;
begin
CryptAcquireContext(CRYPTPROV,nil,nil,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT);
try
//根据密码创建一个有效的密钥
如果不是CryptCreateHash(CRYPTPROV,CALG_SHA1,0,0,CRYPTHASH),则RaiseLastOSError;
尝试
如果不是CryptHashData(CRYPTHASH,@Password [1],Length(Password),0)then RaiseLastOSError;
如果不是CryptDeriveKey(CRYPTPROV,CALG_RC4,CRYPTHASH,0,CRYPTKEY),那么RaiseLastOSError;
finally
CryptDestroyHash(CRYPTHASH);
结束

StreamSource:= TStringStream.Create(Input);
StreamSource.Position:= 0;
StreamDest:= TStringStream.Create;
try
GetMem(Buffer,BufferSize);
尝试

如果没有加密然后
begin
//使用base64解码字符串
解码器:= 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;
结束
finally
Decoder.Free;
结束

end;


重复
BytesIn:= StreamSource.Read(Buffer ^,BufferSize);
Final:=(StreamSource.Position> = StreamSource.Size);
如果加密
begin
如果不是CryptEncrypt(CRYPTKEY,0,Final,0,Buffer,BytesIn,BytesIn),那么RaiseLastOSError;
end
else
如果不是CryptDecrypt(CRYPTKEY,0,Final,0,Buffer,BytesIn),那么RaiseLastOSError;

StreamDest.Write(Buffer ^,BytesIn);
until Final;


//使用base64
编码字符串如果加密然后
begin
编码器:= TIdEncoderMIME.Create(nil);
try
DestStream:= TStringStream.Create;
try
StreamDest.Position:= 0;
Encoder.Encode(StreamDest,DestStream);
结果:= DestStream.DataString;
finally
DestStream.Free;
结束
finally
Encoder.Free;
结束
end
else
结果:= StreamDest.DataString;


finally
FreeMem(Buffer,BufferSize);
结束

finally
StreamSource.Free;
StreamDest.Free;
结束
finally
CryptReleaseContext(CRYPTPROV,0);
结束
结束


var
plaintext:string;
加密:string;
begin
try
plaintext:='这是一个纯文本'; Writeln('Plain Text'+ plaintext);
加密:= CryptString(明文,'... ThiS是一个PaSsWord ...',True);
Writeln('Encrypted / Encoded string'+ Encrypted);
plaintext:= CryptString(加密,'... ThiS是PaSsWord ...',False);
Writeln('Original string'+ plaintext);
除了
在E:Exception do
Writeln(E.ClassName,':',E.Message);
结束
Readln;
结束。


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 to 9. A user must send me the string, I must response.

I can encrypt but with not readable characters.

Thanks!

解决方案

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.

这篇关于Delphi:简单的字符串加密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆