Delphi Firemonkey LockBox3 AES-CBC, PC and Android result are different?












-1















I need a AES library for devolop Firemonkey Moblie App. I tested ElAES and LockBox3, everything works fine complie to PC, But on FMX Android both library return wrong ciphertext.



Test Data (AES128CBC PKCS5Padding):



plainText: 'plainText'  - edtPlaintext.Text
key: '0000000000000000' - edtKey.Text
IV: '0000000000000000' - edtIV.Text
cipherText: hex - 'DD0A2A20616162697B8B4DF53483F1D2',
base64 - '3QoqIGFhYml7i031NIPx0g=='


Test Code:



This is test code reley on LockBox3, related: https://github.com/TurboPack/LockBox3, function 'EncryptMemory' return unfixed ciphertext each time on Android, something need to notice?



uses uTPLb_Codec, uTPLb_CryptographicLibrary, uTPLb_Constants, uTPLb_StreamUtils;

type
TCustomPadder = class(TObject)
private
FIV: TBytes;
public
constructor Create(const AIV: TBytes);
procedure OnSetIV(Value: TMemoryStream);
end;

constructor TCustomPadder.Create(const AIV: TBytes);
begin
FIV := AIV
end;

procedure TCustomPadder.OnSetIV(Value: TMemoryStream);
begin
Value.Size := Length(FIV);
Value.Position := 0;
Value.WriteBuffer(FIV, Length(FIV))
end;

function NewCodec(key: TBytes): TCodec;
var
codec: TCodec;
cryptographicLibrary: TCryptographicLibrary;
keyStream: TStream;
padder: TCustomPadder;
begin
cryptographicLibrary := TCryptographicLibrary.Create(nil);
// basic
codec := TCodec.Create(nil);
codec.BlockCipherId := Format(AES_ProgId, [128]);
codec.ChainModeId := CBC_ProgId;
codec.CryptoLibrary := cryptographicLibrary;
codec.StreamCipherId := BlockCipher_ProgId;
// extend
padder := TCustomPadder.Create(bytesof('0000000000000000'));
keyStream := TMemoryStream.Create;
keyStream.WriteBuffer(key, Length(key));
keyStream.Position := 0;
codec.OnSetIV := padder.OnSetIV;
codec.InitFromStream(keyStream);
result := codec;
end;

function PKCS5Padding(ciphertext: string; blocksize: integer): string;
var
builder: TStringBuilder;
padding: integer;
i: integer;
begin
builder := TStringBuilder.Create(ciphertext);
padding := blocksize - (builder.Length mod blocksize);
for i := 1 to padding do
begin
builder.Append(Char(padding));
end;
result := builder.ToString;
builder.DisposeOf;
end;

function BytesToHexStr(bytes: TBytes): string;
var
i: integer;
begin
result := '';
for i := 0 to Length(bytes) - 1 do
result := result + bytes[i].ToHexString(2);
end;

procedure TformAEST.btnEncryptClick(Sender: TObject);
var
codec: TCodec;
plainBytes, cipherBytes: TBytes;
cipherMemory: TStream;
cipherBytesLen: integer;
begin

cipherMemory := TMemoryStream.Create;

plainBytes := bytesof(PKCS5Padding(edtPlaintext.Text, 16));

codec := NewCodec(bytesof(edtKey.Text));
codec.Begin_EncryptMemory(cipherMemory);
codec.EncryptMemory(plainBytes, Length(plainBytes));
codec.End_EncryptMemory;

cipherMemory.Position := 8;
cipherBytesLen := cipherMemory.Size - 8;
SetLength(cipherBytes, cipherBytesLen);
cipherMemory.ReadBuffer(cipherBytes, cipherBytesLen);
edtCiphertext.Text := BytesToHexStr(cipherBytes);
end;









share|improve this question























  • Consider accepting answers that are helpful and reviewing previous answers an accepting is appropriate. 1, See reputation faq Voting up a question or answer signals to the rest of the community that a post is interesting, well-researched, and useful.

    – zaph
    Jan 1 at 18:04
















-1















I need a AES library for devolop Firemonkey Moblie App. I tested ElAES and LockBox3, everything works fine complie to PC, But on FMX Android both library return wrong ciphertext.



Test Data (AES128CBC PKCS5Padding):



plainText: 'plainText'  - edtPlaintext.Text
key: '0000000000000000' - edtKey.Text
IV: '0000000000000000' - edtIV.Text
cipherText: hex - 'DD0A2A20616162697B8B4DF53483F1D2',
base64 - '3QoqIGFhYml7i031NIPx0g=='


Test Code:



This is test code reley on LockBox3, related: https://github.com/TurboPack/LockBox3, function 'EncryptMemory' return unfixed ciphertext each time on Android, something need to notice?



uses uTPLb_Codec, uTPLb_CryptographicLibrary, uTPLb_Constants, uTPLb_StreamUtils;

type
TCustomPadder = class(TObject)
private
FIV: TBytes;
public
constructor Create(const AIV: TBytes);
procedure OnSetIV(Value: TMemoryStream);
end;

constructor TCustomPadder.Create(const AIV: TBytes);
begin
FIV := AIV
end;

procedure TCustomPadder.OnSetIV(Value: TMemoryStream);
begin
Value.Size := Length(FIV);
Value.Position := 0;
Value.WriteBuffer(FIV, Length(FIV))
end;

function NewCodec(key: TBytes): TCodec;
var
codec: TCodec;
cryptographicLibrary: TCryptographicLibrary;
keyStream: TStream;
padder: TCustomPadder;
begin
cryptographicLibrary := TCryptographicLibrary.Create(nil);
// basic
codec := TCodec.Create(nil);
codec.BlockCipherId := Format(AES_ProgId, [128]);
codec.ChainModeId := CBC_ProgId;
codec.CryptoLibrary := cryptographicLibrary;
codec.StreamCipherId := BlockCipher_ProgId;
// extend
padder := TCustomPadder.Create(bytesof('0000000000000000'));
keyStream := TMemoryStream.Create;
keyStream.WriteBuffer(key, Length(key));
keyStream.Position := 0;
codec.OnSetIV := padder.OnSetIV;
codec.InitFromStream(keyStream);
result := codec;
end;

function PKCS5Padding(ciphertext: string; blocksize: integer): string;
var
builder: TStringBuilder;
padding: integer;
i: integer;
begin
builder := TStringBuilder.Create(ciphertext);
padding := blocksize - (builder.Length mod blocksize);
for i := 1 to padding do
begin
builder.Append(Char(padding));
end;
result := builder.ToString;
builder.DisposeOf;
end;

function BytesToHexStr(bytes: TBytes): string;
var
i: integer;
begin
result := '';
for i := 0 to Length(bytes) - 1 do
result := result + bytes[i].ToHexString(2);
end;

procedure TformAEST.btnEncryptClick(Sender: TObject);
var
codec: TCodec;
plainBytes, cipherBytes: TBytes;
cipherMemory: TStream;
cipherBytesLen: integer;
begin

cipherMemory := TMemoryStream.Create;

plainBytes := bytesof(PKCS5Padding(edtPlaintext.Text, 16));

codec := NewCodec(bytesof(edtKey.Text));
codec.Begin_EncryptMemory(cipherMemory);
codec.EncryptMemory(plainBytes, Length(plainBytes));
codec.End_EncryptMemory;

cipherMemory.Position := 8;
cipherBytesLen := cipherMemory.Size - 8;
SetLength(cipherBytes, cipherBytesLen);
cipherMemory.ReadBuffer(cipherBytes, cipherBytesLen);
edtCiphertext.Text := BytesToHexStr(cipherBytes);
end;









share|improve this question























  • Consider accepting answers that are helpful and reviewing previous answers an accepting is appropriate. 1, See reputation faq Voting up a question or answer signals to the rest of the community that a post is interesting, well-researched, and useful.

    – zaph
    Jan 1 at 18:04














-1












-1








-1








I need a AES library for devolop Firemonkey Moblie App. I tested ElAES and LockBox3, everything works fine complie to PC, But on FMX Android both library return wrong ciphertext.



Test Data (AES128CBC PKCS5Padding):



plainText: 'plainText'  - edtPlaintext.Text
key: '0000000000000000' - edtKey.Text
IV: '0000000000000000' - edtIV.Text
cipherText: hex - 'DD0A2A20616162697B8B4DF53483F1D2',
base64 - '3QoqIGFhYml7i031NIPx0g=='


Test Code:



This is test code reley on LockBox3, related: https://github.com/TurboPack/LockBox3, function 'EncryptMemory' return unfixed ciphertext each time on Android, something need to notice?



