#!/usr/bin/env python # Written by Wesley Wineberg - 2017 import sys import base64 from hashlib import sha256 from binascii import hexlify, unhexlify from Crypto.Cipher import AES MAGIC = "::::MAGIC::::" PAYLOAD_V1 = 1 def usage(): print "./jenkins-decrypt-newformat.py " print "ex: ./jenkins-decrypt-newformat.py master.key hudson.util.Secret {AQAAABAAAAAQGmAVAZnpBr0aqql/F07AEWczeipB/DID2Rt6UEYCDsM=}" sys.exit(0) def main(): if len(sys.argv) != 4: usage() # Check if payload V1 (aka, newish, password encryption) encdata = sys.argv[3] if not (encdata[0] == "{") or not (encdata[len(encdata)-1] == "}"): print "Wrong format for input credential - Doesn't appear to be using Jenkins \"new style\" encryption" print "Should be like this: {AQAAABAAAAAQGmAVAZnpBr0aqql/F07AEWczeipB/DID2Rt6UEYCDsM=}" exit() encraw = base64.decodestring(encdata) # The start of the encrypted data is just a header with the IV ivSize = int(hexlify(encraw[1:5]), 16) dataSize = int(hexlify(encraw[5:9]), 16) # Do the same check Jenkins does to make sure our header is good if (ivSize + dataSize + 9) != len(encraw): print "Error decoding input data header - Doesn't appear to be using Jenkins \"new style\" encryption" exit() iv = encraw[9:(9 + ivSize)] encString = encraw[(9 + ivSize):] # Decrypt the master key. Basically the same as https://github.com/tweksteen/jenkins-decrypt/blob/master/decrypt.py master_key = open(sys.argv[1], "rb").read() hudson_secret_key = open(sys.argv[2], "rb").read() hashed_master_key = sha256(master_key).digest()[:16] aesECB = AES.new(hashed_master_key, AES.MODE_ECB) decSecret = aesECB.decrypt(hudson_secret_key) assert MAGIC in decSecret decKey = decSecret[:-16] decKey = decKey[:16] # Now that we have the decryption key, the IV, and the encrypted data we can do the decrypt aesCBC = AES.new(decKey, AES.MODE_CBC, iv) decString = aesCBC.decrypt(encString) print decString if __name__ == '__main__': main()