From 96af089efa1ac225a3a44f6f02c70a322f13f4d5 Mon Sep 17 00:00:00 2001 From: pklimai Date: Sat, 27 Aug 2016 23:11:22 +0300 Subject: [PATCH 1/8] Changed print call to support Python 3 --- junosdecode.py | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/junosdecode.py b/junosdecode.py index 5c6b3ee..f735b59 100755 --- a/junosdecode.py +++ b/junosdecode.py @@ -8,7 +8,8 @@ ## original: http://search.cpan.org/dist/Crypt-Juniper/lib/Crypt/Juniper.pm ## requires python 2.7 due to use of dict comprehension ## -## version 1.0 +## version 1.01 - works with python 3 +## ## import sys @@ -44,7 +45,7 @@ def _nibble(cref, length): nib = cref[0:length] rest = cref[length:] if len(nib) != length: - print "Ran out of characters: hit '%s', expecting %s chars" % (nib, length) + print("Ran out of characters: hit '%s', expecting %s chars" % (nib, length)) sys.exit(1) return nib, rest @@ -56,7 +57,7 @@ def _gap(c1, c2): def _gap_decode(gaps, dec): num = 0 if len(gaps) != len(dec): - print "Nibble and decode size not the same!" + print("Nibble and decode size not the same!") sys.exit(1) for x in range(0, len(gaps)): num += gaps[x] * dec[x] @@ -92,11 +93,11 @@ def main(): parser.error("wrong number of arguments") encrypted_string = args[0] - print "junos password decrypter" - print "python version by matt hite" - print "original perl version by kevin brintnall\n" - print "encrypted version: %s" % encrypted_string - print "decrypted version: %s" % juniper_decrypt(encrypted_string) + print("junos password decrypter") + print("python version by matt hite") + print("original perl version by kevin brintnall\n") + print("encrypted version: %s" % encrypted_string) + print("decrypted version: %s" % juniper_decrypt(encrypted_string)) if __name__ == "__main__": main() From 2bfeabfe5d3cdc4ba0fcdefd6f5ef5a088169dd5 Mon Sep 17 00:00:00 2001 From: pklimai Date: Sat, 27 Aug 2016 23:13:44 +0300 Subject: [PATCH 2/8] Update README --- README | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README b/README index e69de29..d0081ad 100644 --- a/README +++ b/README @@ -0,0 +1,9 @@ +Example usage (note enclosing password in SINGLE quotes!): + +$ python junosdecode.py '$9$jBkm5n/tIEyCAeWLxVb.P5' +junos password decrypter +python version by matt hite +original perl version by kevin brintnall + +encrypted version: $9$jBkm5n/tIEyCAeWLxVb.P5 +decrypted version: Jun1pEr From bd3c52c78b1e45d4dc5155d89b685fa6664975a8 Mon Sep 17 00:00:00 2001 From: Min Song Date: Sat, 27 May 2017 22:36:54 +0900 Subject: [PATCH 3/8] updated README w/ usage and examples --- README | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README b/README index e69de29..2c51c49 100644 --- a/README +++ b/README @@ -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 +``` From 6564a07e6c6c4daf7e9eebf417b9fc82866fc4c6 Mon Sep 17 00:00:00 2001 From: Min Song Date: Sat, 27 May 2017 22:37:40 +0900 Subject: [PATCH 4/8] added juniper_encrypt and sub functions --- junosdecode.py | 83 ++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 12 deletions(-) mode change 100755 => 100644 junosdecode.py diff --git a/junosdecode.py b/junosdecode.py old mode 100755 new mode 100644 index 5c6b3ee..88edcf4 --- a/junosdecode.py +++ b/junosdecode.py @@ -11,8 +11,15 @@ ## version 1.0 ## +############################################################################# +## added juniper_encrypt and the necessary functions +## by Minsuk Song , who also knows +## very little perl +## + import sys -from optparse import OptionParser, OptionGroup +import argparse +import random ################################################################# ## globals @@ -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() From 76560578bb2cb2eb5c40da9c0745f1eaec65c3cd Mon Sep 17 00:00:00 2001 From: Minsuk Song Date: Sat, 27 May 2017 22:39:34 +0900 Subject: [PATCH 5/8] Rename README to README.md --- README => README.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename README => README.md (100%) diff --git a/README b/README.md similarity index 100% rename from README rename to README.md From 7a82a0b7c4ad737f7c6a954ce131999c88f299d0 Mon Sep 17 00:00:00 2001 From: Chris Iverson Date: Tue, 26 Sep 2017 10:43:49 -0500 Subject: [PATCH 6/8] Remove "version" argument from ArgumentParser constructor The Python 3 argparse module does not appear to support the "version" named argument in the same way that Python 2 does. Removing "version" argument. --- junosdecode.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/junosdecode.py b/junosdecode.py index 2b96d3f..173c431 100644 --- a/junosdecode.py +++ b/junosdecode.py @@ -134,8 +134,7 @@ def juniper_encrypt(plaintext, salt = None): def main(): - parser = argparse.ArgumentParser(description="Junos $9$ password en/decrypt script", - version="1.0") + parser = argparse.ArgumentParser(description="Junos $9$ password en/decrypt script") 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") @@ -160,3 +159,4 @@ def main(): if __name__ == "__main__": main() + \ No newline at end of file From e6a715fa64d19c0b564134c8f65455ee0be727b8 Mon Sep 17 00:00:00 2001 From: Chris Iverson Date: Tue, 26 Sep 2017 14:28:58 -0500 Subject: [PATCH 7/8] Added back --version, added --result-only Added back a Python 3 compatible --version option, added a --result-only option to display just the converted string, without filler text or source string. --- junosdecode.py | 33 ++++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/junosdecode.py b/junosdecode.py index 173c431..4c6c42f 100644 --- a/junosdecode.py +++ b/junosdecode.py @@ -17,11 +17,14 @@ ## by Minsuk Song , who also knows ## very little perl ## +from __future__ import print_function import sys import argparse import random + + ################################################################# ## globals @@ -135,6 +138,9 @@ def juniper_encrypt(plaintext, salt = None): def main(): parser = argparse.ArgumentParser(description="Junos $9$ password en/decrypt script") + parser.add_argument('-v','--version', action='version', version='%(prog)s 1.01') + parser.add_argument("-r","--result-only", action="store_true", dest="resultOnly", help="Output resulting string only") + 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") @@ -144,19 +150,28 @@ def main(): sys.exit(1) args = parser.parse_args() - - print("Junos $9$ secrets en/decrypter") - print("python version by matt hite/min song") - print("original perl version by kevin brintnall\n") + if not args.resultOnly: + print("Junos $9$ secrets en/decrypter") + print("python version by matt hite/min song") + print("original perl version by kevin brintnall\n") + if args.secret: encrypted_string = args.secret - print("encrypted version: %s" % encrypted_string) - print("decrypted version: %s" % juniper_decrypt(encrypted_string)) + + if args.resultOnly: + print(juniper_decrypt(encrypted_string), end='') + else: + 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 args.resultOnly: + print(juniper_encrypt(plaintext_string), end='') + else: + print("plaintext version: %s" % plaintext_string) + print("encrypted version: %s" % juniper_encrypt(plaintext_string)) if __name__ == "__main__": main() - \ No newline at end of file + From 8ab1b87d3b29a88561f11b0f40de272e1657ed3c Mon Sep 17 00:00:00 2001 From: Chris Iverson Date: Tue, 26 Sep 2017 14:37:35 -0500 Subject: [PATCH 8/8] Updated README Updated README with new flag and examples --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c51c49..76d8ed1 100644 --- a/README.md +++ b/README.md @@ -3,17 +3,19 @@ ## Usage ``` $ python junosdecode.py -usage: junosdecode.py [-h] [-v] [-e PLAINTEXT | -d SECRET] +usage: junosdecode.py [-h] [-v] [-r] [-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 + -r, --result-only Output resulting string only -e PLAINTEXT, --encrypt PLAINTEXT encrypt plaintext -d SECRET, --decrypt SECRET decrypt secret + ``` ## Examples @@ -33,4 +35,10 @@ original perl version by kevin brintnall encrypted version: $9$lateMXVb2JGi7-Dk decrypted version: hello + +$ python junosdecode.py -r -e 'hello' +$9$BrKEcyLX-Y2avWYoGif5/CA + +$ python junosdecode.py -r -d '$9$BrKEcyLX-Y2avWYoGif5/CA' +hello ```