uses uTPLb_Codec, uTPLb_CryptographicLibrary, uTPLb_Constants, uTPLb_StreamUtils;

type
TCustomPadder = class(TObject)
private
FIV: TBytes;
public
constructor Create(const AIV: TBytes);
procedure OnSetIV(Value: TMemoryStream);
end;

constructor TCustomPadder.Create(const AIV: TBytes);
begin
FIV := AIV
end;

procedure TCustomPadder.OnSetIV(Value: TMemoryStream);
begin
Value.Size := Length(FIV);
Value.Position := 0;
Value.WriteBuffer(FIV, Length(FIV))
end;

function NewCodec(key: TBytes): TCodec;
var
codec: TCodec;
cryptographicLibrary: TCryptographicLibrary;
keyStream: TStream;
padder: TCustomPadder;
begin
cryptographicLibrary := TCryptographicLibrary.Create(nil);
// basic
codec := TCodec.Create(nil);
codec.BlockCipherId := Format(AES_ProgId, [128]);
codec.ChainModeId := CBC_ProgId;
codec.CryptoLibrary := cryptographicLibrary;
codec.StreamCipherId := BlockCipher_ProgId;
// extend
padder := TCustomPadder.Create(bytesof('0000000000000000'));
keyStream := TMemoryStream.Create;
keyStream.WriteBuffer(key, Length(key));
keyStream.Position := 0;
codec.OnSetIV := padder.OnSetIV;
codec.InitFromStream(keyStream);
result := codec;
end;

function PKCS5Padding(ciphertext: string; blocksize: integer): string;
var
builder: TStringBuilder;
padding: integer;
i: integer;
begin
builder := TStringBuilder.Create(ciphertext);
padding := blocksize - (builder.Length mod blocksize);
for i := 1 to padding do
begin
builder.Append(Char(padding));
end;
result := builder.ToString;
builder.DisposeOf;
end;

function BytesToHexStr(bytes: TBytes): string;
var
i: integer;
begin
result := '';
for i := 0 to Length(bytes) - 1 do
result := result + bytes[i].ToHexString(2);
end;

procedure TformAEST.btnEncryptClick(Sender: TObject);
var
codec: TCodec;
plainBytes, cipherBytes: TBytes;
cipherMemory: TStream;
cipherBytesLen: integer;
begin

cipherMemory := TMemoryStream.Create;

plainBytes := bytesof(PKCS5Padding(edtPlaintext.Text, 16));

codec := NewCodec(bytesof(edtKey.Text));
codec.Begin_EncryptMemory(cipherMemory);
codec.EncryptMemory(plainBytes, Length(plainBytes));
codec.End_EncryptMemory;

cipherMemory.Position := 8;
cipherBytesLen := cipherMemory.Size - 8;
SetLength(cipherBytes, cipherBytesLen);
cipherMemory.ReadBuffer(cipherBytes, cipherBytesLen);
edtCiphertext.Text := BytesToHexStr(cipherBytes);
end;









share|improve this question














I need a AES library for devolop Firemonkey Moblie App. I tested ElAES and LockBox3, everything works fine complie to PC, But on FMX Android both library return wrong ciphertext.



Test Data (AES128CBC PKCS5Padding):



plainText: 'plainText'  - edtPlaintext.Text
key: '0000000000000000' - edtKey.Text
IV: '0000000000000000' - edtIV.Text
cipherText: hex - 'DD0A2A20616162697B8B4DF53483F1D2',
base64 - '3QoqIGFhYml7i031NIPx0g=='


Test Code:



This is test code reley on LockBox3, related: https://github.com/TurboPack/LockBox3, function 'EncryptMemory' return unfixed ciphertext each time on Android, something need to notice?



uses uTPLb_Codec, uTPLb_CryptographicLibrary, uTPLb_Constants, uTPLb_StreamUtils;

type
TCustomPadder = class(TObject)
private
FIV: TBytes;
public
constructor Create(const AIV: TBytes);
procedure OnSetIV(Value: TMemoryStream);
end;

constructor TCustomPadder.Create(const AIV: TBytes);
begin
FIV := AIV
end;

procedure TCustomPadder.OnSetIV(Value: TMemoryStream);
begin
Value.Size := Length(FIV);
Value.Position := 0;
Value.WriteBuffer(FIV, Length(FIV))
end;

