Delphi 7 -使用DEC加密,并使用PHP OpenSSL解密(第二部分)



请参考我之前的问题:Delphi 7 -使用DEC加密,并使用PHP OpenSSL解密

我的Delphi 7客户端应用程序(ICS组件)正在发送base64编码的数据作为HTTP POST请求的参数,到PHP web服务,在那里它正在用base64_decode函数解码。但是,PHP中解码的结果字符串与Delphi中最初编码的字符串不同。我使用的Delphi base64编码函数来自DEC (DEC v5.2)库。

从Delphi向PHP发送数据(并接收响应)的示例代码实现如下:

德尔福:

uses
OverbyteIcsHttpProt, OverbyteIcsLogger, OverbyteIcsWSocket, OverbyteIcsSslHttpRest, StrUtils,
DecFmt;

var
d: String;
StatCode: Integer;
sAPIResponse: WideString;
APIRespData: TAPIRespData;
begin
//
d := 'The quick brown fox jumps over the lazy rabbit..'; 
d := Encrypt(d); // Result string A
d := TFormat_MIME64.Encode(d); // Result string B
SslHttpRest1.RestParams.Clear;
SslHttpRest1.RestParams.AddItem('data', d);
StatCode := SslHttpRest1.RestRequest(httpPOST, strAPIUrl, False, '');
sAPIResponse := SslHttpRest1.ResponseRaw; // Result string C

Encrypt看起来像这样(代码来源:@AmigoJack):

const
GLUE = '::';
cPASSWORD = 'myownpassword';
function Encrypt(AStr: string): string;
var
c: TDecCipher; // Successfully tested with DEC 5.2 on Delphi 7
sKey, // The binary key we have to provide
sIv, // Initialization vector, should be random in the real world
sEncrypted, // Output of the encryption
sPlain: AnsiString; // What we want to encrypt, in binary
iPlus, // Input data padding
iLength: Integer; // Plaintext length source, in bytes
begin
// Keep in mind: Plain, Key and IV are all binary, not text!
sPlain := AStr;
sKey := cPASSWORD;
SetLength(sIv, 16);
RandomBuffer(sIv[1], 16);
// The cipher/algorithm depends on fixed block sizes, so it is automatically
// padded to the next full length. OpenSSL's padding byte is equal to the amount
// of bytes to be added: if 6 bytes need to be added, then 6 times #6 is added.
iLength := Length(sPlain);
iPlus := 16 - (iLength mod 16);
sPlain := sPlain + StringOfChar(Chr(iPlus), iPlus);
// Expect DEC 5.2 to only deal with AES-128-CBC, not 256.
c := ValidCipher(DecCipher.TCipher_Rijndael).Create;
try
c.Mode := cmCBCx;
c.Init(sKey, sIv); // Provide binary key and binary IV
SetLength(sEncrypted, Length(sPlain)); // Both are multiples of 16
c.Encode(sPlain[1], sEncrypted[1], Length(sPlain));
Result := TFormat_MIME64.Encode(sEncrypted) + GLUE + TFormat_MIME64.Encode(sIv) + GLUE + IntToStr(iLength);
finally
c.Free;
end;
end;

结果字符串A:

gS4S0kX9BfrhBYlsZ3MHS9RdgNuuEmKub39aim4/0eiRBPiaw1ykOGOqEk6cY3ol: AAjcM0WrUSlfbBR5EtcPSw = =: 48

结果字符串B:

a1FUTWtyVFlNVWc1UlREL2lEOXVPaTZUcmtDaHRiMUFLWU9DRVRxODUvQVNpZkJzMEs2Y2xxMU50VGZCNjdOYzo6Nmw3R1U3TFl0MDRwVkhjLzAwZDdKZz09Ojo0OA = =

结果字符串C:

B: a1FUTWtyVFlNVWc1UlREL2lEOXVPaTZUcmtDaHRiMUFLWU9DRVRxODUvQVNpZkJzMEs2Y2xxMU50VGZCNjdOYzo6Nmw3R1U3TFl0MDRwVkhjLzAwZDdKZz09Ojo0OA = =: kQTMkrTYMUg5RTD/iD9uOi6TrkChtb1AKYOCETq85/ASifBs0K6clq1NtTfB67Nc:: 6 l7gu7lyt04pvhc/00 d7jg = =: 48

PHP:

$data=$_POST['data'];          echo 'B:' . $data;
$data=base64_decode($data);    echo ' A:' . $data;

我期望String A等于String C (label A:)中返回的字符串,但它们不是。

我的意思是,这个bug与字符集编码的缺失有关,或者是DEC的TFormat_MIME64.Encode函数与PHP (PHP v7.4.7)base64_decode函数之间的不兼容。

任何帮助解决这个问题或指出我在正确的方向是感激的!

这不可能是真的- "结果字符串"不可能变成你说的那样。你确定你用的是DEC5.2而不是更旧的版本吗?

var
sAll, sAgain: AnsiString;
begin
sAll:= 'gS4S0kX9BfrhBYlsZ3MHS9RdgNuuEmKub39aim4/0eiRBPiaw1ykOGOqEk6cY3ol::AAjcM0WrUSlfbBR5EtcPSw==::48';
sAgain:= TFormat_MIME64.Encode( sAll );
if sAgain<> 'Z1M0UzBrWDlCZnJoQllsc1ozTUhTOVJkZ051dUVtS3ViMzlhaW00LzBlaVJCUGlhdzF5a09HT3FFazZjWTNvbDo6QUFqY00wV3JVU2xmYkJSNUV0Y1BTdz09Ojo0OA==' then Halt;

也是完全没有意义的编码你的ASCII字符串再次在Base64中——你只是把它膨胀得更大而没有任何好处。

最新更新