Take the 2-minute tour ×
Information Security Stack Exchange is a question and answer site for Information security professionals. It's 100% free, no registration required.

So I have this web app where I'm supposed to generate my own session key to use in the session manager. I just have few questions about safe approaches to this.

  • I believe to make this safe it should be a randomly generated key and is unique in every instance of my web app processes. Is my assumption correct?

  • I'm using Go 1.2 for my web app and the way I'm generating this random string is by using the following function:

    func generateRandomSessionKey() string {
      rand.Seed(time.Now().UnixNano())
      alpha := "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789~!@#$%^&{}[]:,.*()_+-/?><."
      buf := make([]byte, KEYLENGTH)
    
        for i := 0; i < KEYLENGTH; i++ {
            buf[i] = alpha[rand.Intn(len(alpha))]
        }
    
     return string(buf)
    }
    

This function produces strings like: Hu@$pMaNZd.2)%Lpeet{6hYmKAxn:yYt

Now I know that some might argue why not use "crypto/rand" instead of "math/rand" which is proven to be more secure, I have tried that and apparently the crypto/rand generated invalid strings e.g. \x16 that cannot be used by the web framework I'm using ( Beego). So is what I'm doing here a sensible and secure approach to generate this key?

share|improve this question
    
If there are privacy regulations in play, you should absolutely check to see if you happen to hit that one rare case when you happen to generate a random key that is already in use. "The chances of that happening are so low they're practically nonexistant" doesn't play well on public media, which is where some regulations in some regulated industries have you report privacy breaches (among other areas, fines, etc). –  Anti-weakpasswords Mar 3 at 1:05

2 Answers 2

up vote 3 down vote accepted

crypto/rand generates binary strings. Of course, binary strings cannot be used directly as plain text. You have to encode them into an appropriate text representation first (e.g. base64). Similar to your provided code you could use crypto/rand as follows:

import ("crypto/rand")

func rndString(n int) string {
    const alpha = "abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789~!@#$%^&{}[]:,.*()_+-/?><."
    var bytes = make([]byte, n)
    rand.Read(bytes)
    for i := 0; i < n; i++ {
        bytes[i] = alpha[bytes[i] % byte(len(alpha))]
    }
    return string(bytes)
}

You should never seed the random number generator with the unix time. For any time an attacker could generate valid sessions very easily. If you are on a Linux system and if you really want to seed a PRNG you should read the seed from /dev/urandom which can be treated as a regular file on Linux systems.

share|improve this answer
    
I thought I read somewhere that seeding random with time is bad, I just wanted to make sure. Thanks for the answer. –  Meldar Mar 3 at 12:43

I have tried that and apparently the crypto/rand generated invalid strings e.g. \x16 that cannot be used by the web framework I'm using.

What you should do is take the data generated by crypto/rand and re-encoding it in a way that matches what your web framework requires. You should mention what the framework is in asking the question and you should try to match your output to what the input is exactly.

rand.Seed(time.Now().UnixNano())

That's a bad idea. I can easily guess that based on what time it is and duplicate the results on my end.

share|improve this answer
    
Sorry I failed to mention the web framework name which is Beego. I'll keep your points in mind, thanks for the answer. –  Meldar Mar 3 at 12:45

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.