openfire登录验证AuthProvider

以前一直发现openfire数据库里面的密码是什么加密格式的,但是总弄不清楚,即便是同样的明文密码,在数据库中保存的结果却是不一样的。

今天又从登录入口查找,查到DefaultAuthProvider中的

public String getPassword(String username) throws UserNotFoundException 

方法。在其中设置如下代码

 

String plainText = rs.getString(1);
			String encrypted = rs.getString(2);
			if (encrypted != null) {
				try {
					String plainPass = AuthFactory.decryptPassword(encrypted);
					System.out.println(plainPass);
					System.out.println(AuthFactory.encryptPassword(plainPass));
					System.out.println(AuthFactory.encryptPassword(plainPass));
					System.out.println(AuthFactory.encryptPassword(plainPass));
					return AuthFactory.decryptPassword(encrypted);
				} catch (UnsupportedOperationException uoe) {
					// Ignore and return plain password instead.
				}
			}

 

 

打印的结果如下:

123456

cb669f302c1ae6c20d703cf985b4cfb416bf14c308cae75c

42695c45901a59f58f6594a25ee186aaef22af3039b1fdea

170658949dbcb31a4b6656fdd748f1bc6414f5f1df226211

 

发现即便是同样的明文密码,经过相同的加密方法,得到的结果却不一样。

于是,我查找到了AuthFactory中的

 

public static String decryptPassword(String encryptedPassword) {
        if (encryptedPassword == null) {
            return null;
        }
        Blowfish cipher = getCipher();
        if (cipher == null) {
            throw new UnsupportedOperationException();
        }
        return cipher.decryptString(encryptedPassword);
    }

 private static synchronized Blowfish getCipher() {
        if (cipher != null) {
            return cipher;
        }
        // Get the password key, stored as a database property. Obviously,
        // protecting your database is critical for making the
        // encryption fully secure.
        String keyString;
        try {
            keyString = JiveGlobals.getProperty("passwordKey");
            if (keyString == null) {
                keyString = StringUtils.randomString(15);
                JiveGlobals.setProperty("passwordKey", keyString);
                // Check to make sure that setting the property worked. It won't work,
                // for example, when in setup mode.
                if (!keyString.equals(JiveGlobals.getProperty("passwordKey"))) {
                    return null;
                }
            }
            cipher = new Blowfish(keyString);
        }
        catch (Exception e) {
            Log.error(e.getMessage(), e);
        }
        return cipher;
    }

 由以上代码可以看出,加密以及解密过程都是由 Blowfish 方法提供。

 

我又将上面加密的密码做了一个解密的例子

public class Test1 {

	public static void main(String[] args) {
		Blowfish blow = new Blowfish("4dbKrqSsqQdUk3c");
		System.out
				.println(blow
						.decryptString("c96d8464e6d01a70f39a2e44c4a5cc634b367e021b3a5f20"));
		System.out
				.println(blow
						.decryptString("42d812e85a602f479871acebe0a3987658abb6184fbb132f"));
		System.out
				.println(blow
						.decryptString("1c037aafe1fc7d653cd9bfab7f126aeba9a4abadfe479c8f"));
	}

}

 

 

输出如下:

123456

123456

123456

 

 由此可以看出,只要系统属性的passwordKey值不变化,无论加过密的密码是啥样子的,只要明文相同,就可以恢复成原来相同的明文

此特性是blowfish提供

 

Blowfish是1993年布鲁斯·施奈尔开发的对称密钥区块加密算法,区块长为64位,密钥为1至448位的可变长度。[1]DES等算法相比,其处理速度较快。因为其无须授权即可使用,作为一种自由授权的加密方式在SSH、文件加密软件等被广泛地使用。

猜你喜欢

转载自linyu19872008.iteye.com/blog/1870257