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