function NewCodec(key: TBytes): TCodec;
var
codec: TCodec;
cryptographicLibrary: TCryptographicLibrary;
keyStream: TStream;
padder: TCustomPadder;
begin
cryptographicLibrary := TCryptographicLibrary.Create(nil);
// basic
codec := TCodec.Create(nil);
codec.BlockCipherId := Format(AES_ProgId, [128]);
codec.ChainModeId := CBC_ProgId;
codec.CryptoLibrary := cryptographicLibrary;
codec.StreamCipherId := BlockCipher_ProgId;
// extend
padder := TCustomPadder.Create(bytesof('0000000000000000'));
keyStream := TMemoryStream.Create;
keyStream.WriteBuffer(key, Length(key));
keyStream.Position := 0;
codec.OnSetIV := padder.OnSetIV;
codec.InitFromStream(keyStream);
result := codec;
end;

function PKCS5Padding(ciphertext: string; blocksize: integer): string;
var
builder: TStringBuilder;
padding: integer;
i: integer;
begin
builder := TStringBuilder.Create(ciphertext);
padding := blocksize - (builder.Length mod blocksize);
for i := 1 to padding do
begin
builder.Append(Char(padding));
end;
result := builder.ToString;
builder.DisposeOf;
end;

function BytesToHexStr(bytes: TBytes): string;
var
i: integer;
begin
result := '';
for i := 0 to Length(bytes) - 1 do
result := result + bytes[i].ToHexString(2);
end;

procedure TformAEST.btnEncryptClick(Sender: TObject);
var
codec: TCodec;
plainBytes, cipherBytes: TBytes;
cipherMemory: TStream;
cipherBytesLen: integer;
begin

cipherMemory := TMemoryStream.Create;

plainBytes := bytesof(PKCS5Padding(edtPlaintext.Text, 16));

codec := NewCodec(bytesof(edtKey.Text));
codec.Begin_EncryptMemory(cipherMemory);
codec.EncryptMemory(plainBytes, Length(plainBytes));
codec.End_EncryptMemory;

cipherMemory.Position := 8;
cipherBytesLen := cipherMemory.Size - 8;
SetLength(cipherBytes, cipherBytesLen);
cipherMemory.ReadBuffer(cipherBytes, cipherBytesLen);
edtCiphertext.Text := BytesToHexStr(cipherBytes);
end;






firemonkey delphi-xe lockbox-3






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Jan 1 at 13:52









8615386153

1




1













  • Consider accepting answers that are helpful and reviewing previous answers an accepting is appropriate. 1, See reputation faq Voting up a question or answer signals to the rest of the community that a post is interesting, well-researched, and useful.

    – zaph
    Jan 1 at 18:04



















  • Consider accepting answers that are helpful and reviewing previous answers an accepting is appropriate. 1, See reputation faq Voting up a question or answer signals to the rest of the community that a post is interesting, well-researched, and useful.

    – zaph
    Jan 1 at 18:04

















Consider accepting answers that are helpful and reviewing previous answers an accepting is appropriate. 1, See reputation faq Voting up a question or answer signals to the rest of the community that a post is interesting, well-researched, and useful.

– zaph
Jan 1 at 18:04





Consider accepting answers that are helpful and reviewing previous answers an accepting is appropriate. 1, See reputation faq Voting up a question or answer signals to the rest of the community that a post is interesting, well-researched, and useful.

– zaph
Jan 1 at 18:04












1 Answer
1






active

oldest

votes


















2














Encryption and decryption operate on raw bytes, not on characters.



When encrypting Unicode strings, especially across platforms, you have to encode the characters to bytes using a consistent byte encoding before then encrypting those bytes.



And when decrypting Unicode strings, make sure to use that same byte encoding when converting the decrypted bytes back into characters.



In your code, you are using BytesOf() to encode Unicode characters to bytes. Internally, BytesOf() uses TEncoding.Default as the encoding, which is TEncoding.ANSI on Windows PCs but is TEncoding.UTF8 on other platforms. So, if your input strings contain any non-ASCII characters, you will end up with different results.



I suggest replacing BytesOf() with TEncoding.UTF8.GetBytes() on all platforms:



plainBytes := TEncoding.UTF8.GetBytes(PKCS5Padding(edtPlaintext.Text, 16));

codec := NewCodec(TEncoding.UTF8.GetBytes(edtKey.Text));





