我們可以做的更好1

一、加密連接數(shù)據(jù)庫明文密碼

步驟:
1、對jdbc.property文件的用戶名和密碼進行加密,我們就需要創(chuàng)建一個加密工具類里面包含加密和解密方法。
2、加密好之后再把jdbc.property里的信息換成加密后的字符。
3、創(chuàng)建一個繼承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();
        }

    }

加密方法,這里出現(xiàn)的問題解決Eclipse中無法直接使用Base64Encoder的問題,傳入str之后使用base64encoder把字符串轉(zhuǎn)換為byte數(shù)組,然后再使用cipher.doFinal把byte數(shù)組變成加密后的byte數(shù)組,最后再使用使用base64encode.encode把加密后的byte數(shù)組變成String。

    /**
     * 獲取加密后的信息
     * 
     * @param str(賬號密碼)
     * @return
     */
    public static String getEncryptString(String str) {
        // 基于BASE64編碼,接收byte[]并轉(zhuǎn)換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);
        }
    }

}

解密方法,為什么參數(shù)還是str是因為你加密之后的還是字符串,傳入str之后,使用base64Decoder把字符串轉(zhuǎn)換為byte數(shù)組,然后再用cipher.doFinal轉(zhuǎn)換為加密前的byte數(shù)組,最后再把加密前的byte數(shù)組轉(zhuǎn)換為String返回。

/**
     * 獲取解密之后的信息
     * 
     * @param str
     * @return
     */
    public static String getDecrytString(String str) {
        //基于BASE64編碼,接收byte[]并轉(zhuǎn)換成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函數(shù)之后再把生成的信息填到jdbc.property中

image.png

image.png

3、
convertProperty參數(shù)是從jdbc.property里獲取的,例如:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.username=WnplV/ietfQ=
然后判斷property即jdbc.driver是否是前面屬性數(shù)組里的元素

public class EncryptPropetryPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
    // 需要加密的字段數(shù)組
    private String[] encryptPropNames = { "jdbc.username", "jdbc.password" };

    /**
     * 對關鍵的屬性進行轉(zhuǎn)換
     */
    @Override
    protected String convertProperty(String propertyName, String propertyValue) {
        if (isEncryptProp(propertyName)) {
            // 對已加密的字段進行解密工作
            String decryptValue = DESUtil.getDecrytString(propertyValue);
            return decryptValue;
        } else {
            return propertyName;
        }
    }

    /**
     * 該屬性是否已經(jīng)加密
     * 
     * @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>

設置短點調(diào)試,查看是否解密

image.png

debug啟動tomcat,然后訪問有關數(shù)據(jù)庫的url,http://localhost:8080/o2o/shopadmin/shoplist,這里出錯,原因是spring-dao.xml里寫錯了。屬性locations寫少一個s,properties寫成property。改過來就好。

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

最后它會把動態(tài)運行中賦值給spring-dao.xml里的屬性。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,533評論 19 139
  • 1. Java基礎部分 基礎部分的順序:基本語法,類相關的語法,內(nèi)部類的語法,繼承相關的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,637評論 18 399
  • 她踩著高跟鞋疾走,清晨還有微涼,今天的天氣應該很好,這樣美好的念頭也是一閃而過,地鐵迎來高峰,人流擁著她停不下腳步...
    蔣棲子閱讀 214評論 0 0
  • 目前,燈光節(jié)在全世界十分流行。最著名的有法國的里昂燈光節(jié)、日本的札幌燈光節(jié)、澳大利亞的悉尼燈光節(jié),國內(nèi)大規(guī)模的燈光...
    銳財經(jīng)閱讀 354評論 0 0
  • 本視頻為activiti工作流的web流程設計器整合視頻教程 整合Acitiviti在線流程設計器(Activit...
    61c8365cdcec閱讀 190評論 0 0

友情鏈接更多精彩內(nèi)容