-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Secure random documentation #32957
Secure random documentation #32957
Conversation
Ok, we cannot use this. On 1.1 linux:
Whatever we recommend here, people will use it on old julia versions as well. And this is catastrophic failure, far worse than a segfault. Any ideas what else to recommend? |
On v1.3+ that should work. So maybe the idea of adding a new name |
Can the boilerplate text be shortened? Could I assume 128-bit is the current recommendation, and I'm also thinking will that always be enough? It seems I think the unlimited version is always ok (and Windows doesn't have a choice, I assume it's non-urandom-like). I.e. I only see the non-
https://linux.die.net/man/4/urandom
https://en.wikipedia.org/wiki//dev/random
Also interesting: https://en.wikipedia.org/wiki/Lavarand |
This is nothing specific to It's also not terribly verbose or biolerplateful to get a securely filled random array: julia> rand(RandomDevice(), UInt64, 10)
10-element Array{UInt64,1}:
0x9546c9a14fd83fdf
0x08e6ce584f58e258
0xf5b9c89362242c2a
0x202adcafcc12be2e
0x11340a32242058ff
0xe642d98d0486a785
0xd89e2721abb45e72
0xd7768c51b766fcc7
0x15ddfa425e52c436
0xb57b1c3245a6bad8 |
Sure we could. But secure random is relevant for more than just gen_nonce, also e.g.
Exactly. The secure random has three aspects:
With implicit backporting I mean the following: People will read the newest docs, copy-paste into their application that runs on 1.0, and something happens. This something should either be good or fail loud and hard. Having copy-pastable code that leads to silent catastrophic failure on wrong julia versions would be suboptimal. One could consider including/exporting
and potentially also backport the initialization ( Then one should also explain the pitfalls: Do not to call
I am aware. The example I posted is terrible and wrong code, and people who write such a thing should be ashamed. It's just that, for the specific issue of crypto/security, I'd like to be more misuse resistant. A security-footgun is worse than a harmless-bug-footgun. |
As a side note, there is already an open PR for a global |
Another interesting link for |
@@ -26,6 +26,11 @@ unbounded integers, the interval must be specified (e.g. `rand(big.(1:6))`). | |||
Additionally, normal and exponential distributions are implemented for some `AbstractFloat` and | |||
`Complex` types, see [`randn`](@ref) and [`randexp`](@ref) for details. | |||
|
|||
!!! note | |||
The `MersenneTwister` used by unqualified `rand` or `randstring` calls is not suitable for |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It may be not clear for everyone what is meant by "unqualified" here, what about:
The
MersenneTwister
object used implicitly by unqualifiedrand
orrandstring
calls is ...
`bad_gen_nonce() = rand(Random.RandomDevice(), UInt128)`, in order to not cause performance degradation and an eventual | ||
`ERROR: SystemError: opening file "/dev/urandom": Too many open files`. | ||
|
||
The `RandomDevice` reads and caches `/dev/urandom` on Unix-derived systems, and uses appropriate `Ntsecapi.h` calls on Windows. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will trust you on this fact concerning Windows, but I infer from the name of the file that it's a CSPRNG?
@@ -66,6 +71,18 @@ Random.MersenneTwister | |||
Random.RandomDevice | |||
``` | |||
|
|||
## Cryptographically secure random numbers | |||
|
|||
The Julia standard library does not provide a native cryptographically secure random number generator. For most applications, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By "native", you mean written in Julia? I find it's easy to interpret this sentence as "you can't get CSPRNG" from the Random
module, which seems to be contradicted in the next sentence...
|
||
The Julia standard library does not provide a native cryptographically secure random number generator. For most applications, | ||
we recommend to use the operating system `RandomDevice()`. This should be initialized via a module-level | ||
`const SECURE_RANDOM = Random.RandomDevice()` and subsequently used via e.g. `gen_nonce() = rand(SECURE_RANDOM, UInt128)`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only by the name SECURE_RANDOM
we can infer that indeed RandomDevice
is secure, it should be stated explicitly.
What about: pushing I don't know the performance impact of using a lock, relatively to the cost of generating numbers for |
I feel that this is something a package needs to address - having cryptographically secure random numbers. Saying what Julia's RNGs do not provide (or any other software) is usually a long list. I don't think we need to spell it out in the Julia documentation itself. However, a package that provided cryptographically secure random numbers could talk at length about these issues. |
One possible resolution for #32954 is to simply document that people should use
Random.RandomDevice()
.This is not just "improve some docs", it is an actual recommendation, and a commitment that we will care about security in our wrapper for the OS random.
Hence, this needs more review than usual docfixes.
To start with, the windows, linux, freebsd, openbsd, netbsd, macos all promise secure random. Are there any crazy supported systems that are known to fail here?
Am I understanding right that libuv ensures that this is thread-safe? What happens on older julia versions if multiple threads read from the same random device? Good (all works), fail (segfault) or catastrophic fail (same random emitted multiple times)?
Then there is the buffering by libuv. Are there any issues?