使用AES加密配置文件

考虑到数据库连接密码直接配置在xml中,项目流转出现密码泄露隐患,这里直接对密码进行AES加密

<!-- 配置 读取properties文件 jdbc.properties -->
    <bean class="com.yehuishou.util.ConvertPwdPropertyConfigurer">
        <property name="location" value="classpath:jdbc.properties" />
        <property name="fileEncoding" value="utf-8" />

    </bean>

配置bean指定数据库文件的位置, class属性为重新的方法所在是全类名. 下面的

public class ConvertPwdPropertyConfigurer extends PropertyPlaceholderConfigurer {
    

    //"driverClassName", "url", "username", "password" 必须与配置文件内的名字一致

    private String[] encryptPropNames = { "driverClassName", "url", "username", "password" };

    @Override
    protected String convertProperty(String propertyName, String propertyValue) {

        // 如果在加密属性名单中发现该属性
        if (isEncryptProp(propertyName)) {
            String decryptValue;
            try {
                decryptValue = AES.Decrypt(propertyValue);
            } catch (Exception e) {
                return propertyValue;
            }
            return decryptValue;
        } else {
            return propertyValue;
        }
    }

    private boolean isEncryptProp(String propertyName) {
        for (String encryptName : encryptPropNames) {
            if (encryptName.equals(propertyName)) {
                return true;
            }
        }
        return false;
    }
}

数组encryptPropNames里面的值就是你jdbc.properties 配置文件里面 的名称。

AES.Decrypt(propertyValue); 这个方法是调用AES的加密方法。

 

public class AES{

//AES加密的16位key

    private static String sKey = "1234567887654321";

    
    public static void main(String[] args) throws Exception {
        
        System.out.println(AHEEHES.Encrypt(""));
        
        System.out.println(AHEEHES.Decrypt(""));
    }

    // 加密
    public static String Encrypt(String sSrc) throws Exception {
      
        // 判断Key是否为16位
        if (sKey.length() != 16) {
            System.out.print("Key长度不是16位");
            return null;
        }
        // 8866952612241802
        byte[] raw = sKey.getBytes();
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");// "算法/模式/补码方式"
        IvParameterSpec iv = new IvParameterSpec("9876543223456789".getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
        cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
        byte[] encrypted = cipher.doFinal(sSrc.getBytes());

        return org.apache.commons.codec.binary.Base64.encodeBase64String(encrypted);// 此处使用BAES64做转码功能,同时能起到2次加密的作用。
    }

    // 解密
    public static String Decrypt(String sSrc) throws Exception {
     
            // 判断Key是否为16位
            if (sKey.length() != 16) {
                System.out.print("Key长度不是16位");
                return null;
            }
            byte[] raw = sKey.getBytes("ASCII");
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            IvParameterSpec iv = new IvParameterSpec("9876543223456789".getBytes());
            cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
            byte[] encrypted1 = org.apache.commons.codec.binary.Base64.decodeBase64(sSrc);// 先用bAES64解密
            try {
                byte[] original = cipher.doFinal(encrypted1);
                String originalString = new String(original);
                return originalString;
            } catch (Exception e) {
                System.out.println(e.toString());
                return null;
            }
        } catch (Exception ex) {
            System.out.println(ex.toString());
            return null;
        }
    }
}
 

Key的长度必须是16,24,32位 , 这里用的是AES-128-CBC加密模式 , key需要16

使用AES加密需要的pom坐

<dependency>

       <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.9</version>
</dependency>

 

 

 

 

 

 

