对配置文件内的固定内容加密解密

接到一个需求,背景是对公司的各个服务器环境下的配置文件内存有数据库用户名,数据库密码,因为在配置文件中,许多shell脚本都需要调用配置文件中的数据库用户名,密码,所以一直以明文保存,需求内容就是实现对配置文件内的用户名,密码加密,同时加密后要解决shell脚本文件还可以调用到正确的用户名密码,因此还需要解密。

因为是在服务器环境下,所以可以编写java程序,然后将程序打成jar包,通过shell指令调用jar包实现加密与解密。

因为要实现逆向解密,所以没有采用MD5,只能用比较老的DES或者AES等,这里采用的是DES。

首先给出配置文件的内容,

不便给出全部内容,因此只有部分重要内容,

*********************

*********************

#数据库用户名

dbuser=cmis

#数据库密码

dbpass=cmis

#用户名

douser=cmis

#密码

dopass=cmis

*********************
*********************

假如需要对cmis加密

首先我们需要先实现对一串字符串进行加密与解密,代码如下

import java.awt.List;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
/**
* 加密解密
*
* doencrypt方法进行加密
* dodencrypt方法进行解密
* @author liuhao
*
*/
public class EncryptAndDencrypt {

private static Cipher cipher ;
private static byte[] result ;
private static SecretKey convertsecretKey;
/**
* 生成DES加密解密key值
* @return
* @throws Exception
*/
public static SecretKey doKey() throws Exception{
//生成key
KeyGenerator keyGenerator = KeyGenerator.getInstance("DES");
keyGenerator.init(56);
SecretKey secretKey = keyGenerator.generateKey();
byte[] bytesKey = secretKey.getEncoded();

//KEY转换
DESKeySpec desKeySpec = new DESKeySpec(bytesKey);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey convertsecretKey = factory.generateSecret(desKeySpec);
return convertsecretKey;
}
/**
* 传入明文密码,加密后返回密文
* @param src
* @return
* @throws Exception
*/
public static keyAndSecret doencrypt(String src) throws Exception{
keyAndSecret ks = new keyAndSecret();
convertsecretKey = doKey();
cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
//加密
cipher.init(Cipher.ENCRYPT_MODE, convertsecretKey);
result = cipher.doFinal(src.getBytes());
ks.setKey(convertsecretKey);
ks.setByt(result);
return ks;
}

/**
* 传入密文,解密后返回明文密码
* @param byt
* @return
* @throws Exception
*/
public static String dodecrypt(byte[] byt,SecretKey sKey) throws Exception {
try{
cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
//解密
cipher.init(Cipher.DECRYPT_MODE, sKey);
byt = cipher.doFinal(byt);
}catch(Exception e){
throw e;
}
return new String(byt);
}
}

上边的代码是具体实现加密解密的部分。传入字符串后在加密前先会随机生成一个Key,这个是java提供的,由一个factory生成,这个key十分重要,因为加密时的cipher类调用的init方法只传入两个值一个相当于标示作用既Cipher.DECRYPT_MODE,或Cipher.ENCRYPT_MODE,一个为加密标示,一个为解密标示,另一个传入值就是key。我的代码是加密一个字符串就会生成一个新的key,因此因为还有解密过程所以这个key需要保存下来,保存方式接下来会说到。字符串加密后的类型为byte[].

同时呢为了简化代码,将密文与密钥封装:

import javax.crypto.SecretKey;
/**
* 对秘钥key与相应密文封装
* @author liuhao
*
*/
public class keyAndSecret {
private SecretKey key;//密钥
private byte[] byt;//密文

public SecretKey getKey(){
return key;
}
public void setKey(SecretKey key){
this.key = key;
}
public byte[] getByt(){
return byt;
}
public void setByt(byte[] byt){
this.byt = byt;
}
}

接下来是对于配置文件的IO操作了:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import com.ibm.misc.BASE64Encoder;

public class DoEncrypt {
private static String file = "/etldata/etl/bin/config_pass.conf";
private static String file2 = "/etldata/etl/bin/key.conf";

public static void main(String[] args) throws Exception {

//字符字节转换编码规范
BASE64Encoder enc = new BASE64Encoder();

BufferedReader brkey = new BufferedReader(new InputStreamReader(new FileInputStream(file2)));

BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));
List list = new ArrayList();
//按行读取文件内容存入list
//读取配置文件内容
int t = 0;//定位标记
while(true){
String str = br.readLine();
if(str==null)
break;
list.add(str);

}
br.close();
//读取密钥文件内容
List keylist = new ArrayList();
while(true){
String str = brkey.readLine();
if(str==null)
break;
keylist.add(str);
}
brkey.close();
keyAndSecret ks = new keyAndSecret();
//生成密文与相应的密钥
keylist.clear();

