我们可以做的更好1

一、加密连接数据库明文密码

步骤:
1、对jdbc.property文件的用户名和密码进行加密,我们就需要创建一个加密工具类里面包含加密和解密方法。
2、加密好之后再把jdbc.property里的信息换成加密后的字符。
3、创建一个继承PropertyPlaceHolderConfigure的类用于在程序启动的时候再加载spring-dao.xml后需要解密回来。
4、在需要用到jdbc.property的spring-dao.xml里去掉之前的<context:property-placeholder location="classpath:jdbc.properties" />,然后再声明解密类的bean,配置属性。

1、
三个属性字符串密钥,字符编码,算法,然后使用一个static,static代码块就是用来初始化值key的,我们没有给key赋值就是通过static里的代码快来赋值的。

/**
 * DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法
 * 
 * @author ljs
 *
 */
public class DESUtil {

    private static Key key;

    // 密钥makekey
    private static String KEY_STR = "myKey";
    // 编码
    private static String CHARSETNAME = "UTF-8";
    // java自带的des算法
    private static String ALGORITHM = "DES";

    // 一次加载类的属性
    static {
        try {
            // 生成DES算法对象
            KeyGenerator generator = KeyGenerator.getInstance(ALGORITHM);
            // 运用SHA1安全策略
            SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
            // 设置上密钥种子
            secureRandom.setSeed(KEY_STR.getBytes());
            // 初始化基于SHA1的算法对象
            generator.init(secureRandom);
            // 生成密钥对象
            key = generator.generateKey();
            generator = null;
        } catch (Exception e) {
            throw new RuntimeException();
        }

    }

加密方法,这里出现的问题解决Eclipse中无法直接使用Base64Encoder的问题,传入str之后使用base64encoder把字符串转换为byte数组,然后再使用cipher.doFinal把byte数组变成加密后的byte数组,最后再使用使用base64encode.encode把加密后的byte数组变成String。

    /**
     * 获取加密后的信息
     * 
     * @param str(账号密码)
     * @return
     */
    public static String getEncryptString(String str) {
        // 基于BASE64编码,接收byte[]并转换String
        BASE64Encoder base64encoder = new BASE64Encoder();
        try {
            // 按UTF8编码
            byte[] bytes = str.getBytes(CHARSETNAME);
            // 获取加密对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            // 初始化密码信息
            cipher.init(Cipher.ENCRYPT_MODE, key);
            // 加密
            byte[] doFinal = cipher.doFinal(bytes);
            // byte[]to encode好的String并返回
            return base64encoder.encode(doFinal);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

解密方法,为什么参数还是str是因为你加密之后的还是字符串,传入str之后,使用base64Decoder把字符串转换为byte数组,然后再用cipher.doFinal转换为加密前的byte数组,最后再把加密前的byte数组转换为String返回。

/**
     * 获取解密之后的信息
     * 
     * @param str
     * @return
     */
    public static String getDecrytString(String str) {
        //基于BASE64编码,接收byte[]并转换成String
        BASE64Decoder base64Decoder = new BASE64Decoder();
        try {
            //将字符串decode成byte[]
            byte[] bytes = base64Decoder.decodeBuffer(str);
            //获取解密对象
            Cipher cipher = Cipher.getInstance(ALGORITHM);
            //初始化解密信息
            cipher.init(Cipher.DECRYPT_MODE, key);
            //解密
            byte[] doFinal = cipher.doFinal(bytes);
            //返回解密之后的信息
            return new String(doFinal, CHARSETNAME);
        }catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

}

2、运行main函数之后再把生成的信息填到jdbc.property中

image.png

image.png

3、
convertProperty参数是从jdbc.property里获取的,例如:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=WnplV/ietfQ=
然后判断property即jdbc.driver是否是前面属性数组里的元素

public class EncryptPropetryPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
    // 需要加密的字段数组
    private String[] encryptPropNames = { "jdbc.username", "jdbc.password" };

    /**
     * 对关键的属性进行转换
     */
    @Override
    protected String convertProperty(String propertyName, String propertyValue) {
        if (isEncryptProp(propertyName)) {
            // 对已加密的字段进行解密工作
            String decryptValue = DESUtil.getDecrytString(propertyValue);
            return decryptValue;
        } else {
            return propertyName;
        }
    }

    /**
     * 该属性是否已经加密
     * 
     * @param propertyName
     * @return
     */
    private boolean isEncryptProp(String propertyName) {
        // 若等于需要加密的filed,则进行加密
        for (String encryptpropertyName : encryptPropNames) {
            if (encryptpropertyName.equals(propertyName))
                return true;
        }
        return false;
    }

}

修改spring-dao.xml

<bean class="com.imooc.o2o.util.EncryptPropetryPlaceholderConfigurer">
        <property name="locations">
            <list>
                <value>classpath:jdbc.properties</value>
            </list>
        </property>
        <property name="fileEncoding" value="UTF-8"/>
    </bean>

设置短点调试,查看是否解密

image.png

debug启动tomcat,然后访问有关数据库的url,http://localhost:8080/o2o/shopadmin/shoplist,这里出错,原因是spring-dao.xml里写错了。属性locations写少一个s,properties写成property。改过来就好。

可以看到propertyname是jdbc.url,因为这个不是加密,所以下一步就直接return,这里直接按f8,又可以看到回到断点的地方propetyname这次是jdbc.username是需要解密的,f6之后可以看到解密成功。

最后它会把动态运行中赋值给spring-dao.xml里的属性。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容