<think>嗯,用户想了解如何使用Java中的AES算法对配置文件进行加密,并请求一个示例教程。首先,我需要回顾一下Java中AES加密的基本步骤和相关库。根据用户提供的引用,有两个资源可以参考:一个是tozny的java-aes-crypto库,另一个是Java原生的javax.crypto包。这两个都可以实现AES加密,但使用方式不同。我应该分别考虑这两种方法,并给出示例代码。 首先,用户可能希望一个简单易用的解决方案,所以tozny的库可能更合适,因为它设计目的是简化加密操作。但用户也可能需要原生实现,以便更灵活地控制加密过程。因此,我应该提供两种方法的示例,并比较它们的优缺点。 接下来,我需要确保示例代码的正确性。比如,使用javax.crypto时,需要生成密钥、初始化加密模式(如CBC或GCM)、处理IV(初始化向量)等步骤。要注意密钥的存储问题,因为加密后的数据需要密钥来解密,而密钥不能硬编码在代码中。可能需要提示用户将密钥存储在安全的地方,比如环境变量或密钥管理服务。 另外,配置文件通常是文本格式,加密后可能需要Base64编码,以便保存为字符串。解密时则需要先解码Base64。需要确保示例中包含这些转换步骤。 还要考虑异常处理,比如NoSuchAlgorithmException、InvalidKeyException等,但为了示例简洁,可能暂时省略,但需要提醒用户在实际应用中处理这些异常。 对于配置文件的具体操作,比如使用Properties类加载和保存配置文件加密敏感值(如数据库密码),然后保存加密后的值。解密时读取加密字符串,解密使用。这些步骤需要详细说明。 另外,关于加密模式和填充方式,AES通常使用CBC或GCM模式,而填充可能是PKCS5Padding。需要指出不同模式的区别,比如GCM提供认证加密,更安全,但需要Java 8及以上支持。 密钥存储部分,需要强调不能将密钥硬编码在代码中,应该使用安全的存储方式。可能还需要提到密钥派生函数,如PBKDF2,如果从密码生成密钥的话。 最后,生成相关问题,帮助用户进一步学习,比如性能优化、密钥管理、加密模式选择等。</think>### Java AES加密配置文件教程 以下是使用原生`javax.crypto`和第三方库`java-aes-crypto`两种方式实现配置文件加密的完整流程: #### 方法一:使用javax.crypto原生实现 ```java import javax.crypto.*; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; import java.util.Properties; public class ConfigEncryptor { private static final String ALGORITHM = "AES/CBC/PKCS5Padding"; // 生成随机密钥(实际应存储在安全位置) public static byte[] generateKey() throws Exception { KeyGenerator keyGen = KeyGenerator.getInstance("AES"); keyGen.init(256); return keyGen.generateKey().getEncoded(); } // 加密方法 public static String encrypt(String input, byte[] key) throws Exception { Cipher cipher = Cipher.getInstance(ALGORITHM); SecretKeySpec keySpec = new SecretKeySpec(key, "AES"); IvParameterSpec iv = new IvParameterSpec(new byte[16]); // 固定IV仅示例 cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv); byte[] encrypted = cipher.doFinal(input.getBytes()); return Base64.getEncoder().encodeToString(encrypted); } // 配置文件加密示例 public static void main(String[] args) throws Exception { byte[] key = generateKey(); Properties prop = new Properties(); prop.load(Files.newInputStream(Paths.get("config.properties"))); // 加密数据库密码 String encryptedPass = encrypt(prop.getProperty("db.password"), key); prop.setProperty("db.password", encryptedPass); // 保存加密后的配置文件 prop.store(Files.newOutputStream(Paths.get("secure_config.properties")), "Encrypted configuration"); } } ``` #### 方法二:使用java-aes-crypto库 ```java import com.tozny.crypto.android.AesCbcWithIntegrity; import java.util.Properties; public class SimpleConfigEncryptor { public static void main(String[] args) throws Exception { // 生成密钥对 AesCbcWithIntegrity.SecretKeys keys = AesCbcWithIntegrity.generateKey(); // 加载配置文件 Properties prop = new Properties(); prop.load(getClass().getResourceAsStream("config.properties")); // 加密敏感字段 AesCbcWithIntegrity.CipherTextIvMac civ = AesCbcWithIntegrity.encrypt(prop.getProperty("api.key"), keys); prop.setProperty("api.key", civ.toString()); // 存储密钥和配置(密钥需要安全存储) prop.store(Files.newOutputStream(Paths.get("secure_config.ini")), "Encrypted with AES-GCM"); } } ``` #### 关键注意事项: 1. **密钥管理**:生成的AES密钥必须存储在安全位置(如HashiCorp Vault或AWS KMS),切勿硬编码在代码中[^2] 2. **加密模式选择**:推荐使用经过认证的加密模式如GCM,相比CBC模式提供更好的安全性[^1] 3. **初始向量(IV)**:每次加密都应生成随机IV,避免重用导致安全漏洞 4. **配置文件格式**:建议采用`<key>=<base64密文>`的格式存储加密值 5. **依赖管理**:使用第三方库时需通过Maven/Gradle添加依赖: ```xml <!-- java-aes-crypto库 --> <dependency> <groupId>com.tozny.crypto</groupId> <artifactId>java-aes-crypto</artifactId> <version>1.1.0</version> </dependency> ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值