Skip to content

Instantly share code, notes, and snippets.

@juyeong
Created October 28, 2016 02:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save juyeong/081379bd1ddb3754ed51ab8b8e535f7c to your computer and use it in GitHub Desktop.
Save juyeong/081379bd1ddb3754ed51ab8b8e535f7c to your computer and use it in GitHub Desktop.
Decrypt jenkins password / token
#!/usr/bin/env ruby
# refer to
# https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/hudson/util/Secret.java
# https://github.com/jenkinsci/jenkins/blob/master/core/src/main/java/jenkins/security/ApiTokenProperty.java
require 'base64'
require 'digest'
require 'openssl'
MAGIC = '::::MAGIC::::'
ALGORITHM = 'AES-128-ECB'
def try_decrypt(master_key, hudson_secret_key)
hashed_master_key = Digest::SHA256.digest(master_key)[0..15]
intermediate = OpenSSL::Cipher.new(ALGORITHM)
intermediate.decrypt
intermediate.key = hashed_master_key
salted_final = intermediate.update(hudson_secret_key) + intermediate.final
raise 'no magic key in a' unless salted_final.include?(MAGIC)
salted_final[0..15]
end
def main(filename, input)
abort "usage: #{filename} <master.key> <hudson.util.Secret> encryptedText" unless input.length == 3
master_key = File.read(input[0])
hudson_secret_key = File.read(input[1])
encrypted_text = Base64.decode64(input[2])
key = try_decrypt(master_key, hudson_secret_key)
cipher = OpenSSL::Cipher.new(ALGORITHM)
cipher.decrypt
cipher.key = key
text = cipher.update(encrypted_text) + cipher.final
text = text[0..(text.length-MAGIC.size-1)]
# if api token (md5 hash)
# text = Digest::MD5.new.update(text).hexdigest
puts text
end
if __FILE__ == $0
main(__FILE__, ARGV)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment