認識Jenkins專有用戶數據庫

轉自Jenkins 中文社區java

認識Jenkins專有用戶數據庫

Jenkins 訪問控制分爲:安全域(即認證)與受權策略。git

其中,安全域能夠採用三種形式,分別爲:Jenkins 專有用戶數據庫、LDAP、Servlet 容器代理。github

=108&f=png&s=17000)

在哪裏看到加密後的用戶密碼信息?

Jenkins 專有用戶的數據信息存放位置:$JENKINS_HOME/users/算法

每一個用戶的相關信息存放在各自的 config.xml 文件中: JENKINS_HOME/users/user/config.xml數據庫

在 config.xml 文件中的 passwordHash 節點能夠看到用戶密碼加密後的密文哈希值:安全

用戶密碼是用什麼算法加密的呢?

那麼問題來了,用戶密碼是用何種加密方式加密的呢?能否經過解密密文獲得明文呢?工具

GitHub 上查看其源碼,經過關鍵字 #jbcrypt 搜索定位到 HudsonPrivateSecurityRealm.java 這個文件。 HudsonPrivateSecurityRealm.java 具體路徑是:jenkins/core/src/main/java/hudson/security/HudsonPrivateSecurityRealm.javaui

源碼片斷以下:加密

/** * {@link PasswordEncoder} that uses jBCrypt. */
    private static final PasswordEncoder JBCRYPT_ENCODER = new PasswordEncoder() {
        public String encodePassword(String rawPass, Object _) throws DataAccessException {
            return BCrypt.hashpw(rawPass,BCrypt.gensalt());
        }

        public boolean isPasswordValid(String encPass, String rawPass, Object _) throws DataAccessException {
            return BCrypt.checkpw(rawPass,encPass);
        }
    };
    /** * Combines {@link #JBCRYPT_ENCODER} and {@link #CLASSIC} into one so that we can continue * to accept {@link #CLASSIC} format but new encoding will always done via {@link #JBCRYPT_ENCODER}. */
    public static final PasswordEncoder PASSWORD_ENCODER = new PasswordEncoder() {
        /* CLASSIC encoder outputs "salt:hash" where salt is [a-z]+, so we use unique prefix '#jbcyrpt" to designate JBCRYPT-format hash. '#' is neither in base64 nor hex, which makes it a good choice. */
        public String encodePassword(String rawPass, Object salt) throws DataAccessException {
            return JBCRYPT_HEADER+JBCRYPT_ENCODER.encodePassword(rawPass,salt);
        }

        public boolean isPasswordValid(String encPass, String rawPass, Object salt) throws DataAccessException {
            if (encPass.startsWith(JBCRYPT_HEADER))
                return JBCRYPT_ENCODER.isPasswordValid(encPass.substring(JBCRYPT_HEADER.length()),rawPass,salt);
            else
                return CLASSIC.isPasswordValid(encPass,rawPass,salt);
        }

        private static final String JBCRYPT_HEADER = "#jbcrypt:";
    };
複製代碼

經過分析該源碼得知:spa

  1. 明文經過 jbcrypt 算法獲得密文 encPass
  2. 密文的格式爲:salt: encPass,其中以 #jbcrypt 表示 salt 做爲數據頭

jbcrypt 是什麼?

jbcrypt 是 bcrypt 加密工具的 java 實現。 它的 API 很是簡單,DEMO 以下,在 HudsonPrivateSecurityRealm.java 中能夠看到加密和校驗時使用了以下 API:

// Hash a password for the first time 
String hashed = BCrypt.hashpw(password, BCrypt.gensalt()); 

// gensalt's log_rounds parameter determines the complexity the work factor is 2**log_rounds, and the default is 10 
String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12)); 

// Check that an unencrypted password matches one that has previously been hashed 
if (BCrypt.checkpw(candidate, hashed)) 
  System.out.println("It matches"); 
else 
  System.out.println("It does not match");
複製代碼

經驗證,用 jbcrypt 對同一個明文加密後由於 salt 通常不一樣,加密後的密文通常不一樣。

bcrypt 精要概況

  1. bcrypt 是不可逆的加密算法,沒法經過解密密文獲得明文。
  2. bcrypt 和其餘對稱或非對稱加密方式不一樣的是,不是直接解密獲得明文,也不是二次加密比較密文,而是把明文和存儲的密文一塊運算獲得另外一個密文,若是這兩個密文相同則驗證成功。

總結

綜上, Jenkins 專有用戶數據庫使用了 jbcrypt 加密, jbcrypt 加密是不可逆的,並且對於同一個明文的加密結果通常不一樣。

相關文章
相關標籤/搜索