Hi,
Can we change openssl_public_encrypt()
and openssl_private_decrypt()
from
defaulting to PKCS1v1.5 padding, in favor of defaulting to OAEP?
I'll create an RFC for this later. It will just prevent a lot of issues.
To wit:
https://github.com/garyr/portunus/blob/89853c180c85c71baac7015cb77ff8ddae129942/src/Portunus/Crypt/RSA/PrivateKey.php#L20
If we can't stop PHP developers who aren't cryptographers from writing
their own high-level RSA implementation, we can at least make it safer by
default.
Scott Arciszewski
Chief Development Officer
Paragon Initiative Enterprises <https://paragonie.com
Hi,
On Thu, Nov 3, 2016 at 4:11 PM, Scott Arciszewski scott@paragonie.com
wrote:
Hi,
Can we change
openssl_public_encrypt()
andopenssl_private_decrypt()
from
defaulting to PKCS1v1.5 padding, in favor of defaulting to OAEP?I'll create an RFC for this later. It will just prevent a lot of issues.
To wit:
https://github.com/garyr/portunus/blob/89853c180c85c71baac7015cb77ff8
ddae129942/src/Portunus/Crypt/RSA/PrivateKey.php#L20https://github.com/NorseBlue/Sikker/blob/c158bab1e676d751e5228cb17ecf95
93c6b94e95/src/Asymmetric/Keys/PrivateKey.php#L72If we can't stop PHP developers who aren't cryptographers from writing
their own high-level RSA implementation, we can at least make it safer by
default.
We can't change default in 7.x as it would be a BC break and in this case a
very hard to catch BC break as the only way how we could let user know
about that is a documentation. This is a very low level function and
PKCSv1.5 is still used a lot so some apps might depend on. I think that the
default is bad but I don't think that breaking both function without notice
is a good solution as users might not be able to catch it especially if
it's some third party protocol that is not very secure but you don't have
choice because 3rd party won't change it (that was actually the only case
where I used these functions in practice so it's not made up). And even
worse if you don't have tests, then it breaks just production without a
warning...
What I would prefer instead is to deprecate calling
openssl_(private|public)_(en|de)crypt without a padding parameter. The
default would stay the same but user would get a deprecation message and
the parameter would become required in PHP 8. We should add a note to the
doc, to let the user know what the safest option is. It means OAEP
for openssl_private_decrypt and openssl_public_encrypt. In case of
openssl_public_decrypt and openssl_private_encrypt, we support just
PKCS1v1.5 but if we add support for PSS (would require a little bit of
tweaking as it works on EVP level only but might add it later), we could
easily recommend it then.
I have got actually very similar plan for openssl_seal and openssl_open
that have default method rc4. Again very bad default but the best way how
to let user know is to deprecate it rather than choose new default and
break compatibility.
Cheers
Jakub
2016-11-06 20:19 GMT+01:00 Jakub Zelenka bukka@php.net:
Hi,
On Thu, Nov 3, 2016 at 4:11 PM, Scott Arciszewski scott@paragonie.com
wrote:Hi,
Can we change
openssl_public_encrypt()
andopenssl_private_decrypt()
from
defaulting to PKCS1v1.5 padding, in favor of defaulting to OAEP?I'll create an RFC for this later. It will just prevent a lot of issues.
To wit:
https://github.com/garyr/portunus/blob/89853c180c85c71baac7015cb77ff8
ddae129942/src/Portunus/Crypt/RSA/PrivateKey.php#L20https://github.com/NorseBlue/Sikker/blob/c158bab1e676d751e5228cb17ecf95
93c6b94e95/src/Asymmetric/Keys/PrivateKey.php#L72If we can't stop PHP developers who aren't cryptographers from writing
their own high-level RSA implementation, we can at least make it safer by
default.We can't change default in 7.x as it would be a BC break and in this case a
very hard to catch BC break as the only way how we could let user know
about that is a documentation. This is a very low level function and
PKCSv1.5 is still used a lot so some apps might depend on. I think that the
default is bad but I don't think that breaking both function without notice
is a good solution as users might not be able to catch it especially if
it's some third party protocol that is not very secure but you don't have
choice because 3rd party won't change it (that was actually the only case
where I used these functions in practice so it's not made up). And even
worse if you don't have tests, then it breaks just production without a
warning...What I would prefer instead is to deprecate calling
openssl_(private|public)_(en|de)crypt without a padding parameter. The
default would stay the same but user would get a deprecation message and
the parameter would become required in PHP 8. We should add a note to the
doc, to let the user know what the safest option is. It means OAEP
for openssl_private_decrypt and openssl_public_encrypt. In case of
openssl_public_decrypt and openssl_private_encrypt, we support just
PKCS1v1.5 but if we add support for PSS (would require a little bit of
tweaking as it works on EVP level only but might add it later), we could
easily recommend it then.I have got actually very similar plan for openssl_seal and openssl_open
that have default method rc4. Again very bad default but the best way how
to let user know is to deprecate it rather than choose new default and
break compatibility.Cheers
Jakub
Huge +1 for that plan!
Regards, Niklas
Hi,
On Thu, Nov 3, 2016 at 4:11 PM, Scott Arciszewski scott@paragonie.com
wrote:Hi,
Can we change
openssl_public_encrypt()
andopenssl_private_decrypt()
from
defaulting to PKCS1v1.5 padding, in favor of defaulting to OAEP?I'll create an RFC for this later. It will just prevent a lot of issues.
To wit:
https://github.com/garyr/portunus/blob/89853c180c85c71baac7015cb77ff8ddae129942/src/Portunus/Crypt/RSA/PrivateKey.php#L20
If we can't stop PHP developers who aren't cryptographers from writing
their own high-level RSA implementation, we can at least make it safer by
default.We can't change default in 7.x as it would be a BC break and in this case a
very hard to catch BC break as the only way how we could let user know about
that is a documentation. This is a very low level function and PKCSv1.5 is
still used a lot so some apps might depend on. I think that the default is
bad but I don't think that breaking both function without notice is a good
solution as users might not be able to catch it especially if it's some
third party protocol that is not very secure but you don't have choice
because 3rd party won't change it (that was actually the only case where I
used these functions in practice so it's not made up). And even worse if you
don't have tests, then it breaks just production without a warning...What I would prefer instead is to deprecate calling
openssl_(private|public)_(en|de)crypt without a padding parameter. The
default would stay the same but user would get a deprecation message and the
parameter would become required in PHP 8. We should add a note to the doc,
to let the user know what the safest option is. It means OAEP for
openssl_private_decrypt and openssl_public_encrypt. In case of
openssl_public_decrypt and openssl_private_encrypt, we support just
PKCS1v1.5 but if we add support for PSS (would require a little bit of
tweaking as it works on EVP level only but might add it later), we could
easily recommend it then.I have got actually very similar plan for openssl_seal and openssl_open that
have default method rc4. Again very bad default but the best way how to let
user know is to deprecate it rather than choose new default and break
compatibility.Cheers
Jakub
Hi Jakub,
We can't change default in 7.x as it would be a BC break and in this case a very hard to catch BC break as the only way how we could let user know about that is a documentation.
A sane proposal had emerged before I even received this email, via
kemmeta on Reddit:
A backwards-compatible interface would default
openssl_public_encrypt()
to OAEP, but openssl_private_decrypt()
would
default to a new constant: OPENSSL_PKCS1_UNSPECIFIED, which when
passed would first try OAEP and, if a padding error occurred, emit an
E_DEPRECATED
and fallback to PKCS1v1.5 (a.k.a. "let's pretend Daniel
Bleichenbacher's research doesn't exist" mode).
The upside is that better security would be applied opportunistically
in codebases where the PHP developer was not a cryptographer. The
downside is a performance hit unless you specify one mode or another.
A long term solution would be to not even use RSA anymore.
I have got actually very similar plan for openssl_seal and openssl_open that
have default method rc4. Again very bad default but the best way how to let
user know is to deprecate it rather than choose new default and break
compatibility.
If your plan is to get it more in line with libsodium's
crypto_box_seal API, I'd love to see it.
Scott Arciszewski
Chief Development Officer
Paragon Initiative Enterprises
Hi,
On Thu, Nov 3, 2016 at 4:11 PM, Scott Arciszewski scott@paragonie.com
wrote:Hi,
Can we change
openssl_public_encrypt()
andopenssl_private_decrypt()
from
defaulting to PKCS1v1.5 padding, in favor of defaulting to OAEP?I'll create an RFC for this later. It will just prevent a lot of issues.
To wit:
https://github.com/garyr/portunus/blob/89853c180c85c71baac7015cb77ff8ddae129942/src/Portunus/Crypt/RSA/PrivateKey.php#L20
If we can't stop PHP developers who aren't cryptographers from writing
their own high-level RSA implementation, we can at least make it safer by
default.We can't change default in 7.x as it would be a BC break and in this case a
very hard to catch BC break as the only way how we could let user know about
that is a documentation. This is a very low level function and PKCSv1.5 is
still used a lot so some apps might depend on. I think that the default is
bad but I don't think that breaking both function without notice is a good
solution as users might not be able to catch it especially if it's some
third party protocol that is not very secure but you don't have choice
because 3rd party won't change it (that was actually the only case where I
used these functions in practice so it's not made up). And even worse if you
don't have tests, then it breaks just production without a warning...What I would prefer instead is to deprecate calling
openssl_(private|public)_(en|de)crypt without a padding parameter. The
default would stay the same but user would get a deprecation message and the
parameter would become required in PHP 8. We should add a note to the doc,
to let the user know what the safest option is. It means OAEP for
openssl_private_decrypt and openssl_public_encrypt. In case of
openssl_public_decrypt and openssl_private_encrypt, we support just
PKCS1v1.5 but if we add support for PSS (would require a little bit of
tweaking as it works on EVP level only but might add it later), we could
easily recommend it then.I have got actually very similar plan for openssl_seal and openssl_open that
have default method rc4. Again very bad default but the best way how to let
user know is to deprecate it rather than choose new default and break
compatibility.Cheers
Jakub
Hi Jakub,
We can't change default in 7.x as it would be a BC break and in this case a very hard to catch BC break as the only way how we could let user know about that is a documentation.
A sane proposal had emerged before I even received this email, via
kemmeta on Reddit:A backwards-compatible interface would default
openssl_public_encrypt()
to OAEP, butopenssl_private_decrypt()
would
default to a new constant: OPENSSL_PKCS1_UNSPECIFIED, which when
passed would first try OAEP and, if a padding error occurred, emit an
E_DEPRECATED
and fallback to PKCS1v1.5 (a.k.a. "let's pretend Daniel
Bleichenbacher's research doesn't exist" mode).The upside is that better security would be applied opportunistically
in codebases where the PHP developer was not a cryptographer. The
downside is a performance hit unless you specify one mode or another.A long term solution would be to not even use RSA anymore.
I have got actually very similar plan for openssl_seal and openssl_open that
have default method rc4. Again very bad default but the best way how to let
user know is to deprecate it rather than choose new default and break
compatibility.If your plan is to get it more in line with libsodium's
crypto_box_seal API, I'd love to see it.Scott Arciszewski
Chief Development Officer
Paragon Initiative Enterprises--
Hey,
It might make even more sense to not provide a default here at all. As history shows that those methods that are considered secure today can become less-than-desirably secure in a couple of years. Which means the same cycle of deprecation/changing defaults in years to come.