AKushWarrior / steel_crypt

A collection of high-level API's exposing PointyCastle to perform hashing and encrypting in popular/secure algorithms.
https://pub.dev/packages/steel_crypt
Mozilla Public License 2.0
40 stars 10 forks source link

How to decrypt aes-256-gcm in PHP OpenSSL? #11

Closed ghost closed 4 years ago

ghost commented 4 years ago

When I encrypt or decrypt aes-256-gcm in PHP OpenSSL, I will use tag, like this:

openssl_encrypt($input, 'aes-256-gcm', $key, OPENSSL_ZERO_PADDING, $iv,$tag);

And the tag parameter is required.

How can I get a tag in steel_crypt?

@AKushWarrior

AKushWarrior commented 4 years ago

Sorry that I'm late to respond; I was on vacation.

The tag is passed for authenticated modes of AES, such as GCM. Most cryptography libraries omit it entirely; OpenSSL has it as an optional parameter, as per these docs. In my implementation of AES-256-GCM, I use a blank internally, with no drawback.

If the parameter is required, you can try passing null. If that doesn't work, get back to me with the error logs.

You also might want to try Stack Overflow – I'm not a PHP programmer.

AKushWarrior commented 4 years ago

P.S. you don't have to tag me. I get notified whenever anyone posts a comment/issue on this package.

ghost commented 4 years ago

The tag parameter cannot be omitted in PHP. It is a required parameter. If NULL is passed, PHP will directly return an error!

ghost commented 4 years ago

I also encountered a communication encryption problem between Java and fluent in Java. AES/CFB/NoPadding is used in Java, and I can't use the nopadding of CFB to fill in in steel_crypt!

AKushWarrior commented 4 years ago

moving to https://github.com/AKushWarrior/steel_crypt/issues/14 for the second part

AKushWarrior commented 4 years ago

As for the tag, have you tried an empty/0-filled byte array?

ghost commented 4 years ago

$tag is an output return parameter. You have tried to fill 0 or null, which is wrong!

AKushWarrior commented 4 years ago

I'm fixing this in steel_crypt 2.0, which will (hopefully) be out in a month or so.

Monitor #22.

AKushWarrior commented 4 years ago

@cailetech Also, just saying, you should file an issue with the php people. The authentication tag is NOT a required param for secure encryption.

AKushWarrior commented 4 years ago

This is fixed in 2.0. You can now pass aad to GCM.

Archprogrammer commented 4 years ago

Not to nag, but I have also had some problems with the tag - NOT the aad. I need to use a 96-bit tag but it appears steel_crypt only generates 64-bit tags?

I also suspect the bytes in the tag might be wrong, but I haven't had time to examine this aspect closely yet.

Doing this:

AesCrypt encrypter = AesCrypt(
   mode: ModeAES.gcm,
   padding: PaddingAES.pkcs7, // Causes an exception if set to "none"
   key: key128bit
);

String out=encrypter.encrypt(
   plaintext, 
   iv: ivbuf
);

on a plaintext of 88 bytes results in an output of 96 bytes which, given that AES-GCM does not use padding, should mean that a tag of 8 bytes (64bits) has been appended to the encrypted data?

Manually inspecting the output from another implementation (Firefox, subtle.crypto) of the same data with the same key and IV (and setting the tag length to 96 bits) results in the same output for the first 88 bytes but after that the result diverges. That is, the result is different after the 88th byte.

To summarize: 1) I need to set the tag length to 96 bits, but I have not found a way to do this. 2) The appended tag differs from the result of another implementation which, if I understand it correctly, appears to be wrong.

Would humbly request this issue to be reopened.

AKushWarrior commented 4 years ago

@archprogrammer Thanks for this extremely detailed report. I would ask that you make a new issue for this; perhaps "Investigate AES-GCM divergence" or something of that sort. I agree that something is up here.

AKushWarrior commented 4 years ago

@ghost you would pass 128. I didn't read your issue well at first, and misunderstood what you wanted.