ListIterator ite = list.listIterator();
//遍历找到对应行
while(ite.hasNext()){
String str0= ite.next().toString();
if(str0.contains(new String("数据库用户名".getBytes("GBK")))){
t = ite.nextIndex();
break;
}
}
String str = (String) list.get(t);
int temp = str.lastIndexOf("=")+1;
ks = EncryptAndDencrypt.doencrypt(str.substring(temp));
list.set(t, "dbuser="+enc.encode(ks.getByt()));//对应1密钥
keylist.add(0,enc.encode(ks.getKey().getEncoded()));//1密钥
System.out.println(t+"----"+list.get(t));

while(ite.hasNext()){
String str1 = ite.next().toString();
if(str1.contains(new String("数据库密码".getBytes("GBK")))){
t = ite.nextIndex();
break;
}
}
str = (String) list.get(t);
ks = EncryptAndDencrypt.doencrypt(str.substring(temp));//对应2密钥
list.set(t, "dbpass="+enc.encode(ks.getByt()));
keylist.add(1, enc.encode(ks.getKey().getEncoded()));//2密钥
System.out.println(t+"----"+list.get(t));

while(ite.hasNext()){
String str2 = ite.next().toString();
if(str2.contains(new String("用户名".getBytes("GBK")))){
t = ite.nextIndex();
break;
}
}
str = (String) list.get(t);
ks = EncryptAndDencrypt.doencrypt(str.substring(temp));
list.set(t, "douser="+enc.encode(ks.getByt()));//对应3密钥
keylist.add(2,enc.encode(ks.getKey().getEncoded()));//3密钥
System.out.println(t+"----"+list.get(t));

while(ite.hasNext()){
String str3 = ite.next().toString();
if(str3.contains(new String("密码".getBytes("GBK")))){
t = ite.nextIndex();
break;
}
}
str = (String) list.get(t);
ks = EncryptAndDencrypt.doencrypt(str.substring(temp));
list.set(t, "dopass="+enc.encode(ks.getByt()));//对应4密钥
keylist.add(3,enc.encode(ks.getKey().getEncoded()));//4密钥
System.out.println(t+"----"+list.get(t));

//密钥文件路径
PrintWriter pw1 = new PrintWriter(file2);
for(int i=0;i<keylist.size();i++){

String str2 =keylist.get(i).toString();
pw1.println(str2);

}
pw1.close();
//密文保存
PrintWriter pw = new PrintWriter(file);

for(int i=0;i<list.size();i++){
String str1 =list.get(i).toString();
System.out.println(str1);
pw.println(str1);

}
pw.close();

}
}

其中对于如何key类型的密钥,与byte[]类型的密文存入文件,就需要转换成string字符了,并且在解密时能正确的转换回原来的类型是一个需要特别注意的地方。

这里直接告诉大家byte转换string不能使用toString()方法,因为toString()是返回表示此 Byte 的值的 String 对象。例如,如果byte[]内容是a1b2c3d4=,string内容也是a1b2c3d4=,这并不是我们需要的,因为在解密时读取到a1b2c3d4=后转换为byte[]时结果就不是a1b2c3d4=了。

因此需要BASE64的出场了。调用的encode方法可以将byte[]对象转换成字符串(这里返回的对象不是byte的值,而是真正意义上的转换值),在解密时调用BASE64Decoder的decodeBuffer方法就能将字符串转换BASE64Encoder回我们原先的byte[]类型了。

同理,key类型用方法getEncoded()可以将key类型转换为byte,再使用BASE64Encoder转换为字符串存储即可。

解密代码:

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.ibm.misc.BASE64Decoder;

public class DoDencypt {

/**
* @param args
*/
private static String file = "/etldata/etl/bin/config_pass.conf";//配置文件路径
private static String file2 = "/etldata/etl/bin/key.conf";

public static String JM(String str) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file)));

BufferedReader brkey = new BufferedReader(new InputStreamReader(new FileInputStream(file2)));

//读取配置文件内容
List list = new ArrayList();

while(true){
String str1 = br.readLine();
if(str1==null)
break;
list.add(str1);
}
br.close();
//读取密钥文件内容
List keylist = new ArrayList();