share|improve this answer
























  • Thanks answer, from Debugger/Output: key/IV:30303030303030303030303030303030 plainBytes: 706C61696E5465787407070707070707, the same two platform, seems not this reason.

    – 86153
    Jan 2 at 1:16











  • @86153 it is very unlikely that 2 different encryption libraries would both fail on mobile, it is more likely that you are doing sonething differently in how you use the libraries across platforms. You will have to continue debugging to see where differences between platforms actually occur at each step.

    – Remy Lebeau
    Jan 2 at 7:31













  • @86153 And FYI, on a side note, you should NOT be applying PKCS5 padding to the string you are encrypting, you should be applying the padding to plainBytes before giving it to the library. Again, encryption operates on bytes, and the blocksize applies to the bytes being encrypted, not to the characters used to produce those bytes, so the padding needs to be added to the end of the actual bytes, not the string. This is a subtle but important thing to get right.

    – Remy Lebeau
    Jan 2 at 7:32













  • Thanks Remy, finally I use DCPcrypt2, it's work on android. Related Quetion: stackoverflow.com/questions/43523262/…

    – 86153
    Jan 2 at 8:18











  • @86153 that other question is not the same issue as this one. The other question used string buffers for the bytes, and suffered from indexing issues across platforms. This question does not do that.

    – Remy Lebeau
    Jan 2 at 16:37











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53996009%2fdelphi-firemonkey-lockbox3-aes-cbc-pc-and-android-result-are-different%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














Encryption and decryption operate on raw bytes, not on characters.



When encrypting Unicode strings, especially across platforms, you have to encode the characters to bytes using a consistent byte encoding before then encrypting those bytes.



And when decrypting Unicode strings, make sure to use that same byte encoding when converting the decrypted bytes back into characters.



In your code, you are using BytesOf() to encode Unicode characters to bytes. Internally, BytesOf() uses TEncoding.Default as the encoding, which is TEncoding.ANSI on Windows PCs but is TEncoding.UTF8 on other platforms. So, if your input strings contain any non-ASCII characters, you will end up with different results.



I suggest replacing BytesOf() with TEncoding.UTF8.GetBytes() on all platforms:



plainBytes := TEncoding.UTF8.GetBytes(PKCS5Padding(edtPlaintext.Text, 16));

codec := NewCodec(TEncoding.UTF8.GetBytes(edtKey.Text));





share|improve this answer
























  • Thanks answer, from Debugger/Output: key/IV:30303030303030303030303030303030 plainBytes: 706C61696E5465787407070707070707, the same two platform, seems not this reason.

    – 86153
    Jan 2 at 1:16











  • @86153 it is very unlikely that 2 different encryption libraries would both fail on mobile, it is more likely that you are doing sonething differently in how you use the libraries across platforms. You will have to continue debugging to see where differences between platforms actually occur at each step.

    – Remy Lebeau
    Jan 2 at 7:31













  • @86153 And FYI, on a side note, you should NOT be applying PKCS5 padding to the string you are encrypting, you should be applying the padding to plainBytes before giving it to the library. Again, encryption operates on bytes, and the blocksize applies to the bytes being encrypted, not to the characters used to produce those bytes, so the padding needs to be added to the end of the actual bytes, not the string. This is a subtle but important thing to get right.

    – Remy Lebeau
    Jan 2 at 7:32













  • Thanks Remy, finally I use DCPcrypt2, it's work on android. Related Quetion: stackoverflow.com/questions/43523262/…

    – 86153
    Jan 2 at 8:18











  • @86153 that other question is not the same issue as this one. The other question used string buffers for the bytes, and suffered from indexing issues across platforms. This question does not do that.

    – Remy Lebeau
    Jan 2 at 16:37
















2














Encryption and decryption operate on raw bytes, not on characters.



When encrypting Unicode strings, especially across platforms, you have to encode the characters to bytes using a consistent byte encoding before then encrypting those bytes.



And when decrypting Unicode strings, make sure to use that same byte encoding when converting the decrypted bytes back into characters.



In your code, you are using BytesOf() to encode Unicode characters to bytes. Internally, BytesOf() uses TEncoding.Default as the encoding, which is TEncoding.ANSI on Windows PCs but is TEncoding.UTF8 on other platforms. So, if your input strings contain any non-ASCII characters, you will end up with different results.



I suggest replacing BytesOf() with TEncoding.UTF8.GetBytes() on all platforms:



plainBytes := TEncoding.UTF8.GetBytes(PKCS5Padding(edtPlaintext.Text, 16));

codec := NewCodec(TEncoding.UTF8.GetBytes(edtKey.Text));





share|improve this answer
























  • Thanks answer, from Debugger/Output: key/IV:30303030303030303030303030303030 plainBytes: 706C61696E5465787407070707070707, the same two platform, seems not this reason.

    – 86153
    Jan 2 at 1:16











  • @86153 it is very unlikely that 2 different encryption libraries would both fail on mobile, it is more likely that you are doing sonething differently in how you use the libraries across platforms. You will have to continue debugging to see where differences between platforms actually occur at each step.

    – Remy Lebeau
    Jan 2 at 7:31













  • @86153 And FYI, on a side note, you should NOT be applying PKCS5 padding to the string you are encrypting, you should be applying the padding to plainBytes before giving it to the library. Again, encryption operates on bytes, and the blocksize applies to the bytes being encrypted, not to the characters used to produce those bytes, so the padding needs to be added to the end of the actual bytes, not the string. This is a subtle but important thing to get right.

    – Remy Lebeau
    Jan 2 at 7:32













  • Thanks Remy, finally I use DCPcrypt2, it's work on android. Related Quetion: stackoverflow.com/questions/43523262/…

    – 86153
    Jan 2 at 8:18











  • @86153 that other question is not the same issue as this one. The other question used string buffers for the bytes, and suffered from indexing issues across platforms. This question does not do that.

    – Remy Lebeau
    Jan 2 at 16:37














2












2








2







Encryption and decryption operate on raw bytes, not on characters.



When encrypting Unicode strings, especially across platforms, you have to encode the characters to bytes using a consistent byte encoding before then encrypting those bytes.



And when decrypting Unicode strings, make sure to use that same byte encoding when converting the decrypted bytes back into characters.



In your code, you are using BytesOf() to encode Unicode characters to bytes. Internally, BytesOf() uses TEncoding.Default as the encoding, which is TEncoding.ANSI on Windows PCs but is TEncoding.UTF8 on other platforms. So, if your input strings contain any non-ASCII characters, you will end up with different results.



I suggest replacing BytesOf() with TEncoding.UTF8.GetBytes() on all platforms:



plainBytes := TEncoding.UTF8.GetBytes(PKCS5Padding(edtPlaintext.Text, 16));

codec := NewCodec(TEncoding.UTF8.GetBytes(edtKey.Text));





share|improve this answer













Encryption and decryption operate on raw bytes, not on characters.



When encrypting Unicode strings, especially across platforms, you have to encode the characters to bytes using a consistent byte encoding before then encrypting those bytes.



And when decrypting Unicode strings, make sure to use that same byte encoding when converting the decrypted bytes back into characters.



In your code, you are using BytesOf() to encode Unicode characters to bytes. Internally, BytesOf() uses TEncoding.Default as the encoding, which is TEncoding.ANSI on Windows PCs but is TEncoding.UTF8 on other platforms. So, if your input strings contain any non-ASCII characters, you will end up with different results.



I suggest replacing BytesOf() with TEncoding.UTF8.GetBytes() on all platforms:



plainBytes := TEncoding.UTF8.GetBytes(PKCS5Padding(edtPlaintext.Text, 16));

codec := NewCodec(TEncoding.UTF8.GetBytes(edtKey.Text));






share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 1 at 16:50









Remy LebeauRemy Lebeau

339k19263458




