-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Use crypto/rand for Id generation #102
Conversation
In case you haven't seen it, this came up previously in #48. |
This is somewhat faster than #48, but of course still slower. Numbers and benchmark below.
package main
import (
cr "crypto/rand"
"math/big"
mr "math/rand"
"testing"
"time"
)
func BenchmarkOriginal(b *testing.B) {
var sum int
for i := 0; i < b.N; i++ {
sum += int(uint16(mr.Int()) ^ uint16(time.Now().Nanosecond()))
}
_ = sum
}
func BenchmarkDiscordianfish(b *testing.B) {
var sum int
for i := 0; i < b.N; i++ {
id, e := cr.Int(cr.Reader, big.NewInt(0xFFFF))
if e != nil {
panic(e)
}
sum += int(uint16(id.Uint64()))
}
_ = sum
}
func BenchmarkTaruti(b *testing.B) {
var sum int
for i := 0; i < b.N; i++ {
var buf [2]byte
_, e := cr.Read(buf[:])
if e != nil {
panic(e)
}
sum += int(uint16(buf[0]) | (uint16(buf[1]) << 8))
}
_ = sum
} |
Thanks. But as I mentioned in #48 I'm not convinced: is the current random so bad? Also the real solution against spoofing is DNSSEC, the rest are tricks that
|
Yes, it is that bad. math/rand is not seeded with a random value unless the user does so explicitly. math/rand has 2**31-1 states (i.e. less than four bytes). Typically system clock nanosecond counts will be somewhat predictable depending on the os. |
I'm not convinced... If you care about spoofing DNSSEC is your friend anything else is a bandaid. I'm inclined to close this PR. |
Ok, no problem. Will just use a fork for our code. |
If there's not too much overhead, making |
Or a boolean in client, SecureId to flick it to use this? Or allow it to be
|
@miekg did you check what random sources other DNS servers are using? |
No I did not check other servers. The 16! bit id is way too small to give
|
On second, second thought we use math.Rand, so if nobody can show me: we could spoof Go dns in x seconds and with crypto.Rand it took 2x seconds I'm sceptical. |
Actually with using a random source port for every request (this can be done with the library out of box without any extra patches) one gets slightly more randomness (like 31 bits in total in a (w)lan, if going through nat to the name server it is reduced back...). Which makes the attacks somewhat harder. Of course DNSSEC (or having a nameserver in a VPN/over IPSEC/...) is the right solution, but that is not available in many cases. For example BIND8 had a weak PRNG and that did make spoofing easier (they analysed the outputs and made the attack based on the prng) and it was made somewhat better in BIND9. There were papers about that 5-10 years ago. |
If go dns does not randomize the source port that would be a bug. Honestly Re: Id function. This night I figured we can make it a variable pointing to
|
Actually I just pushed a change where Id is a variable which can reassigned to different function. |
Too many implementations have had problems with poor random ids and DNS spoofing attacks.