while(true){
String str1 = brkey.readLine();
if(str1==null)
break;
keylist.add(str1);
}
brkey.close();
SecretKey key = null;
byte[] byt = null;
BASE64Decoder dec = new BASE64Decoder();//字符字节转换编码规范
int t = 0;//定位标记
/**
* 根据传入值匹配对哪个类型解密
*/
if("dbuser".equals(str)){
ListIterator ite = list.listIterator();
while(ite.hasNext()){
String str1 = ite.next().toString();
if(str1.contains(new String("数据库用户名".getBytes("GBK")))){
t = ite.nextIndex();
break;
}
}
str = list.get(t).toString();

byt = (dec.decodeBuffer(keylist.get(0).toString()));
key = new SecretKeySpec(byt, "DES");
try {
str = EncryptAndDencrypt.dodecrypt(dec.decodeBuffer(str.substring(7)), key);
} catch (Exception e) {
e.printStackTrace();
}
return str;
}else if("dbpass".equals(str)){
ListIterator ite = list.listIterator();
while(ite.hasNext()){
String str1 = ite.next().toString();
if(str1.contains(new String("数据库密码".getBytes("GBK")))){
t = ite.nextIndex();
break;
}
}
str = list.get(t).toString();
byt = (dec.decodeBuffer(keylist.get(1).toString()));
key = new SecretKeySpec(byt, "DES");
try {
str = EncryptAndDencrypt.dodecrypt(dec.decodeBuffer(str.substring(7)), key);
} catch (Exception e) {
e.printStackTrace();
}
return str;
}else if("douser".equals(str)){
ListIterator ite = list.listIterator();
while(ite.hasNext()){
String str1 = ite.next().toString();
if(str1.contains(new String("#用户名".getBytes("GBK")))){
t = ite.nextIndex();
break;
}
}
str = list.get(t).toString();
byt = (dec.decodeBuffer( keylist.get(2).toString()));
key = new SecretKeySpec(byt, "DES");
try {
str = EncryptAndDencrypt.dodecrypt(dec.decodeBuffer(str.substring(7)), key);
} catch (Exception e) {
e.printStackTrace();
}
return str;
}else if("dopass".equals(str)){
ListIterator ite = list.listIterator();
while(ite.hasNext()){
String str1 = ite.next().toString();
if(str1.contains(new String("#密码".getBytes("GBK")))){
t = ite.nextIndex();
break;
}
}
str = list.get(t).toString();
byt = (dec.decodeBuffer( keylist.get(3).toString()));
key = new SecretKeySpec(byt, "DES");
try {
str = EncryptAndDencrypt.dodecrypt(dec.decodeBuffer(str.substring(7)), key);
} catch (Exception e) {
e.printStackTrace();
}
return str;
}else{
return "error";
}

}

}

解密就不需要多说了,需要注意的就是一定要选对正确的key,因为在加密时的key必须与解密的key相同。

这也是我初次写加密解密以及对文件特殊IO操作的代码,内容可能有很多可以简化或者更加优秀的写法。

对于打包也有一些需要注意,如果需要在Linux下运行jar程序,在打包时需要定一个main函数,一个jar只能定一个main。如果想要给这个jar的main传入参数的话参看一下代码:

import java.io.IOException;

public class ThisMain {
public static void main(String[] args) {
try {
String str = args[0];
String result = DoDencypt.JM(str);
System.out.print(result);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

在服务器上的shell指令加密指令是:java -jar 包名

解密指令为:java -jar 包名 传入值

时间: 2024-12-05 18:36:21

对配置文件内的固定内容加密解密的相关文章

winform 配置文件的加密解密

winform 配置文件的加密解密Visual Studio 命令提示(2010) 窗口下直接输入 :解密aspnet_regiis -pdf connectionStrings 程序文件夹全目录 加密aspnet_regiis -pef connectionStrings 程序文件夹全目录 注意:加密解密过程中必须把配置文件名称改为web.config程序运行一定要改回来App.cong 也可以通过运行CMD切换到命令提示符下,进入到C:\WINDOWS\Microsoft.net\Frame

php使用内置的mcrypt_encrypt和mcrypt_decrypt进行字符串加密解密

<?php /*****************************加密*******************************/$key = "miyao";//密钥$string="jiami";//需要加密的字符//自带的加密函数$crypttext = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($key), $string, MCRYPT_MODE_CBC, md5(md5($

openssl 加密 解密 应用及CA的实现

一 现在的加密/解密技术主要有三种:对称加密,公钥加密,和单向加密 对称加密:指的是加密方和解密方使用的是同一个密钥 特性: 1 加密.解密使用同一个秘钥: 2 将原始数据分割成固定大小的块,逐个进行加密 算法:DES  3DES  AES 公钥加密:秘钥是成对出现 公钥:公开给所有人: pubkey 私钥:自己留存,必须保证去私密性:secret key 特点:用公钥加密的数据只能用与之配对的私钥解密,反之亦然: 特性: 数字签名:用于接收方确认发送方的身份 秘钥交换:发送方用对方的公钥加密一

加密解密过程

1,首先来说说有关加密解密有关的信息 信息安全标准NIST(National Institute of Standards and Technology)美国国家标准与技术研究院 openssl有CIA C:保密性: 数据保密性 隐私性 A:完整性: 数据完整性 系统完整性 I:可用性 真实性:一个实体是真实的,可被验证的. 可追溯性:一旦被攻击,能够追溯攻击源在哪 2,OSI规定的X.800 1)安全攻击: 被动攻击:窃听 主动攻击:1,伪装 2,重播 3,消息修改 4,拒绝攻击等 2)安全服

加密解密

在现代密码学中,加密方法大致可分为对称密钥加密(对称加密)和公开密钥加密(非对称加密). 一. 对称加密(Symmetric-key algorithm,或对等加密: Reciprocal cipher ) 对称加密,即加密和解密使用同一个密钥,或者知道一方密钥能够轻易计算出另一方密钥.其解密(decryption)算法等同于加密算法,也就是说,要还原对等加密的密文,套用加密同样的算法即可得到明文. 对称加密的速度比非对称加密快很多,在很多场合都需要对称加密. 对称加密又可分为分组密码(分组加密

加密解密原理,自建CA

目前数据的加密方式有3种:单向加密,对称加密,公钥加密(非对称加密),我们常见的加密算法有DES,MD5,SHA1...SHA512,RSA,都有各自不同的用处.简单介绍下这3中加密方式. 单向加密 通过某种Hash 函数对原始数据进行提取,提取得到一端固定长度的密文(不管文件有多大,密文长度不变),这段数据也常被称为数据指纹或特征码. 特点:1)单向加密,只能由原始数据得到特征码,而不能由特征码逆向推出原始数据. 2)雪崩效应,原始数据微小的改变会导致特征码巨大的变化 应用:常被应用于数字签名

加密解密以及私有CA的实现

一.加密和解密 什么是加密:加密之前为明文,加密后是密文,将明文转换为密文的过程就是加密. 1. 对称加密 提供算法本身,加密和解密使用的是同一个密钥,用以保证数据的机密性.但安全性依赖于密钥,而非算法. 对称加密的优点是运算特别快:缺点是安全几乎全部依赖于密钥(算法基本上是公开的),当通信对象很多的时候,很难对密钥进行有效管理. 常见算法: DES(Data Encrption Standard):早期的算法,公开可以使用的,56bit密码长度,惨遭淘汰. 3DES:DES后DES再DES A

Openssl及加密解密(二)openssl

openssl是一个条件实现了上百种算法.实现了单向加密工具等一组套件,代码量很小但是功能强大.它有三部分组成: libcrypto:通用功能的加密库,软件开发时可以直接调用 libssl:实现TLS/SSL的功能 openssl:多功能命令行工具,加密.解密.创建CA.证书.一对秘钥等 openssl enc加密解密命令: 参数 说明 -des3 是指定加密算法 -a 是输出文件按base64内容输出,否则就是二进制的 -in 要加密的文件 -out 加密后的文件 -salt 加盐 -d 表示

加密解密技术基础、PKI及创建私有CA

加密解密技术基础.PKI及创建私有CA 一.背景 随着互联网的快速发展,整个互联网中涌入了大量的用户,正所谓林子大了什么鸟都有,随之而来的就是数据的安全性得不到保障:因此就有了对数据的加密及解密. 二.安全的目标 1.目标: 信息加密的目的是为了确保所传输的信息具有保密性,不被其他人所劫持后篡改信息:如果被篡改后接收方也应该能知道,而且也应该确保没被劫持的信息接收方可以读取. 2.数据在网络中传输过程中要保证三个要点: (1)数据的完整性:防止数据在传输过程中遭到未授权用户的破坏或篡改. (2)