【问题标题】:Encrypt and decrypt a Unicode string加密和解密 Unicode 字符串
【发布时间】:2014-10-13 08:19:40
【问题描述】:

谁能给我在delphi firemonkey Mobile中加密和解密Unicode字符串的代码? 我已经用 xor 和其他库尝试了所有东西,但什么也没有。 总是有一些字符不能被识别为欧元符号 € 。 如果有人可以帮助我,将不胜感激。

编辑: 谢谢汉斯,但我总是对 stringstream 有同样的问题。此代码在 windows 中完美运行,但 ios 给我这个错误:“目标多字节代码页中不存在 Unicode 字符的映射”

unit UMain;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, ElAES,
  FMX.StdCtrls, FMX.Layouts, FMX.Memo, Math;

type
  TForm2 = class(TForm)
    ToolBar1: TToolBar;
    Label1: TLabel;
    Label2: TLabel;
    Memo1: TMemo;
    Layout1: TLayout;
    Button1: TButton;
    Button3: TButton;
    procedure Button1Click(Sender: TObject);
    procedure Button3Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
const
  PASSWORD = '1234';
var
  Form2: TForm2;

implementation

{$R *.fmx}
{$R *.iPhone.fmx IOS}
function StringToHex(S: string): string;
var
    i: integer;

begin
  Result := '';

  // Go throught every single characters, and convert them
  // to hexadecimal...
    for i := 1 to Length( S ) do
    Result := Result + IntToHex( Ord( S[i] ), 2 );
end;

function HexToString(S: string): string;
var
    i: integer;

begin
  Result := '';

  // Go throught every single hexadecimal characters, and convert
  // them to ASCII characters...
  for i := 1 to Length( S ) do
  begin
    // Only process chunk of 2 digit Hexadecimal...
    if ((i mod 2) = 1) then
        Result := Result + Chr( StrToInt( '0x' + Copy( S, i, 2 )));
  end;
end;


procedure TForm2.Button1Click(Sender: TObject);
var
  Source: TStringStream;
  Dest: TStringStream;
  Key: TAESKey128;
begin
try

  Source := TStringStream.Create( Memo1.Text );
  Dest   := TStringStream.Create('');
  FillChar( Key, SizeOf(Key), 0 );
  Move( PChar(PASSWORD)^, Key, Min( SizeOf( Key ), Length( PASSWORD )));
  EncryptAESStreamECB( Source, 0, Key, Dest );
  //Memo1.Lines.BeginUpdate;
  Memo1.Text := Dest.DataString;
  //Memo1.Lines.EndUpdate;
  Label2.Text := 'Texto Encriptado';
  Source.Free;
  Dest.Free;
except on E: Exception do
  begin
    ShowMessage(e.ToString);
    Source.Free;
    Dest.Free;
    Memo1.Text :='';
  end;
end;

end;


procedure TForm2.Button3Click(Sender: TObject);
var
  Source: TStringStream;
  Dest: TStringStream;
  Key: TAESKey128;
  Size: integer;
begin
try
  Source := TStringStream.Create(Trim(Memo1.Text) );
  Dest   := TStringStream.Create('');
  Size := Source.Size;
  Source.ReadBuffer(Size, SizeOf(Size));
  FillChar(Key, SizeOf(Key), 0);
  Move(PChar(PASSWORD)^, Key, Min(SizeOf(Key), Length(PASSWORD)));
  Source.Position := 0;
  DecryptAESStreamECB(Source, Source.Size - Source.Position, Key, Dest);
  Memo1.Text := Trim(Dest.DataString);
  Label2.Text := 'Texto Original';
  Source.Free;
  Dest.Free;
except on E: Exception do
  begin
    ShowMessage(e.ToString);
    Source.Free;
    Dest.Free;
    Memo1.Text :='';
  end;
end;

end;

end.

我也试过用这个来创建字符串流:

Source := TStringStream.Create(Trim(Memo1.Text) , TEncoding.Unicode) ;

有时效果很好,有时会给我以下错误:“Los surrogate char without a prior high surrogate char at index: 8. 检查字符串是否正确编码。 有什么想法吗?

【问题讨论】:

  • 您不加密/解密字符串。加密对二进制数据进行操作。您需要决定如何对文本进行编码,然后决定使用何种加密算法。只有你可以决定。
  • 解密后的部分知道什么样的数据被加密了是非常重要的。字符串还具有您需要知道的编码(ANSI、UTF8、UTF16...),以便从字节汤中获取预期信息。图像也是如此。您需要知道它是图像类型(BMP、JPG、TIFF、...)
  • 这个问题似乎离题了,因为 stackoverflow 不是“给我代码”网站。
  • 如上所述,您正在搞乱编码和加密。您似乎不知道系统中使用的编码。 FWIW 你得到的关于代理的错误是因为你的系统需要 UTF-16(主要用于 Windows)。
  • 您的编辑表明您并不真正了解这里的基本概念。我建议您需要进行一些背景研究,以明确了解 Delphi 中如何处理 Unicode。

标签: delphi encryption cryptography firemonkey delphi-xe7


【解决方案1】:

使用标准化库,而不是尝试制作自己的加密解决方案。例如,Delphi 有几种可用的 AES 加密实现(例如Eldos which is included in the NativeXML library)。 将您的字符串 (MyString) 写入流并对其进行加密:

var
  lSourceStream: TStringStream;
  lDestinationStream: TMemoryStream;
begin
  lSourceStream := TStringStream.Create(MyString);
  lDestinationStream := TMemoryStream.Create;
  AESencrypt(lSourceStream,lDestinationStream);
  lDestinationStream.SaveToFile(<filename>);
end;

【讨论】:

  • 另一个有趣的问题,这里使用了什么加密密钥和操作模式?
  • @DavidHeffernan:它使用默认编码,但要确保使用 Unicode,请添加一个参数:TStringStream.Create(MyString, TEncoding.UniCode)。
  • @user246408:我没有进入 AES 例程,因为它们的实现方式不同,但是您当然必须设置一个加密密钥(例如 128 位),它可能是一个参数或一个属性在 AES 类中。
  • 指定 UTF-8 不是更好吗?按照您的建议使用 ANSI 是个坏主意。
  • @DavidHeffernan 你在哪里看到 ANSI?
猜你喜欢
  • 2012-07-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多