以前一直发现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、文件加密软件等被广泛地使用。