Skip to content

Instantly share code, notes, and snippets.

@daemonkeeper
Last active November 12, 2017 02:12
Show Gist options
  • Select an option

  • Save daemonkeeper/188fbfa2e4197014299b8c548bb1960a to your computer and use it in GitHub Desktop.

Select an option

Save daemonkeeper/188fbfa2e4197014299b8c548bb1960a to your computer and use it in GitHub Desktop.
Junos reversible passphrase generator
def junos_crypt(plain, salt=None, stable_crypt=False):
"""
create and return a reversible Junos crypted passphrase,
which can be used as a passphrase in places where the plain
text must be accessible to the RE, such as BGP peerings
:param plain: plain text passphrase
:param salt: salt
:param stable_crypt: always return the same hash without rotation
heavily inspired by http://search.cpan.org/dist/Crypt-Juniper/lib/Crypt/Juniper.pm
"""
FAMILY = ["QzF3n6/9CAtpu0O", "B1IREhcSyrleKvMW8LXx", "7N-dVbwsY2g4oaJZGUDj", "iHkq.mPf5T"]
EXTRA = dict()
for x, item in enumerate(FAMILY):
for c in item:
EXTRA[c] = 3 - x
NUM_ALPHA = [x for x in "".join(FAMILY)]
ALPHA_NUM = {NUM_ALPHA[x]: x for x in range(0, len(NUM_ALPHA))}
ENCODING = [[1, 4, 32], [1, 16, 32], [1, 8, 32], [1, 64], [1, 32], [1, 4, 16, 128], [1, 32, 64]]
def _randc(cnt=0, stable_crypt=False):
r = ''
while cnt > 0:
if stable_crypt:
r += NUM_ALPHA[cnt]
else:
r += random.choice(NUM_ALPHA)
cnt -= 1
return r
def _gap_encode(pc, prev, enc):
chr_ord = ord(pc)
crypt = ''
gaps = []
for mod in reversed(enc):
gaps.insert(0, int(chr_ord / mod))
chr_ord %= mod
for gap in gaps:
gap += ALPHA_NUM[prev] + 1
prev = NUM_ALPHA[gap % len(NUM_ALPHA)]
c = prev
crypt += c
return crypt
if not salt:
salt = _randc(1)
rand = _randc(EXTRA[salt], stable_crypt)
pos = 0
prev = salt
crypt = "$9$%s%s" % (salt, rand)
for p in plain:
encode = ENCODING[pos % len(ENCODING)]
crypt += _gap_encode(p, prev, encode)
prev = crypt[-1]
pos += 1
return crypt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment