40 comments

[ 3.0 ms ] story [ 95.4 ms ] thread
here's my lazy PW script, written in node. :)

   require('uuid').v4().split('-').join('')
Why remove the hyphens? If that’s wanted, there’s the more direct:

  crypto.randomBytes(16).toString('hex')
They don't _really_ affect your entropy that much (since the attacker doesn't know your character set in the first place), and some websites disallow certain characters.
A funny little flaw in this is that 13th character of those passwords is always "4", right?
(comment deleted)
And the character that was after the 3rd hyphen is always one of [89ab].
In Python for those who don't want to install node and run Debian / Ubuntu or any distro that includes Python out of the box:

>>> import uuid

>>> uuid.uuid4().hex

Interesting someone else mentioned the 14th character is always a 4... I am creeped out just a little bit (cause I never noticed).

That's because it indicates the version of uuid it is.
(comment deleted)
I was expecting something that would focus on the rules that so many sites impose. Length is easy, but many have silly rules where certain characters are not allowed.

Then there is the side of making a password that is easy to type on a phone. Ideally, I want a hard password that doesn't require me to change input mode on my phone too many times.

Well, ideally, I'd rather I could just use my security token everywhere... But that is a separate problem.

I have been thinking about that. How would one do that with a minimal impact on password security? Character sets are easy, but one could set some arbitrary limits on character frequency. I would probably generate a shitload of passwords and filter them based on the rules since that would mean not having to have complicated logic for password generation and thus not accidentally generating passwords that are less secure than the rule limitations.
I made this: https://pastebin.com/kQhKexEd in 5 minutes. It is however slightly off with the random distribution since I am only doing a simple remainder.

    (let ((byte (remainder (get-u8 urandom) size)))
is skewed if size isn't a power of 2. What you should do is mod by the next-largest power of 2 (e.g. if size is 82, mod by 128). Then if the result is in-range use it, otherwise discard and reroll.
I just edited the comment before I saw your answer. I realised my mistake and wanted to sink through the earth. Everyone has brain farts, I guess.

What I ended up doing was limiting the charset size to 256 a maximum of characters, and then discarding any value that is larger than the current charset.

I still think that the best approach to password requirements was the one used at Nortel. They ran a password hash cracking algorithm continuously on the PW database, and when they cracked yours you had to change it. Other than that there were no complexity requirements or mandatory change intervals. If you had a good complex password you got to keep it for a long time, and if you set '12345', 1 minute later you'd have to change it.
That is super cool. Is there any reading material on this somewhere?
I heard this anecdotally from a long time colleague of mine who worked there. I don't know of any more solid reference to give, sorry.
I use a Bash Script copied from Stack Overflow:

  #!/bin/bash
  choose() { echo ${1:RANDOM%${#1}:1} $RANDOM; }

  {
      choose '!@#$%^\&'
      choose '0123456789'
      choose 'abcdefghijklmnopqrstuvwxyz'
      choose 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
      for i in $( seq 1 $(( 4 + RANDOM % 8 )) )
      do
          choose '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
      done

  } | sort -R | awk '{printf "%s",$1}'
  echo ""
https://stackoverflow.com/questions/26665389/random-password...
Generating passwords with $RANDOM seems like an incredibly bad idea. In bash, it’s a Lehmer RNG seeded with the current microsecond and PID – and the seed is 32 bits. sort -R kind of saves it because it uses /dev/urandom + ISAAC, but it’s really not comfortable – 1/8 of passwords it generates are breakable in at most ~2^29 × 40320 attempts, for example (and the expected number could be much lower than that, I haven’t done the math).
(comment deleted)
as opposed to a manually designed password?
Depends on what your strategy for manually designing passwords is (yes, it’s that bad). But anyone who can figure out how to use this bash script can figure out how to use one of the `< /dev/urandom tr` scripts, pwgen, or a password manager.

  for i in ["".join(random.choice(wordlist) for x in range(5)) for y in range(20)]: 
    print (i)
Use secrets.choice instead of random.choice, since only the former is backed by a CSPRNG.
Or random.SytemRandom().choice if the secrets module is not available.
You can always open /dev/random and read bytes from there as well
This one-line shell script is a bit simpler:

    base64 /dev/urandom | head -c 16
(Vary the number of characters according to the desired entropy: you get 6 bits of entropy for each character of output, so 16*6 = 96 bits in the example. Use /dev/random or /dev/arandom if you prefer those random sources.)

For passphrases, use GNU shuf (from the coreutils package):

    shuf -n 4 --random-source=/dev/urandom /usr/share/dict/words
Also `openssl rand -hex 16` works pretty well :)
Even if one can just use `pwgen` on most linux plateforms, it's a fun exercice, and one that is always welcome in classrooms.

You need to parse the cmd, make sure you use the proper random generator, and accumulate different source of characters.

Options such as --allow-unicode, --exclude-similar-chars or --group-chars all provide small additional challenges in different areas.

It's something all students should code at least once, if not for pleasure, at least for practice.

But honestly I find it fun enough that I just wrote one again after reading the article. I'm pretty sure a timeline of all the attempts is telling of ones progression in style :)

Here's my biggest pet peeve when using password generators: passwords containing special symbols like (but not limited to) "-\/({^$:%" will just break in some random service and you'll stay a long time trying to escape them in the correct way until they work

Keep your sanity and avoid special characters.

I only run into banks hating those, and obscure websites I am pretty sure I don't bother going back to. I don't understand why they're such an issue, but now I have less keys for a hacker to guess.
Try setting it on an URL, on an environment variable or in a config file.
Why would you ever put a password on a URL though? That's really bad security. I understand what you mean, but passwords should be stored in some hashed / encrypted form.
I appreciate the follow through of showing how the package is set up. That's something a lot of articles or blog posts on racket seem to miss.
Is that nested-define common racket style? I know it's been legal, at least since R4RS, but I've never seen it actually done.
Not sure if it's common amongst Racketeers, but I've used it a few times in R6RS Scheme. It can help reduce nesting in complicated functions. But in these simple cases I think most would reach first for `let`.