Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upUse system random generator in crypto #5798
Comments
mscdex
added
crypto
feature request
labels
Mar 19, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bnoordhuis
Mar 19, 2016
Member
Instead of linking to a blog post, please summarize the pros and cons here.
|
Instead of linking to a blog post, please summarize the pros and cons here. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ChALkeR
Mar 19, 2016
Member
Perhaps @joepie91 or @paragonie-scott would be interested to elaborate that here.
|
Perhaps @joepie91 or @paragonie-scott would be interested to elaborate that here. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
paragonie-scott
Mar 19, 2016
From "a blog post":
Why not {SecureRandom, OpenSSL, havaged, &c}?
These are userspace CSPRNGs. You want to use the kernel’s CSPRNG, because:
- The kernel has access to raw device entropy.
- It can promise not to share the same state between applications.
- A good kernel CSPRNG, like FreeBSD’s, can also promise not to feed you random data before it’s seeded.
Additionally, OpenSSL's userspace PRNG has caused issues in other languages (PHP under Apache for sure) because it's not fork-safe, which caused random numbers to repeat. (Combine this with the consequences of nonce reuse for most stream ciphers and boom your cryptosystem loses all privacy.)
A safer bet would be to adopt what PHP 7's random_bytes() does:
https://github.com/php/php-src/blob/e8f056e535813bf864743626c3a208ceafee70b9/ext/standard/random.c#L83-L186
paragonie-scott
commented
Mar 19, 2016
|
From "a blog post":
Additionally, OpenSSL's userspace PRNG has caused issues in other languages (PHP under Apache for sure) because it's not fork-safe, which caused random numbers to repeat. (Combine this with the consequences of nonce reuse for most stream ciphers and boom your cryptosystem loses all privacy.) A safer bet would be to adopt what PHP 7's |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bnoordhuis
Mar 19, 2016
Member
OpenSSL's PRNG is seeded from /dev/{,s,u}random, can get entropy from entropy-collecting daemons, and forking is not an issue for node.js. So far I'm not seeing a compelling reason to switch.
|
OpenSSL's PRNG is seeded from /dev/{,s,u}random, can get entropy from entropy-collecting daemons, and forking is not an issue for node.js. So far I'm not seeing a compelling reason to switch. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ChALkeR
Mar 19, 2016
Member
@paragonie-scott That's does not look like a good reasoning. Could you please be more calm? ;-)
|
@paragonie-scott That's does not look like a good reasoning. Could you please be more calm? ;-) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
joepie91
Mar 19, 2016
Contributor
@bnoordhuis Trying to find specific reasons to explain away potential issues is not a good approach to security-related matters. The issues exist, and there's no way to predict how Node will evolve - for example, if fork-safety might start to matter due to future changes, at which point people will likely have forgotten about this specific issue.
We should be striving for the optimally secure implementation (within technical constraints), instead of attempting to 'defend' the current implementation when there are known edge cases / issues with it.
This post addresses that further.
|
@bnoordhuis Trying to find specific reasons to explain away potential issues is not a good approach to security-related matters. The issues exist, and there's no way to predict how Node will evolve - for example, if fork-safety might start to matter due to future changes, at which point people will likely have forgotten about this specific issue. We should be striving for the optimally secure implementation (within technical constraints), instead of attempting to 'defend' the current implementation when there are known edge cases / issues with it. This post addresses that further. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ChALkeR
Mar 19, 2016
Member
I do not yet have a strong opinion on this. I called @joepie91 and @paragonie-scott here because they expressed similar considerations as @speakeasypuncture in an IRC chat earlier.
@bnoordhuis, as I understand their points, the reasons here are:
- System PRNG is good for this, is known to be stable and hasn't caused many security issues.
- Adding a user-space PRNG of top of that doesn't make it more secure, but it makes it more prone to errors.
- OpenSSL isn't actually a very high code quality product.
- Using OpenSSL PRNG caused serious security issues for some projects, namely for Debian, Android and PHP (that latter is still not fixed, btw), though that was mostly their fault. Those issues are not directly applicable to Node.js, but this gives an uneasy feeling.
- There seems to be no reason not to ditch OpenSSL PRNG and reduce the possible errors.
Everyone — did I miss anything?
|
I do not yet have a strong opinion on this. I called @joepie91 and @paragonie-scott here because they expressed similar considerations as @speakeasypuncture in an IRC chat earlier. @bnoordhuis, as I understand their points, the reasons here are:
Everyone — did I miss anything? |
ChALkeR
added
the
security
label
Mar 19, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ChALkeR
Mar 19, 2016
Member
Again: I do not yet have a strong opinion on this.
I would like to hear what would the drawbacks of this change be, and is there something where (or why) OpenSSL PRNG could be better than the system PRNG.
Excluding the fact that it's already used, of course — that also isn't a good enough argument, this won't even be a semver-major change. It's not documented that crypto.randomBytes() uses OpenSSL.
|
Again: I do not yet have a strong opinion on this. I would like to hear what would the drawbacks of this change be, and is there something where (or why) OpenSSL PRNG could be better than the system PRNG. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
/cc @nodejs/crypto. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ChALkeR
Mar 19, 2016
Member
@mscdex I'm not sure if this is a «feature request», it looks like a proposal to change the implementation of crypto.randomBytes() to me.
|
@mscdex I'm not sure if this is a «feature request», it looks like a proposal to change the implementation of |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
@ChALkeR Your summary seems accurate to me. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
paragonie-scott
Mar 19, 2016
Also, random number generators are hot-swappable without compatibility concerns, only security concerns.
paragonie-scott
commented
Mar 19, 2016
|
Also, random number generators are hot-swappable without compatibility concerns, only security concerns. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
I'm -1 on this, no compelling reasons for me. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
joepie91
Mar 20, 2016
Contributor
@indutny Please refer back to this comment in particular, plus several others in the thread. There is a lack of reasons not to do this (insofar anybody has stated them, that is), while there are documented reasons to do it.
If you feel that there is a reason not to do it, then please share it - but "no compelling reasons for me" really isn't a sufficient argument for a security-related matter. Even a small defect can have disastrous consequences.
|
@indutny Please refer back to this comment in particular, plus several others in the thread. There is a lack of reasons not to do this (insofar anybody has stated them, that is), while there are documented reasons to do it. If you feel that there is a reason not to do it, then please share it - but "no compelling reasons for me" really isn't a sufficient argument for a security-related matter. Even a small defect can have disastrous consequences. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
indutny
Mar 20, 2016
Member
@joepie91 sure, sorry for too short reply.
What about systems with "good" PRNG? How many of them are there? Do we have to carry both implementations to support them?
|
@joepie91 sure, sorry for too short reply. What about systems with "good" PRNG? How many of them are there? Do we have to carry both implementations to support them? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
joepie91
Mar 20, 2016
Contributor
@indutny Thanks for the elaboration.
As I understand it (and please correct me if not), OpenSSL depends on the system PRNG to begin with. I'm not aware of any platforms (of those supported by Node, that is) where OpenSSL can provide a better PRNG than the one that the system offers natively.
It should thus be possible to just remove OpenSSL's PRNG from the equation entirely, and rely purely on the system PRNG, as PHP has done.
|
@indutny Thanks for the elaboration. As I understand it (and please correct me if not), OpenSSL depends on the system PRNG to begin with. I'm not aware of any platforms (of those supported by Node, that is) where OpenSSL can provide a better PRNG than the one that the system offers natively. It should thus be possible to just remove OpenSSL's PRNG from the equation entirely, and rely purely on the system PRNG, as PHP has done. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
indutny
Mar 20, 2016
Member
@joepie91 do you suggest to use this randomness for TLS protocol as well? I'm not sure if it is possible, though.
|
@joepie91 do you suggest to use this randomness for TLS protocol as well? I'm not sure if it is possible, though. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
joepie91
Mar 20, 2016
Contributor
While that would probably be nice (albeit requiring more investigation), I don't think that's doable. As far as I know, OpenSSL's other functionality relies internally on its own PRNG with no ability to change that - unless we want to get rid of OpenSSL entirely, which would be a separate proposal (and likely not viable at this stage, given the lack of well-tested alternatives).
So, this specific proposal would concern the "user-facing" randomBytes method only.
|
While that would probably be nice (albeit requiring more investigation), I don't think that's doable. As far as I know, OpenSSL's other functionality relies internally on its own PRNG with no ability to change that - unless we want to get rid of OpenSSL entirely, which would be a separate proposal (and likely not viable at this stage, given the lack of well-tested alternatives). So, this specific proposal would concern the "user-facing" |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
Ok, considering arguments it probably make more sense now. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bnoordhuis
Mar 20, 2016
Member
Here's a reason not to switch: OpenSSL's PRNG is a known quantity, the strength of platform-specific PRNGs is not. If the next Windows or FreeBSD release has a flawed PRNG, that will compromise node.js.
If (generic) you think moving to platform-specific solutions is the way forward, get OpenSSL to adopt your approach and node.js will automatically go along. I believe @paragonie-scott is volunteering? He sure seems to feel strongly about it.
if fork-safety might start to matter due to future changes, at which point people will likely have forgotten about this specific issue.
@joepie91 The bucket list of fork-safety issues that would have to be addressed is so long that I think it's safe to say that node.js will never be fork-safe. There are many things that keep me awake at night but this is not one of them.
|
Here's a reason not to switch: OpenSSL's PRNG is a known quantity, the strength of platform-specific PRNGs is not. If the next Windows or FreeBSD release has a flawed PRNG, that will compromise node.js. If (generic) you think moving to platform-specific solutions is the way forward, get OpenSSL to adopt your approach and node.js will automatically go along. I believe @paragonie-scott is volunteering? He sure seems to feel strongly about it.
@joepie91 The bucket list of fork-safety issues that would have to be addressed is so long that I think it's safe to say that node.js will never be fork-safe. There are many things that keep me awake at night but this is not one of them. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
alfiepates
Mar 20, 2016
If the next Windows or FreeBSD release has a flawed PRNG, that will compromise node.js.
I don't believe this argument holds any merit, honestly.
FreeBSD are not just going to push broken code EDIT: FreeBSD are not going to push broken code to the -STABLE kernel branch, especially when they have a perfectly functional CSPRNG already, and especially as they have a security team of their own who would definitely catch any changes to the CSPRNG which would lead to a vulnerability in the OS.
I'm going to be frank, here: Attempting to justify away security issues is downright irresponsible, and possibly dangerous. You need to strive for bulletproof security, or you may as well not implement any security at all (And no, don't twist this to mean "Don't bother with security", because that's just lazy.)
I appreciate it's "extra work" to make a change like this, but considering you're using a PRNG which has actually caused security issues in the past, I'd err on the safe side and move to something more provably secure.
alfiepates
commented
Mar 20, 2016
I don't believe this argument holds any merit, honestly.
I'm going to be frank, here: Attempting to justify away security issues is downright irresponsible, and possibly dangerous. You need to strive for bulletproof security, or you may as well not implement any security at all (And no, don't twist this to mean "Don't bother with security", because that's just lazy.) I appreciate it's "extra work" to make a change like this, but considering you're using a PRNG which has actually caused security issues in the past, I'd err on the safe side and move to something more provably secure. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bnoordhuis
Mar 20, 2016
Member
as they have a security team of their own who would definitely catch any changes to the CSPRNG which would lead to a vulnerability in the OS
Besides being an appeal to authority, you're asking (generic) me to trust several teams of implementors (the platforms) instead of just one (OpenSSL) to get their implementation right.
considering you're using a PRNG which has actually caused security issues in the past
Are you saying you feel OpenSSL's PRNG is insecure? If so, why aren't you taking that up with the OpenSSL team? Griping about it here isn't going to do any good.
I'll repeat what I've said above: get the upstream project to move over, and we as downstream consumers will automatically move along with it.
Besides being an appeal to authority, you're asking (generic) me to trust several teams of implementors (the platforms) instead of just one (OpenSSL) to get their implementation right.
Are you saying you feel OpenSSL's PRNG is insecure? If so, why aren't you taking that up with the OpenSSL team? Griping about it here isn't going to do any good. I'll repeat what I've said above: get the upstream project to move over, and we as downstream consumers will automatically move along with it. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
joepie91
Mar 20, 2016
Contributor
Here's a reason not to switch: OpenSSL's PRNG is a known quantity, the strength of platform-specific PRNGs is not. If the next Windows or FreeBSD release has a flawed PRNG, that will compromise node.js.
Yet OpenSSL's PRNG relies on these platform-specific PRNGs, and mixing in one broken PRNG can weaken the entire (combined) PRNG. How does relying on OpenSSL fix the issue you've described?
The bucket list of fork-safety issues that would have to be addressed is so long that I think it's safe to say that node.js will never be fork-safe. There are many things that keep me awake at night but this is not one of them.
That is a very dangerous assumption to make.
f so, why aren't you taking that up with the OpenSSL team?
I think the existence of this project should give an indication. At this stage, there's a fairly wide consensus around the security community that OpenSSL is awful software, and the only real reason it is still being recommended is because it's what has been tested in the real world for so long. Not because it is of high quality or well-maintained.
Yet OpenSSL's PRNG relies on these platform-specific PRNGs, and mixing in one broken PRNG can weaken the entire (combined) PRNG. How does relying on OpenSSL fix the issue you've described?
That is a very dangerous assumption to make.
I think the existence of this project should give an indication. At this stage, there's a fairly wide consensus around the security community that OpenSSL is awful software, and the only real reason it is still being recommended is because it's what has been tested in the real world for so long. Not because it is of high quality or well-maintained. |
ChALkeR
added
the
discuss
label
Mar 20, 2016
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
paragonie-scott
Mar 20, 2016
Here's a reason not to switch: OpenSSL's PRNG is a known quantity, the strength of platform-specific PRNGs is not. If the next Windows or FreeBSD release has a flawed PRNG, that will compromise node.js.
This is a common argument that people make, but it's ultimately invalid.
Even if you avoid depending on the operating system's PRNG, the rest of your system definitely depends on it for security. Node.js will be compromised regardless of what Node.js does.
paragonie-scott
commented
Mar 20, 2016
This is a common argument that people make, but it's ultimately invalid. Even if you avoid depending on the operating system's PRNG, the rest of your system definitely depends on it for security. Node.js will be compromised regardless of what Node.js does. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
indutny
Mar 20, 2016
Member
Just a bit of FYI for everyone here:
http://lwn.net/Articles/633805/rss
"FreeBSD random number generator broken for last 4 months"
|
Just a bit of FYI for everyone here: http://lwn.net/Articles/633805/rss "FreeBSD random number generator broken for last 4 months" |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ChALkeR
Mar 20, 2016
Member
@indutny Note that it also affects keys generated by Node.js on FreeBSD (using crypto.randomBytes()):
This includes, but not limited to, ssh keys and keys generated by openssl.
|
@indutny Note that it also affects keys generated by Node.js on FreeBSD (using
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ircmaxell
Mar 20, 2016
Here's a reason not to switch: OpenSSL's PRNG is a known quantity, the strength of platform-specific PRNGs is not. If the next Windows or FreeBSD release has a flawed PRNG, that will compromise node.js.
Actually, if Windows's CSPRNG is compromised, then Node.JS will be compromised. This is because OpenSSL relies on the system CSPRNG to seed it. There is no other source of high-quality random data in the system.
This means that the OpenSSL CSPRNG can by definition not be any stronger than the system's CSPRNG. However, it can be weaker (as has been seen several times).
The reason @paragonie-scott and others (including myself) are anti-userspace-csprng is that they provide no possible security gain, but introduce several security risks (by increasing attack surface area, by increasing bug surface area, etc).
There really is no benefit to not switching (other than not making a change at all). However, as has been demonstrated in this thread already, there are several advantages to switching.
My suggestion would be to switch to the kernel-space CSPRNG.
ircmaxell
commented
Mar 20, 2016
Actually, if Windows's CSPRNG is compromised, then Node.JS will be compromised. This is because OpenSSL relies on the system CSPRNG to seed it. There is no other source of high-quality random data in the system. This means that the OpenSSL CSPRNG can by definition not be any stronger than the system's CSPRNG. However, it can be weaker (as has been seen several times). The reason @paragonie-scott and others (including myself) are anti-userspace-csprng is that they provide no possible security gain, but introduce several security risks (by increasing attack surface area, by increasing bug surface area, etc). There really is no benefit to not switching (other than not making a change at all). However, as has been demonstrated in this thread already, there are several advantages to switching. My suggestion would be to switch to the kernel-space CSPRNG. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
indutny
Mar 20, 2016
Member
@ChALkeR this was a reply to:
FreeBSD are not just going to push broken code, especially when they have a perfectly functional CSPRNG already
|
@ChALkeR this was a reply to:
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ChALkeR
Mar 20, 2016
Member
@indutny yes, this assumption by @alfiepates is incorrect:
FreeBSD are not just going to push broken code, especially when they have a perfectly functional CSPRNG already, and especially as they have a security team of their own who would definitely catch any changes to the CSPRNG which would lead to a vulnerability in the OS.
Everyone makes mistakes, you can't say «{*} are not just going to push broken code» or «this lib is magical, shining, and will never be broken».
But what should be actually considered here is the fact that OpenSSL PRNG depends on system PRNG. So, it seems like under no circuimstances you could trust OpenSSL PRNG more than system PRNG, which makes «we can't trust system PRNGs, so let's use OpenSSL» argument invalid.
|
@indutny yes, this assumption by @alfiepates is incorrect:
Everyone makes mistakes, you can't say «{*} are not just going to push broken code» or «this lib is magical, shining, and will never be broken». But what should be actually considered here is the fact that OpenSSL PRNG depends on system PRNG. So, it seems like under no circuimstances you could trust OpenSSL PRNG more than system PRNG, which makes «we can't trust system PRNGs, so let's use OpenSSL» argument invalid. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
alfiepates
Mar 20, 2016
I will retract some of my comment, it was far too absolute, but I don't believe it's wrong.
It's disingenuous to link this article without stating the fact that this occured on the FreeBSD -CURRENT branch, as opposed to the -STABLE branch. The -CURRENT branch is the bleeding-edge branch, and therefore bugs do happen, and in this case the bug was caught before the it made it to -STABLE.
Besides, I feel you're missing the point of this discussion. OpenSSL's CSPRNG is a security risk. EDIT: Need to pay more attention when tired.
alfiepates
commented
Mar 20, 2016
|
I will retract some of my comment, it was far too absolute, but I don't believe it's wrong. It's disingenuous to link this article without stating the fact that this occured on the FreeBSD -CURRENT branch, as opposed to the -STABLE branch. The -CURRENT branch is the bleeding-edge branch, and therefore bugs do happen, and in this case the bug was caught before the it made it to -STABLE.
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
indutny
Mar 20, 2016
Member
@ChALkeR of course, I'm not saying that this is a counter-argument. Just wanted to make sure that everyone on the same page and does not trust OS vendors blindly.
|
@ChALkeR of course, I'm not saying that this is a counter-argument. Just wanted to make sure that everyone on the same page and does not trust OS vendors blindly. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
indutny
Mar 20, 2016
Member
@alfiepates hey, I'm not missing the point here!
|
@alfiepates hey, I'm not missing the point here! |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
alfiepates
Mar 20, 2016
@indutny Ahh, wonderful. I'll retract that part of my comment too :P (Please forgive me, I'm one cup of coffee behind right now)
alfiepates
commented
Mar 20, 2016
|
@indutny Ahh, wonderful. I'll retract that part of my comment too :P (Please forgive me, I'm one cup of coffee behind right now) |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
indutny
Mar 20, 2016
Member
There is however a risk of incorrect implementation on our side, when we will write that new code to support OS-level PRNG. Just some food for thoughts.
|
There is however a risk of incorrect implementation on our side, when we will write that new code to support OS-level PRNG. Just some food for thoughts. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ChALkeR
Mar 20, 2016
Member
@indutny True. There is also a blocking-vs-nonblocking argument that would need to be discussed when implementing this (i.e. /dev/random vs /dev/urandom). I don't have an opinion on that yet.
|
@indutny True. There is also a blocking-vs-nonblocking argument that would need to be discussed when implementing this (i.e. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
paragonie-scott
Mar 20, 2016
@indutny Sure. I'm almost certain that the rough draft will be incorrect in some way. That's why peer review matters.
For what it's worth, I did help with PHP's implementation and I work for a company that audits crypto code. There are others in this thread that are often more perceptive than I am.
So as long as we participated it's highly likely that any implementation bugs will be spotted and rectified.
paragonie-scott
commented
Mar 20, 2016
|
@indutny Sure. I'm almost certain that the rough draft will be incorrect in some way. That's why peer review matters. For what it's worth, I did help with PHP's implementation and I work for a company that audits crypto code. There are others in this thread that are often more perceptive than I am. So as long as we participated it's highly likely that any implementation bugs will be spotted and rectified. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
co60ca
Sep 17, 2016
To @joepie91 I've seen a implementation of UUID v4 use math.random so yes, a secure default that pulls from system entropy would be fantastic.
co60ca
commented
Sep 17, 2016
|
To @joepie91 I've seen a implementation of UUID v4 use math.random so yes, a secure default that pulls from system entropy would be fantastic. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
atoponce
Sep 17, 2016
As another example of using crypto.randomBytes() in a non-HTTPS setting, I am using it in a password generator: https://github.com/atoponce/nodepassgen.
atoponce
commented
Sep 17, 2016
|
As another example of using crypto.randomBytes() in a non-HTTPS setting, I am using it in a password generator: https://github.com/atoponce/nodepassgen. |
grahamc
referenced this issue
Nov 19, 2016
Closed
[wip] nodejs: Flag to disable building with openSSL #20513
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
ping @nodejs/crypto ... should this remain open? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
|
No, let's close. |
bnoordhuis
closed this
May 30, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
azet
May 30, 2017
this issue remains unfixed and there has been valuable discussion on resolving the problem.
similar issues in e.g. ruby proper lead to switch to libsodium-like approaches: https://bugs.ruby-lang.org/issues/9569
OpenSSL's implementation remains, to my knowledge, largely untested and specifically optimized to cater to TLS implementation's needs for fast random numbers. most languages (e.g. python) opt to use the /dev/urandom device on Linux distributions. libsodium is platform aware and spares the overhead of fiddling and maintaining distribution specific code-paths. libsodium has also been reviewed and is used by a lot of people and projects to provide a layer of abstraction for obtaining cryptographically secure pseudo random numbers.
I urge the core team to use libsodium's reviewed, platform-aware way to obtain secure pseudo random numbers: https://github.com/jedisct1/libsodium/blob/master/src/libsodium/randombytes/randombytes.c
please re-open this security relevant issue.
azet
commented
May 30, 2017
•
|
this issue remains unfixed and there has been valuable discussion on resolving the problem. OpenSSL's implementation remains, to my knowledge, largely untested and specifically optimized to cater to TLS implementation's needs for fast random numbers. most languages (e.g. python) opt to use the I urge the core team to use libsodium's reviewed, platform-aware way to obtain secure pseudo random numbers: https://github.com/jedisct1/libsodium/blob/master/src/libsodium/randombytes/randombytes.c please re-open this security relevant issue. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
tarcieri
commented
May 31, 2017
|
What was the rationale for closing this issue? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Trott
May 31, 2017
Member
If I understand correctly (which is a big "if" when it comes to cryptography and related issues):
Especially given activity on openssl/openssl#898 fairly recently, and that progress there could mean a suitable fix here that can still use OpenSSL APIs, I'd be for keeping this open.
|
If I understand correctly (which is a big "if" when it comes to cryptography and related issues): Especially given activity on openssl/openssl#898 fairly recently, and that progress there could mean a suitable fix here that can still use OpenSSL APIs, I'd be for keeping this open. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
sam-github
May 31, 2017
Member
@nodejs/crypto I think we should keep it open until its fixed. Last discussion was that OpenSSL were themselves moving this direction, and we hoped to simply inherit their fix. From openssl/openssl#898, it does indeed look like they are moving along (slowly, but with recent progress). But if OpenSSL 1.1 doesn't change this, we could revisit whether node should use some other way of getting pseudo-random.
|
@nodejs/crypto I think we should keep it open until its fixed. Last discussion was that OpenSSL were themselves moving this direction, and we hoped to simply inherit their fix. From openssl/openssl#898, it does indeed look like they are moving along (slowly, but with recent progress). But if OpenSSL 1.1 doesn't change this, we could revisit whether node should use some other way of getting pseudo-random. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
MylesBorins
May 31, 2017
Member
As a handful of people (including collaborators) have chimed in about wanting to continue the discussion. I'm reopening
That being said I think this might be part of a larger conversation about openssl... perhaps we can look into improving their implementation on systems that have support?
afaict libsodium is going to be a nonstarter if it doesn't have fips support
|
As a handful of people (including collaborators) have chimed in about wanting to continue the discussion. I'm reopening That being said I think this might be part of a larger conversation about openssl... perhaps we can look into improving their implementation on systems that have support? afaict libsodium is going to be a nonstarter if it doesn't have fips support |
MylesBorins
reopened this
May 31, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
paragonie-scott
May 31, 2017
afaict libsodium is going to be a nonstarter if it doesn't have fips support
Replacing OpenSSL entirely with Libsodium might be a nonstarter.
Is FIPS-140-2 compliance an absolute mandatory requirement? Because ECB mode is FIPS compliant, and you sure as hell don't want people encrypting that way.
paragonie-scott
commented
May 31, 2017
Replacing OpenSSL entirely with Libsodium might be a nonstarter. Is FIPS-140-2 compliance an absolute mandatory requirement? Because ECB mode is FIPS compliant, and you sure as hell don't want people encrypting that way. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
technion
May 31, 2017
Any changes to OpenSSL, even if they improve in this space, are going to show up on a new major release, which moves much, much slower than Node. If they made a great release tomorrow, it will take years to hit some distributions at all. I don't feel you want to wait on this.
technion
commented
May 31, 2017
|
Any changes to OpenSSL, even if they improve in this space, are going to show up on a new major release, which moves much, much slower than Node. If they made a great release tomorrow, it will take years to hit some distributions at all. I don't feel you want to wait on this. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
Trott
May 31, 2017
Member
If they made a great release tomorrow, it will take years to hit some distributions at all.
Node.js doesn't use the operating system's OpenSSL. Node.js ships with its own copy of OpenSSL.
Node.js doesn't use the operating system's OpenSSL. Node.js ships with its own copy of OpenSSL. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bnoordhuis
May 31, 2017
Member
I might be open to bundling libsodium in addition to openssl but that should be its own issue because there will be numerous details to hash out.
We sure as heck are not going to ship something homegrown and until openssl grows the requisite APIs there isn't anything actionable. I'm closing this again and I'm locking it to prevent this already humongous thread from growing bigger.
|
I might be open to bundling libsodium in addition to openssl but that should be its own issue because there will be numerous details to hash out. We sure as heck are not going to ship something homegrown and until openssl grows the requisite APIs there isn't anything actionable. I'm closing this again and I'm locking it to prevent this already humongous thread from growing bigger. |
bnoordhuis
closed this
May 31, 2017
nodejs
locked and limited conversation to collaborators
May 31, 2017
ChALkeR
added
the
ctc-agenda
label
Jun 1, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ChALkeR
Jun 1, 2017
Member
@MylesBorins Re: FIPS compliance — if libsodium randombytes.c is not compliant and if FIPS compliance is desired, that could be fixed with a runtime flag that switches back the impl to OpenSSL (as we won't stop bundling OpenSSL nevertheless). Also, see this link.
|
@MylesBorins Re: FIPS compliance — if libsodium |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
sam-github
Jun 1, 2017
Member
Note that openssl 1.1 won't be FIPS compliant for quite a while, so FIPS users will need to stick to a node built on 1.0. cf. https://www.openssl.org/blog/blog/2016/07/20/fips/
I'm still hopeful that OpenSSL will deal with this for us, I'm not saying we should be thinking of libsodium for 8.x, but I don't think FIPS would be a blocker if we go looking elsewhere for a PRNG. Also, I'm not sure random seeds are covered by FIPS, anyway, that would take some looking into.
|
Note that openssl 1.1 won't be FIPS compliant for quite a while, so FIPS users will need to stick to a node built on 1.0. cf. https://www.openssl.org/blog/blog/2016/07/20/fips/ I'm still hopeful that OpenSSL will deal with this for us, I'm not saying we should be thinking of libsodium for 8.x, but I don't think FIPS would be a blocker if we go looking elsewhere for a PRNG. Also, I'm not sure random seeds are covered by FIPS, anyway, that would take some looking into. |
ChALkeR
removed
the
ctc-agenda
label
Jun 7, 2017
mhdawson
reopened this
Jun 8, 2017
nodejs
unlocked this conversation
Jun 8, 2017
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
shigeki
Aug 3, 2017
Contributor
Note that OpenSSL has just landed a commit to use DRGB with AES-CTR of NIST SP 800-90A as openssl/openssl@75e2c87. We can use it with the os-specific seeding source (e.g. /dev/urandom) by a default define flag of OPENSSL_RAND_SEED_OS.
I think it is best for us to wait for the next release of OpenSSL-1.1.1.
|
Note that OpenSSL has just landed a commit to use DRGB with AES-CTR of NIST SP 800-90A as openssl/openssl@75e2c87. We can use it with the os-specific seeding source (e.g. /dev/urandom) by a default define flag of |
added a commit
to saghul/libuv
that referenced
this issue
Aug 15, 2017
bdharrington7
referenced this issue
Nov 1, 2017
Closed
Has the nodejs crypto module been audited at all? #16662
Trott
removed
the
discuss
label
Mar 11, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
davisjam
Mar 13, 2018
Contributor
[Edited arguments for and against based on feedback]
I'm going to attempt to summarize the conversation and arguments that have happened on this issue. Sorry if I missed your post, I can amend.
Preliminaries
@speakeasypuncture initially opened this issue.
Per @joepie91, this issue is about Node's crypto.randomBytes. (Statement).
Issue statement
Node's crypto.randomBytes may not be cryptographically secure.
- Operating systems expose a "system" RNG (Cryptographically Secure Pseudo-Random Number Generator or CSPRNG) which offers the best source of randomness on the system.
- Rather than use the system RNG, Node.js relies on OpenSSL for
crypto.randomBytes. - OpenSSL can be no more secure than the system RNG, and may be less secure. OpenSSL's use of a user-space CSPRNG on top of the kernel's CSPRNG is unnecessary and simply adds a layer of vulnerability.
I do not believe anyone has claimed that OpenSSL's CSPRNG is currently broken, although @ChALkeR pointed out some reasons why it might not be trustworthy.
Proposal
Node should consider an alternative implementation for random numbers that is definitely derived securely.
- @azet says that libsodium is a better option for random numbers than OpenSSL is, because libsodium underwent a review.
- @FiloSottile here and @ircmaxell here add that avoiding reliance on a user-space CSPRNG, whether derived from a kernel CSPRNG or not, would reduce Node's attack surface.
Arguments against
The major arguments from the Node maintainers (and I may be reading between the lines a little bit) appear to be:
- @bnoordhuis here and @sam-github here: if Node's security is broken because of issues in OpenSSL, it seems like the right answer is to pursue enhancements to OpenSSL. @shigeki here says that efforts along these lines are underway.
- Code inertia. The OpenSSL-based implementation works. Changing the implementation to one derived from another library means investing time and energy into development and maintenance.
Peer pressure
- @azet said Python uses the system CSPRNG rather than a user-space CSPRNG.
- @paragonie-scott pointed to PHP's implementation (link), and @azet pointed to Ruby's.
- @bnoordhuis indicated that implementing PRNG logic in Node directly seemed undesirable.
My impressions
- This proposal seems unlikely to result in motion from the Node maintainers until the OpenSSL API is available.
- It seems like adopting libsodium would lead to unnecessary code churn because the OpenSSL API is on its way, albeit perhaps slowly.
- In the interim, if security-conscious developers don't trust OpenSSL, they can use an npm module or an add-on that accesses platform-specific sources of randomness directly.
|
[Edited arguments for and against based on feedback] I'm going to attempt to summarize the conversation and arguments that have happened on this issue. Sorry if I missed your post, I can amend. Preliminaries@speakeasypuncture initially opened this issue. Issue statementNode's
I do not believe anyone has claimed that OpenSSL's CSPRNG is currently broken, although @ChALkeR pointed out some reasons why it might not be trustworthy. ProposalNode should consider an alternative implementation for random numbers that is definitely derived securely.
Arguments againstThe major arguments from the Node maintainers (and I may be reading between the lines a little bit) appear to be:
Peer pressure
My impressions
|
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
paragonie-scott
Mar 13, 2018
There's an upstream proposal to make OpenSSL create the equivalent of libsodium's randombytes_sysrandom() (which uses the OS's CSPRNG) which Node could then use instead of the userspace PRNG. This isn't close-worthy, it's stalled until OpenSSL does something.
Swapping out one userspace PRNG for another userspace PRNG is not a fix. Bypassing the userspace and using the OS's CSPRNG is the solution.
paragonie-scott
commented
Mar 13, 2018
•
|
There's an upstream proposal to make OpenSSL create the equivalent of libsodium's Swapping out one userspace PRNG for another userspace PRNG is not a fix. Bypassing the userspace and using the OS's CSPRNG is the solution. |
Trott
added
stalled
and removed
stalled
labels
Mar 13, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bnoordhuis
Mar 13, 2018
Member
This isn't close-worthy, it's stalled until OpenSSL does something.
It's not actionable at the moment and won't be for a long time to come. Inactionable items clog up the bug tracker so I'll close this out for now. We can revisit when we upgrade to an openssl version that supports this new API.
It's not actionable at the moment and won't be for a long time to come. Inactionable items clog up the bug tracker so I'll close this out for now. We can revisit when we upgrade to an openssl version that supports this new API. |
bnoordhuis
closed this
Mar 13, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
ChALkeR
Mar 13, 2018
Member
@bnoordhuis How are we going to remember to revisit it, then?
Perhaps introducing a separate label for temporary-inactionable items that were closed just because of that is needed so we don't forget to revisit?
|
@bnoordhuis How are we going to remember to revisit it, then? Perhaps introducing a separate label for temporary-inactionable items that were closed just because of that is needed so we don't forget to revisit? |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
bnoordhuis
Mar 13, 2018
Member
We go over the changelog with a fine-tooth comb whenever we upgrade (at least I do) so it's unlikely that such a change would go unnoticed.
Perhaps introducing a separate label for temporary-inactionable items that were closed just because of that is needed so we don't forget to revisit?
I'm not completely opposed.
|
We go over the changelog with a fine-tooth comb whenever we upgrade (at least I do) so it's unlikely that such a change would go unnoticed.
I'm not completely opposed. |
ChALkeR
added
the
revisit later
label
Mar 13, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
FiloSottile
Mar 14, 2018
Thanks for summarizing, but I don't think that captures the point. We are not advocating for reimplementing something that's in a library (for whatever reason), but for removing the library entirely. The library implements a user-space CSPRNG on top of kernel entropy, it might be good or bad, doesn't matter, we are arguing for not using one at all.
What you say is valid about primitives, which have to be implemented somewhere, but here we are talking about removing a layer from a system, where each layer is an independent point of failure.
As for "they are the ones that know about security", OpenSSL is bound by a lot of legacy, BoringSSL and libsodium are widely regarded as secure modern implementations, and those use the kernel CSPRNG.
FiloSottile
commented
Mar 14, 2018
|
Thanks for summarizing, but I don't think that captures the point. We are not advocating for reimplementing something that's in a library (for whatever reason), but for removing the library entirely. The library implements a user-space CSPRNG on top of kernel entropy, it might be good or bad, doesn't matter, we are arguing for not using one at all. What you say is valid about primitives, which have to be implemented somewhere, but here we are talking about removing a layer from a system, where each layer is an independent point of failure. As for "they are the ones that know about security", OpenSSL is bound by a lot of legacy, BoringSSL and libsodium are widely regarded as secure modern implementations, and those use the kernel CSPRNG. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
davisjam
Mar 14, 2018
Contributor
@FiloSottile Thanks, I've amended my post. Holler if you're still unhappy with my representations.
|
@FiloSottile Thanks, I've amended my post. Holler if you're still unhappy with my representations. |
speakeasypuncture commentedMar 19, 2016
randomBytes uses OpenSSL as its random number generator. It would be wiser and less errorprone to use a system RNG like urandom on Unix platforms, getrandom syscall on Linux and CryptGenRandom on Windows.