起因: 有 个项目采用nifi作为中间件,进行数据的批处理.nifi使用简单,容易上手,非常方便.nifi可以在页面配置连接数据库,然后nifi会把
密码加密,然后保存在flow.xml文件中.我们开发这个项目给客户用之后,不想让他们访问nifi页面去修改密码,这样也不是很方便,想直接让现场的运维人员
通过修改配置文件即可操作.然后我就开始了看nifi的源码.
心酸历程: 首先第一次从nifi的源码中,找了很多的数据库连接配置和加密的类,都没有找到加密和解密方法.然后找到nifi有tools项目,然后开始了看了源码,找到了破解之路
nifi使用加密: 已经写好了nifi加密算法nifi数据库密码加密
nifi使用加密算法为:
PBEWITHMD5AND256BITAES-CBC-OPENSSL
密码长度为64位(ea2b8b8388eba5518b4b0e79e5f547efda95b20184580c5300fbe968a7222252) test的密码
如果要使用该算法,需要导入往jdk导入jar包(可以自行网上搜索,等有空再写上步骤)
加密使用随机使用的16位的盐
代码:
package com.company;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.*;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
public class DecryptTest {
private static final String DEFAULT_FLOW_ALGORITHM = "PBEWITHMD5AND256BITAES-CBC-OPENSSL";
private static final String DEFAULT_PROVIDER = BouncyCastleProvider.PROVIDER_NAME;
//nififtw! 是口令,nifi默认的,当初就是没有找到他,花了好长时间
public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, BadPaddingException, IOException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeySpecException, InvalidKeyException, DecoderException {
System.out.println(decryptFlowElement("ea2b8b8388eba5518b4b0e79e5f547efda95b20184580c5300fbe968a7222252","nififtw!"));
}
//password是口令,saltBytes是盐
private static Cipher generateFlowDecryptionCipher(String password,byte[] saltBytes) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException {
Cipher decryptCipher = Cipher.getInstance(DEFAULT_FLOW_ALGORITHM, DEFAULT_PROVIDER);
PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DEFAULT_FLOW_ALGORITHM, DEFAULT_PROVIDER);
SecretKey pbeKey = keyFactory.generateSecret(keySpec);
PBEParameterSpec parameterSpec = new PBEParameterSpec(saltBytes, 1000);
decryptCipher.init(Cipher.DECRYPT_MODE, pbeKey, parameterSpec);
return decryptCipher;
}
//password是口令,text是需要解密的数据
private static String decryptFlowElement(String text, String password) throws DecoderException, NoSuchPaddingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeySpecException, BadPaddingException, IllegalBlockSizeException {
byte[] cipherBytes = Hex.decodeHex(text.toCharArray());
byte[] saltBytes = Arrays.copyOfRange(cipherBytes,0,16);
byte [] newCipherBytes = Arrays.copyOfRange(cipherBytes,16,cipherBytes.length);
Cipher decryptionCipher = generateFlowDecryptionCipher(password, saltBytes);
byte[] plainBytes = decryptionCipher.doFinal(newCipherBytes);
return new String(plainBytes, StandardCharsets.UTF_8);
}
}
总结:这次看nifi的源码收获了很多,学习到了很多,希望以后可以继续看源码,学习经验. 后面还会有加密的步骤