Dup Ver Goto 📝

PgenPasswordGenerator

PT2/aw/lang/python does not exist
To
171 lines, 679 words, 5135 chars Page 'PgenPasswordGenerator' does not exist.

See also PgenKivy, PgenQt and PgenCs

Pgen version 1

Equivalent of the following on a standard Gnu command line

echo "$input$secret" | md5sum | cut -c1-32 | base64 | cut -c1-16 | tr "+/" "@#"
#!/usr/bin/env python3

import hashlib
import base64
import sys
args = sys.argv[1:]
import os
env = os.environ

def hash(x):
    'Takes bytes x and returns md5 digest as bytes'
    x = x + b"\n"
    m = hashlib.md5()
    m.update(x)
    return m.hexdigest().encode("utf8")
def b64(x):
    'Takes bytes x and returns base64 encoding as string'
    return base64.b64encode(x).decode("utf8")
def tr(x):
    'equivalent of tr "+/" "@#"'
    return x.replace("/","@").replace("+","#")
def comb(i,s,schema=b"$I$S"):
    return schema.replace(b"$I",i).replace(b"$S",s)
def j(i,s,schema="$I$S"):
    i = i.encode("utf8")
    s = s.encode("utf8")
    schema = schema.encode("utf8")
    return tr(b64(hash(comb(i,s,schema))))

s = os.getenv("S","")
for x in args:
    print(j(x,s)[:16])

This version has a few flaws, in particular omitting the xxd -r -p to convert the hex string output by md5sum to binary before feeding it through base64. Thus the 16 character string output only captures half the entropy it should. Another is a relic of the bash version, and in particular the missing '-n' on the echo command. The Javascript implementation of this (versions 1 and 2) keeps these flaws when in Md5n mode.

Pgen version 2

Equivalent of the following on a standard Gnu command line.

echo "$input$secret" | sha256sum | cut -c1-64 | xxd -r -p | base64 | cut -c1-16 | tr "+/" "@#"
#!/usr/bin/env python3

import hashlib
import base64
import sys
args = sys.argv[1:]
import os
env = os.environ

def hash(x):
    'Takes bytes x and returns sha256 digest as bytes'
    m = hashlib.sha256()
    m.update(x)
    return m.digest()
def b64(x):
    'Takes bytes x and returns base64 encoding as string'
    return base64.b64encode(x).decode("utf8")
def tr(x):
    'equivalent of tr "+/" "@#"'
    return x.replace("+","@").replace("/","#")
def comb(i,s,schema=b"$I$S"):
    return schema.replace(b"$I",i).replace(b"$S",s)
def jj(i,s,schema="$I$S"):
    i = i.encode("utf8")
    s = s.encode("utf8")
    schema = schema.encode("utf8")
    return tr(b64(hash(comb(i,s,schema))))

s = os.getenv("S","")
for x in args:
    print(jj(x,s)[:16])

Pgen version 3

No bash command line equivalent, uses sha256 function iteratively 16384*n times where n is the length of the sequence (here the sequence is "in principio erat verbum et verbum erat apud deum et deus erat verbum")

#!/usr/bin/env python3

import hashlib
import base64
import sys
args = sys.argv[1:]
import os
env = os.environ

john1 = "in principio erat verbum et verbum erat apud deum et deus erat verbum".encode("utf8").split(b" ")

def hash(x):
    'Takes bytes x and returns sha256 digest as bytes'
    m = hashlib.sha256()
    m.update(x)
    return m.digest()
def jjjs(inp,sec,seq,n=16384):
    "inp cur seq are bytes() objects"
    x =inp 
    for i in range(n):
        for t in seq:
            x = hash(b"".join((t,sec,inp,x,sec,t)))
    return x
def jjjt(inp,sec):
    return jjjs(inp,sec,john1)

def b64(x):
    'Takes bytes x and returns base64 encoding as string'
    return base64.b64encode(x).decode("utf8")
def tr(x):
    'equivalent of tr "+/" "@#"'
    return x.replace("+","@").replace("/","#")

def jjj(inp,sec,n=16):
    return tr(b64(jjjt(inp,sec)))[:n]

s = os.getenv("S","").encode("utf8")
for x in args:
    print(jjj(x.encode("utf8"),s))

And if one wishes to have multiple 'secret' phrases, it is simple enough to append them to the sequence. Basically the idea here is to make a more processor intensive hashing function out of sha256. In addition, one can change the hash function to anything else. The key is that the process is repeatable. The versions 1 and 2 have the nice property that they can be expressed as a 1-line bash command (indeed, it works with /bin/dash too). In practice, version 2 is fine for most things, and version 3 is perhaps overkill.

Pgen version 3.1

I figure it is easier to iterate the x -> sha256 -> base64 -> x loop rather than something fancy like a sequence of words.

#!/usr/bin/env python3

import hashlib
import base64
import sys
args = sys.argv[1:]
import os
env = os.environ

# helpers for iterating sha
def sha256(x, coding='utf8'):
    return sha256_real(x.encode(coding)).decode(coding)
def sha256_real(x):
    sha = hashlib.sha256()
    sha.update(x)
    return base64.b64encode(sha.digest())
def sha_multi_round(x,n, coding='utf8'):
    return sha_multi_round_real(x.encode(coding),n).decode(coding)
def sha_multi_round_real(x,n):
    for j in range(n):
        x = sha256_real(x)
    return x

def b64(x):
    'Takes bytes x and returns base64 encoding as string'
    return base64.b64encode(x).decode("utf8")
def tr(x):
    'equivalent of tr "+/" "@#"'
    return x.replace("+","@").replace("/","#")

def jjj(inp,sec,n=16384,l=16):
    return tr(sha_multi_round(inp+sec,n))[:l]

s = os.getenv("S","")
for x in args:
    print(jjj(x,s))