Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file removed README
Empty file.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Junos $9$ secrets encrypt/decrypt script

## Usage
```
$ python junosdecode.py
usage: junosdecode.py [-h] [-v] [-e PLAINTEXT | -d SECRET]

Junos $9$ password en/decrypt script

optional arguments:
-h, --help show this help message and exit
-v, --version show program's version number and exit
-e PLAINTEXT, --encrypt PLAINTEXT
encrypt plaintext
-d SECRET, --decrypt SECRET
decrypt secret
```

## Examples
```
$ python junosdecode.py -e 'hello'
Junos $9$ secrets en/decrypter
python version by matt hite/min song
original perl version by kevin brintnall

plaintext version: hello
encrypted version: $9$lateMXVb2JGi7-Dk

$ python junosdecode.py -d '$9$lateMXVb2JGi7-Dk'
Junos $9$ secrets en/decrypter
python version by matt hite/min song
original perl version by kevin brintnall

encrypted version: $9$lateMXVb2JGi7-Dk
decrypted version: hello
```
83 changes: 71 additions & 12 deletions junosdecode.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,15 @@
## version 1.0
##

#############################################################################
## added juniper_encrypt and the necessary functions
## by Minsuk Song <msuk.song@gmail.com>, who also knows
## very little perl
##

import sys
from optparse import OptionParser, OptionGroup
import argparse
import random

#################################################################
## globals
Expand Down Expand Up @@ -80,23 +87,75 @@ def juniper_decrypt(crypt):
decrypt += _gap_decode(gaps, decode)
return decrypt

def _reverse(my_list):
new_list = list(my_list)
new_list.reverse()
return new_list

def _gap_encode(pc, prev, encode):
_ord = ord(pc)

crypt = ''
gaps = []
for mod in _reverse(encode):
gaps.insert(0, int(_ord/mod))
_ord %= mod

for gap in gaps:
gap += ALPHA_NUM[prev] + 1
prev = NUM_ALPHA[gap % len(NUM_ALPHA)]
crypt += prev

return crypt

def _randc(cnt = 0):
ret = ""
for _ in range(cnt):
ret += NUM_ALPHA[random.randrange(len(NUM_ALPHA))]
return ret

def juniper_encrypt(plaintext, salt = None):
if salt is None:
salt = _randc(1)
rand = _randc(EXTRA[salt])

pos = 0
prev = salt
crypt = MAGIC + salt + rand

for x in plaintext:
encode = ENCODING[pos % len(ENCODING)]
crypt += _gap_encode(x, prev, encode)
prev = crypt[-1]
pos += 1

return crypt


def main():
parser = OptionParser(usage="usage: %prog [options] encrypted_string",
parser = argparse.ArgumentParser(description="Junos $9$ password en/decrypt script",
version="1.0")
group = parser.add_mutually_exclusive_group()
group.add_argument("-e", "--encrypt", dest="plaintext", help="encrypt plaintext")
group.add_argument("-d", "--decrypt", dest="secret", help="decrypt secret")

(options, args) = parser.parse_args()

# right number of arguments?
if len(args) < 1:
parser.error("wrong number of arguments")
if len(sys.argv) == 1:
parser.print_help()
sys.exit(1)
args = parser.parse_args()

encrypted_string = args[0]
print "junos password decrypter"
print "python version by matt hite"
print "Junos $9$ secrets en/decrypter"
print "python version by matt hite/min song"
print "original perl version by kevin brintnall\n"
print "encrypted version: %s" % encrypted_string
print "decrypted version: %s" % juniper_decrypt(encrypted_string)
if args.secret:
encrypted_string = args.secret
print "encrypted version: %s" % encrypted_string
print "decrypted version: %s" % juniper_decrypt(encrypted_string)
elif args.plaintext:
plaintext_string = args.plaintext
print "plaintext version: %s" % plaintext_string
print "encrypted version: %s" % juniper_encrypt(plaintext_string)


if __name__ == "__main__":
main()