Last active
August 19, 2017 17:24
-
-
Save JackZielke/b0bd3b887820bef55c164e7cc9541f1d to your computer and use it in GitHub Desktop.
Use random binary data to create various non-biased passwords
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/sh | |
| # Source of random data | |
| #DEV=/dev/urandom | |
| #DEV=/dev/random | |
| #DEV=/dev/hwrng | |
| DEV=/var/run/rtl_entropy.fifo | |
| # Remap unused characters | |
| # OWASP will no longer look like alphanum | |
| REMAP=1 | |
| OUT= | |
| for cmd in bc head sed tail tr xxd; do | |
| command -v $cmd >/dev/null || OUT="$OUT $cmd" | |
| done | |
| if test -n "$OUT"; then | |
| echo "The following required command(s) are missing:$OUT" | |
| exit 1 | |
| fi | |
| if test $# -ne 0; then | |
| if case $1 in (*[!0-9]*|"") false ;; (*) true ;; esac; then | |
| LEN=$1 | |
| else | |
| echo "$1 is not a number" | |
| exit 1 | |
| fi | |
| else | |
| LEN=64 | |
| fi | |
| H1= | |
| H2= | |
| C=1 | |
| S=0 | |
| while test $C -le $LEN; do | |
| if test $((C%10)) -eq 0; then | |
| H1="$H1$((C/10))" | |
| S=$((${#C}-2)) | |
| else | |
| if test $S -gt 0; then | |
| S=$((S-1)) | |
| else | |
| H1="$H1 " | |
| fi | |
| fi | |
| H2="$H2${C#${C%?}}" | |
| C=$((C+1)) | |
| done | |
| A= | |
| B= | |
| C= | |
| D= | |
| E= | |
| F= | |
| if test $REMAP -eq 1; then | |
| # 1.34738 from 1/(95/128) | |
| MULT=14 | |
| MAP="tr '\200-\377' '\000-\177'|tr '\000-\031' 'A-Z'|tr '\032-\057' 'a-v'|tr '\072-\075' 'w-z'|tr '\133-\140' '0-5'|tr '\173-\176' '6-9'" | |
| else | |
| # 2.41510 from 1/(53/128) | |
| MULT=25 | |
| MAP="tr '\200-\377' '\000-\177'" | |
| fi | |
| GET=$(($LEN*$MULT/10+1)) | |
| # Ensure base64 is not biased at the end | |
| if test $MULT -lt 8; then | |
| while test $((GET%3)) -ne 0; do | |
| GET=$((GET+1)) | |
| done | |
| fi | |
| # B needs the most data w/out remap, C needs the most data with remap | |
| while test ${#B} -lt $LEN -o ${#C} -lt $LEN; do | |
| echo -n . | |
| if test -z "$bin"; then | |
| bin="$(head -c$GET <"$DEV"|xxd -p -u|tr -d '\n')" | |
| else | |
| bin="$(head -c15 <"$DEV"|xxd -p -u|tr -d '\n')" | |
| fi | |
| if test ${#A} -lt $LEN; then | |
| A="$A$(echo -n $bin|xxd -r -p|eval $MAP|tr -dc A-Za-z0-9)" | |
| fi | |
| if test ${#B} -lt $LEN; then | |
| B="$B$(echo -n $bin|xxd -r -p|eval $MAP|tr -dc A-Za-z0-9|tr -d O0Il12Z5S|tr -s vV)" | |
| B="$(echo $B|tr -s vV)" | |
| fi | |
| if test ${#C} -lt $LEN; then | |
| C="$C$(echo -n $bin|xxd -r -p|tr '\200-\377' '\000-\177'|tr -dc 'A-Za-z0-9 !"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~')" | |
| C="$(echo $C|sed 's/\(.\)\1\1*/\1\1/g')" | |
| fi | |
| if test ${#D} -le $LEN; then | |
| OUT= | |
| MAX="$(echo "256^(${#bin}/2)-1"|BC_LINE_LENGTH=0 bc)" | |
| DEC="$(echo "ibase=16;obase=A;$bin"|BC_LINE_LENGTH=0 bc)" | |
| BUF=$(printf %0${#MAX}s|tr ' ' 0) | |
| T=1 | |
| while [ $T -lt ${#MAX} ]; do | |
| PRE=$(echo $MAX|head -c$T) | |
| DIV=$(printf '%s%*.*s' $PRE 0 $((${#MAX}-$T)) $BUF) | |
| if test $(echo $DIV-$DEC|BC_LINE_LENGTH=0 bc|head -c1) != '-'; then | |
| M=$((${#MAX}-$T)) | |
| DEC=$(echo -n $DEC|tail -c$M) | |
| # pad with zeros | |
| while test ${#DEC} -lt $M; do | |
| DEC="0$DEC" | |
| done | |
| OUT=$DEC | |
| break | |
| fi | |
| T=$((T+1)) | |
| done | |
| D="$D$OUT" | |
| fi | |
| if test ${#E} -le $LEN; then | |
| E="$E$bin" | |
| fi | |
| if test ${#F} -le $LEN; then | |
| F="$F$(echo -n $bin|xxd -r -p|base64 -w0)" | |
| fi | |
| done | |
| echo | |
| echo " $H1" | |
| echo " $H2" | |
| echo -n 'alphanum ' | |
| echo "$A"|head -c"$LEN";echo | |
| echo -n 'visual C&P ' | |
| echo "$B"|head -c"$LEN";echo | |
| echo -n 'OWASP ' | |
| echo "$C"|head -c"$LEN";echo | |
| echo -n 'digits ' | |
| echo "$D"|head -c"$LEN";echo | |
| echo -n 'raw hex ' | |
| echo "$E"|head -c"$LEN";echo | |
| echo -n 'base64 ' | |
| echo "$F"|head -c"$LEN";echo |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Accepts password length as the 1 parameter, defaults to 64 characters. The guide helps with copying a portion of the output.
alphanum - Uppercase letters, lowercase letters, and numbers.
visual C&P - alphanum with the following characters removed: O0Il12Z5S, consecutive v and V (vv and VV).
OWASP - alphanum plus 33 characters suggested by OWASP.
digits - Digits from the raw binary read as a number and stripping the leading digits as necessary.
raw hex - Raw input converted to hexadecimal.
base64 - Raw input converted to base64.
alphanum, visual C&P, and OWASP have the high bit dropped (128-255 are remapped to 0-127).
alphanum and visual C&P optionally have unused characters remapped without introducing bias.
digits, raw hex, and base64 use the raw input.
The script is called staticpass because I am using radio static as my random data source via rtl-entropy. The script is somewhat painfully written for dash in the hopes that it will be more portable.