339k19263458













  • Thanks answer, from Debugger/Output: key/IV:30303030303030303030303030303030 plainBytes: 706C61696E5465787407070707070707, the same two platform, seems not this reason.

    – 86153
    Jan 2 at 1:16











  • @86153 it is very unlikely that 2 different encryption libraries would both fail on mobile, it is more likely that you are doing sonething differently in how you use the libraries across platforms. You will have to continue debugging to see where differences between platforms actually occur at each step.

    – Remy Lebeau
    Jan 2 at 7:31













  • @86153 And FYI, on a side note, you should NOT be applying PKCS5 padding to the string you are encrypting, you should be applying the padding to plainBytes before giving it to the library. Again, encryption operates on bytes, and the blocksize applies to the bytes being encrypted, not to the characters used to produce those bytes, so the padding needs to be added to the end of the actual bytes, not the string. This is a subtle but important thing to get right.

    – Remy Lebeau
    Jan 2 at 7:32













  • Thanks Remy, finally I use DCPcrypt2, it's work on android. Related Quetion: stackoverflow.com/questions/43523262/…

    – 86153
    Jan 2 at 8:18











  • @86153 that other question is not the same issue as this one. The other question used string buffers for the bytes, and suffered from indexing issues across platforms. This question does not do that.

    – Remy Lebeau
    Jan 2 at 16:37



















  • Thanks answer, from Debugger/Output: key/IV:30303030303030303030303030303030 plainBytes: 706C61696E5465787407070707070707, the same two platform, seems not this reason.

    – 86153
    Jan 2 at 1:16











  • @86153 it is very unlikely that 2 different encryption libraries would both fail on mobile, it is more likely that you are doing sonething differently in how you use the libraries across platforms. You will have to continue debugging to see where differences between platforms actually occur at each step.

    – Remy Lebeau
    Jan 2 at 7:31













  • @86153 And FYI, on a side note, you should NOT be applying PKCS5 padding to the string you are encrypting, you should be applying the padding to plainBytes before giving it to the library. Again, encryption operates on bytes, and the blocksize applies to the bytes being encrypted, not to the characters used to produce those bytes, so the padding needs to be added to the end of the actual bytes, not the string. This is a subtle but important thing to get right.

    – Remy Lebeau
    Jan 2 at 7:32













  • Thanks Remy, finally I use DCPcrypt2, it's work on android. Related Quetion: stackoverflow.com/questions/43523262/…

    – 86153
    Jan 2 at 8:18











  • @86153 that other question is not the same issue as this one. The other question used string buffers for the bytes, and suffered from indexing issues across platforms. This question does not do that.

    – Remy Lebeau
    Jan 2 at 16:37

















Thanks answer, from Debugger/Output: key/IV:30303030303030303030303030303030 plainBytes: 706C61696E5465787407070707070707, the same two platform, seems not this reason.

– 86153
Jan 2 at 1:16





Thanks answer, from Debugger/Output: key/IV:30303030303030303030303030303030 plainBytes: 706C61696E5465787407070707070707, the same two platform, seems not this reason.

– 86153
Jan 2 at 1:16













@86153 it is very unlikely that 2 different encryption libraries would both fail on mobile, it is more likely that you are doing sonething differently in how you use the libraries across platforms. You will have to continue debugging to see where differences between platforms actually occur at each step.

– Remy Lebeau
Jan 2 at 7:31







@86153 it is very unlikely that 2 different encryption libraries would both fail on mobile, it is more likely that you are doing sonething differently in how you use the libraries across platforms. You will have to continue debugging to see where differences between platforms actually occur at each step.

– Remy Lebeau
Jan 2 at 7:31















@86153 And FYI, on a side note, you should NOT be applying PKCS5 padding to the string you are encrypting, you should be applying the padding to plainBytes before giving it to the library. Again, encryption operates on bytes, and the blocksize applies to the bytes being encrypted, not to the characters used to produce those bytes, so the padding needs to be added to the end of the actual bytes, not the string. This is a subtle but important thing to get right.

– Remy Lebeau
Jan 2 at 7:32







@86153 And FYI, on a side note, you should NOT be applying PKCS5 padding to the string you are encrypting, you should be applying the padding to plainBytes before giving it to the library. Again, encryption operates on bytes, and the blocksize applies to the bytes being encrypted, not to the characters used to produce those bytes, so the padding needs to be added to the end of the actual bytes, not the string. This is a subtle but important thing to get right.

– Remy Lebeau
Jan 2 at 7:32















Thanks Remy, finally I use DCPcrypt2, it's work on android. Related Quetion: stackoverflow.com/questions/43523262/…

– 86153
Jan 2 at 8:18





Thanks Remy, finally I use DCPcrypt2, it's work on android. Related Quetion: stackoverflow.com/questions/43523262/…

– 86153
Jan 2 at 8:18













@86153 that other question is not the same issue as this one. The other question used string buffers for the bytes, and suffered from indexing issues across platforms. This question does not do that.

– Remy Lebeau
Jan 2 at 16:37





@86153 that other question is not the same issue as this one. The other question used string buffers for the bytes, and suffered from indexing issues across platforms. This question does not do that.

– Remy Lebeau
Jan 2 at 16:37




















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53996009%2fdelphi-firemonkey-lockbox3-aes-cbc-pc-and-android-result-are-different%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

MongoDB - Not Authorized To Execute Command

How to fix TextFormField cause rebuild widget in Flutter

in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith