Delphi:简单字符串加密
我有一个字符串-主板的序列号(只有数字和字母)。如何加密/解密它,并有一个正常的看法:字母只从a到Z和数字从0到9。用户必须向我发送字符串,我必须响应 我可以加密,但不能使用可读字符Delphi:简单字符串加密,delphi,encryption,Delphi,Encryption,我有一个字符串-主板的序列号(只有数字和字母)。如何加密/解密它,并有一个正常的看法:字母只从a到Z和数字从0到9。用户必须向我发送字符串,我必须响应 我可以加密,但不能使用可读字符 谢谢 这是一个众所周知的例子: 除A..Z、A..Z、0..9以外的任何字符都将保持不变。最好的方法是加密字符串,然后对其进行编码 检查此示例,它使用库对字符串进行加密,并使用Indy在base64中进行编码和解码 {$APPTYPE CONSOLE} uses ExceptionLog, Classes
谢谢 这是一个众所周知的例子:
除A..Z、A..Z、0..9以外的任何字符都将保持不变。最好的方法是加密字符串,然后对其进行编码 检查此示例,它使用库对字符串进行加密,并使用Indy在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.
支持Unicode的简单Enc/Dec,Enc输出仅为十六进制字符:
const CKEY1 = 53761;
CKEY2 = 32618;
function EncryptStr(const S :WideString; Key: Word): String;
var i :Integer;
RStr :RawByteString;
RStrB :TBytes Absolute RStr;
begin
Result:= '';
RStr:= UTF8Encode(S);
for i := 0 to Length(RStr)-1 do begin
RStrB[i] := RStrB[i] xor (Key shr 8);
Key := (RStrB[i] + Key) * CKEY1 + CKEY2;
end;
for i := 0 to Length(RStr)-1 do begin
Result:= Result + IntToHex(RStrB[i], 2);
end;
end;
function DecryptStr(const S: String; Key: Word): String;
var i, tmpKey :Integer;
RStr :RawByteString;
RStrB :TBytes Absolute RStr;
tmpStr :string;
begin
tmpStr:= UpperCase(S);
SetLength(RStr, Length(tmpStr) div 2);
i:= 1;
try
while (i < Length(tmpStr)) do begin
RStrB[i div 2]:= StrToInt('$' + tmpStr[i] + tmpStr[i+1]);
Inc(i, 2);
end;
except
Result:= '';
Exit;
end;
for i := 0 to Length(RStr)-1 do begin
tmpKey:= RStrB[i];
RStrB[i] := RStrB[i] xor (Key shr 8);
Key := (tmpKey + Key) * CKEY1 + CKEY2;
end;
Result:= UTF8Decode(RStr);
end;
我使用的这个非常简单的技巧非常简单: 我使用它在数据库中存储非关键加密密码。我的目标是设置一层模糊处理(并最大限度地减少解密所需的计算),而不是进行严格的加密,例如,对于管理员密码,我使用AES:
// this function both encryptes and decryptes
// EnDecrypt(EnDeCrypt(astring)) = astring
function EnDeCrypt(const Value : String) : String;
var
CharIndex : integer;
begin
Result := Value;
for CharIndex := 1 to Length(Value) do
Result[CharIndex] := chr(not(ord(Value[CharIndex])));
end;
请澄清你的问题。看起来您正在询问一个加密方案,该方案将为您留下一个人类可查看的“ASCII”字符串。如果是这样,那么使用任何ol'加密方案,但Base64编码字符串。对!!!我需要一条人眼可见的线谢谢你!!!但是每个人都知道Base64。它具有“=”-易于识别和解码。这并不重要,因为字符串是加密的。如果有人解码base64字符串,则会有一个加密字符串。@maxfax,请检查我更新的代码,添加使用示例和小修改,以支持旧(非unicode)版本的delphi。嘿,如果=困扰您,请将其删除,然后在解码时重新添加。没关系,加密才是安全的。Base64只是为了满足人类可读的需求。代码不错,但它使用了30MB的库。为什么所有绝地库都是文件和依赖项的纠缠。这不是有点太简单吗?@Allforfree它显然是简单的模糊处理,而不是加密。用AES来做更强壮的东西。但您需要使用一个经过验证的库。例如,有关符号加密和密钥的不对称计算,请参见。为什么在一个函数中“s”参数声明为字符串,而在另一个函数中声明为宽字符串???为什么在decryptstr中使用try/EXCEPT?代码有一个警告:W1000符号“UTF8Decode”已弃用:“使用UTF8ToWideString或UTF8ToString”我在EncryptStr中收到RangeCheckError。可能这就是您使用Try/Except的原因。隐藏RangeCheckErrors。抱歉。你的代码很糟糕。我不知道你是怎么得到这么多选票的!
procedure TForm1.btn1Click(Sender: TObject);
begin
txt2.Text:= EncryptStr(txt1.Text, 223);
lbl1.Caption:= DecryptStr(txt2.Text, 223);
end;
// this function both encryptes and decryptes
// EnDecrypt(EnDeCrypt(astring)) = astring
function EnDeCrypt(const Value : String) : String;
var
CharIndex : integer;
begin
Result := Value;
for CharIndex := 1 to Length(Value) do
Result[CharIndex] := chr(not(ord(Value[CharIndex])));
end;