You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 11.1与XE5数据类型差异致Lockbox加密结果不一致问题

Delphi XE5迁移至Delphi 11.1后Lockbox加密结果不一致问题

我正在将Delphi XE5应用迁移至Delphi 11.1,使用相同版本的Lockbox组件时,得到的加密字符串却不一致。

调试发现调用链为:EncryptSymStr() → TCodec.EncryptString() → TSimpleCodec.EncryptString() → Stream_to_Base64(),在调用Stream_to_Base64()之前,所有中间内容均完全一致。

首次差异出现在Stream_to_Base64()函数内的ThreeBytes变量:

  • 在XE5中,ThreeBytes的值为:
    ThreeBytes [0] = 253
               [1] = 206
               [2] = 0
    
  • 在Delphi 11中,ThreeBytes的值为:
    ThreeBytes [0] = 105
               [1] = 155
               [2] = 1
    

由于两个环境使用的Lockbox版本相同,推测问题源于XE5到11.1之间的数据类型差异。相关代码如下:

var
oCodeRDL:   TCodec;

cmdstr := '...---... ETS4162735 BUBBA '; 
cmdStr := EncryptSymStr(cmdStr);

function EncryptSymStr(Value: string): string;
var
   CipherText: ansistring;
begin
   if AllowEncryption then
   begin
      oCodeRDL.EncryptString(Value, CipherText);
      Result := CipherText;
   end
   else
      Result := Value;      
end;

procedure TCodec.EncryptString(
  const Plaintext: string; var CipherText_Base64: ansistring);
begin
InterfacesAreCached := True;
BeginEncDec;
FCodec.EncryptString( Plaintext, CipherText_Base64);
EndEncDec
end;

procedure TSimpleCodec.EncryptString(
  const Plaintext: string;
  var CipherText_Base64: ansistring);
var
  Temp: TMemoryStream;
  L: integer;
begin
Temp := TMemoryStream.Create;
try
  Begin_EncryptMemory( Temp);
  L := Length( Plaintext) * SizeOf( Char);
  if L > 0 then
    EncryptMemory( Plaintext[1], L);
  End_EncryptMemory;
  if FisUserAborted then
      CipherText_Base64 := ''
    else
      begin
      Temp.Position := 0;
      if isNotBase64Converter then
          CipherText_Base64 := Stream_to_Base64( Temp)
        else
          // If its already a Base64 encoder, no point in double-encoding it as base64.
          CipherText_Base64 := Stream_to_AnsiString( Temp)
      end
finally
  Temp.Free
end;

function  Stream_to_Base64( Source: TStream): ansistring;
var
  ThreeBytes: packed array[ 0..2 ] of byte;
  BytesRead: integer;
  P, j, i: integer;

begin
SetLength( result, (Source.Size + 2) div 3 * 4);
Source.Position := 0;
P := 1;
repeat
  BytesRead := Source.Read( ThreeBytes, 3);
  if BytesRead = 0 then break;
  for j := BytesRead to 2 do
    ThreeBytes[j] := 0;
  for j := 0 to BytesRead do
    begin
    result[ P ] := Base64Chars[ ( ThreeBytes[0] shr 2) + 1];
    Inc( P);
    for i := 0 to 1 do
      ThreeBytes[i] := (ThreeBytes[i] shl 6) + (ThreeBytes[i+1] shr 2);
    ThreeBytes[ 2] := ThreeBytes[ 2] shl 6
    end
until BytesRead < 3;
if BytesRead > 0 then
  for j := BytesRead to 2 do
    begin
    result[ P] := '=';
    Inc( P)
    end
end;

内容的提问来源于stack exchange,提问作者David Kroll

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 14:01:05