中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

江門網(wǎng)站建設(shè)企業(yè)商丘seo排名

江門網(wǎng)站建設(shè)企業(yè),商丘seo排名,免費(fèi)申請網(wǎng)站,塘下建設(shè)銀行網(wǎng)站需求背景 應(yīng)用程序開發(fā)的時候,往往會存在一些敏感的配置屬性 數(shù)據(jù)庫賬號、密碼第三方服務(wù)賬號密碼內(nèi)置加密密碼其他的敏感配置 對于安全性要求比較高的公司,往往不允許敏感配置以明文的方式出現(xiàn)。 通常做法是對這些敏感配置進(jìn)行加密,然后在…

需求背景

應(yīng)用程序開發(fā)的時候,往往會存在一些敏感的配置屬性

  • 數(shù)據(jù)庫賬號、密碼
  • 第三方服務(wù)賬號密碼
  • 內(nèi)置加密密碼
  • 其他的敏感配置

對于安全性要求比較高的公司,往往不允許敏感配置以明文的方式出現(xiàn)。
通常做法是對這些敏感配置進(jìn)行加密,然后在使用的地方進(jìn)行解密。但是有一些第三方的配置可能未提供解密注入點如數(shù)據(jù)庫密碼,這時要實現(xiàn)起來就比較麻煩。有沒有比較方便的方法可以自動識別并解密。
本次主要針對這個問題,解決敏感配置的加密問題

實現(xiàn)思路

  • 使用已有的第三方包:如jasypt-spring-boot
    • 這是一個針對SpringBoot項目配置進(jìn)行加解密的包,可以在項目里通過引入依賴來實現(xiàn)。具體使用方式自行搜索
  • 參考官方文檔利用官方提供的擴(kuò)展點自己實現(xiàn)
    • 實現(xiàn)EnvironmentPostProcessor
      • EnvironmentPostProcessor在配置文件解析后,bean創(chuàng)建前調(diào)用
    • 實現(xiàn)BeanFactoryPostProcessor(優(yōu)先考慮)
      • BeanFactoryPostProcessor在配置文件解析后,bean創(chuàng)建前調(diào)用
      • 實現(xiàn)方式同EnvironmentPostProcessor基本一致,注入時機(jī)更靠后。

通過實現(xiàn)EnvironmentPostProcessor方式解決

實現(xiàn)EnvironmentPostProcessor可自定義環(huán)境配置處理邏輯。實現(xiàn)示例如下

    @Overridepublic void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {MutablePropertySources mutablePropertySources = environment.getPropertySources();for (PropertySource<?> propertySource : mutablePropertySources) {if (propertySource instanceof OriginTrackedMapPropertySource) {mutablePropertySources.replace(propertySource.getName(),// 實現(xiàn)一個包裝類,動態(tài)判斷new PropertySourceWrapper(propertySource, initSimpleEncryptor("reduck-project"), new EncryptionWrapperDetector("$ENC{", "}")));}}}

EnvironmentPostProcessor 也可以自動擴(kuò)展配置文件,如果有些項目自己在這個擴(kuò)展點實現(xiàn)了自己的配置加載邏輯,可能就需要考慮順序問題。這里比較推薦實現(xiàn)BeanFactoryPostProcessor,他在EnvironmentPostProcessor相關(guān)實例處理后調(diào)用,且在Bean創(chuàng)建前??梢愿脻M足需求。

通過實現(xiàn)BeanFactoryPostProcessor解決

  • 實現(xiàn)EncryptionBeanPostProcessor
    • 一般OriginTrackedMapPropertySource是我們自定義的配置加載實例,通過一個包裝類替換原先的實例
@RequiredArgsConstructor
public class EncryptionBeanPostProcessor implements BeanFactoryPostProcessor, Ordered {private final ConfigurableEnvironment environment;@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {MutablePropertySources mutablePropertySources = environment.getPropertySources();String secretKey = environment.getProperty("configuration.crypto.secret-key");if(secretKey ==  null) {return;}for (PropertySource<?> propertySource : mutablePropertySources) {if (propertySource instanceof OriginTrackedMapPropertySource) {mutablePropertySources.replace(propertySource.getName(),new PropertySourceWrapper(propertySource, new AesEncryptor(PrivateKeyFinder.getSecretKey(secretKey)), new EncryptionWrapperDetector("$ENC{", "}")));}}}@Overridepublic int getOrder() {return Ordered.LOWEST_PRECEDENCE - 100;}
}
  • 定義一個 PropertySource包裝類
    • PropertySource只有一個方法 public Object getProperty(String name),只需要實現(xiàn)這個方法,如果是加密配置就解密
public class PropertySourceWrapper<T> extends PropertySource<T> {private final String prefix = "$ENC{";private final String suffix = "}";private final Encryptor encryptor;private final PropertySource<T> originalPropertySource;private final EncryptionWrapperDetector detector;public PropertySourceWrapper(PropertySource<T> originalPropertySource, Encryptor encryptor, EncryptionWrapperDetector detector) {super(originalPropertySource.getName(), originalPropertySource.getSource());this.originalPropertySource = originalPropertySource;this.encryptor = encryptor;this.detector = detector;}@Overridepublic Object getProperty(String name) {if (originalPropertySource.containsProperty(name)) {Object value = originalPropertySource.getProperty(name);if (value != null) {String property = value.toString();if (detector.detected(property)) {return encryptor.decrypt(detector.unWrapper(property));}}}return originalPropertySource.getProperty(name);}
}
  • 定義一個加解密幫助類EncryptionWrapperDetector
    • 根據(jù)前后綴判斷是否是加密屬性
    • 對加密屬性進(jìn)行包裝
    • 對加密屬性去除包裝
public class EncryptionWrapperDetector {private final String prefix;private final String suffix;public EncryptionWrapperDetector(String prefix, String suffix) {this.prefix = prefix;this.suffix = suffix;}public boolean detected(String property) {return property != null && property.startsWith(prefix) && property.endsWith(suffix);}public String wrapper(String property) {return prefix + property + suffix;}public String unWrapper(String property) {return property.substring(prefix.length(), property.length() - suffix.length());}
}
  • 定義一個加解密類
    • 對配置文件進(jìn)行加密
    • 對配置問價進(jìn)行解密
public class AesEncryptor implements Encryptor {private final byte[] secretKey;private final byte[] iv = new byte[16];public AesEncryptor(byte[] secretKey) {this.secretKey = secretKey;System.arraycopy(secretKey, 0, iv, 0, 16);}@Overridepublic String encrypt(String message) {return Base64.getEncoder().encodeToString(_AesUtils.encrypt(secretKey, iv, message.getBytes()));}@Overridepublic String decrypt(String message) {return new String(_AesUtils.decrypt(secretKey, iv, Base64.getDecoder().decode(message)));}
}
  • 密鑰加密存儲
    • 采用非對稱加密方式對密鑰進(jìn)行加密,用公鑰加密后的密鑰可以直接寫在配置文件中
    • 在進(jìn)行解密的時候先通過內(nèi)置的私鑰解密獲取原始加密密鑰
    • 注意細(xì)節(jié)
      • 私鑰存儲的時候可以再進(jìn)行一次加密
      • 私鑰可放在META-INF路徑下,通過Classloader獲取
public class PrivateKeyFinder {private static final String PRIVATE_KEY_RESOURCE_LOCATION = "META-INF/configuration.crypto.private-key";private static final String PUBLIC_KEY_RESOURCE_LOCATION = "META-INF/configuration.crypto.public-key";private final byte[] keyInfo = new byte[]{(byte) 0xD0, (byte) 0x20, (byte) 0xDA, (byte) 0x92, (byte) 0xC8, (byte) 0x0B, (byte) 0x6D, (byte) 0x57,(byte) 0x48, (byte) 0x7B, (byte) 0x15, (byte) 0x3A, (byte) 0x44, (byte) 0xA0, (byte) 0x98, (byte) 0xC2,(byte) 0xF1, (byte) 0x6F, (byte) 0xB6, (byte) 0x09, (byte) 0x2F, (byte) 0x6D, (byte) 0x69, (byte) 0xFB,(byte) 0x2D, (byte) 0x02, (byte) 0x00, (byte) 0xCB, (byte) 0xBE, (byte) 0x48, (byte) 0xDD, (byte) 0xD5,(byte) 0x90, (byte) 0xC2, (byte) 0x95, (byte) 0x98, (byte) 0x60, (byte) 0x59, (byte) 0x24, (byte) 0xE2,(byte) 0xB7, (byte) 0x84, (byte) 0x12, (byte) 0x5D, (byte) 0xB9, (byte) 0xC1, (byte) 0x19, (byte) 0xFF,(byte) 0x4F, (byte) 0x01, (byte) 0xB9, (byte) 0xC5, (byte) 0xD8, (byte) 0xD2, (byte) 0x99, (byte) 0xEE,(byte) 0xAA, (byte) 0x0D, (byte) 0x59, (byte) 0xF8, (byte) 0x37, (byte) 0x49, (byte) 0x91, (byte) 0xAB};static byte[] getSecretKey(String encKey) {byte[] key = loadPrivateKey();return RsaUtils.decrypt(Base64.getDecoder().decode(encKey), new PrivateKeyFinder().decrypt(Base64.getDecoder().decode(key)));}static String generateSecretKey() {return Base64.getEncoder().encodeToString(RsaUtils.encrypt(new SecureRandom().generateSeed(16), Base64.getDecoder().decode(loadPublicKey())));}static String generateSecretKeyWith256() {return Base64.getEncoder().encodeToString(RsaUtils.encrypt(new SecureRandom().generateSeed(32), Base64.getDecoder().decode(loadPublicKey())));}@SneakyThrowsstatic byte[] loadPrivateKey() {return loadResource(PRIVATE_KEY_RESOURCE_LOCATION);}@SneakyThrowsstatic byte[] loadPublicKey() {return loadResource(PUBLIC_KEY_RESOURCE_LOCATION);}@SneakyThrowsprivate static byte[] loadResource(String location) {// just lookup from current jar  pathClassLoader classLoader = new URLClassLoader(new URL[]{PrivateKeyFinder.class.getProtectionDomain().getCodeSource().getLocation()}, null);
//        classLoader = PrivateKeyFinder.class.getClassLoader();Enumeration<URL> enumeration = classLoader.getResources(location);// should only find onewhile (enumeration.hasMoreElements()) {URL url = enumeration.nextElement();UrlResource resource = new UrlResource(url);return FileCopyUtils.copyToByteArray(resource.getInputStream());}return null;}private final String CIPHER_ALGORITHM = "AES/CBC/NoPadding";private final String KEY_TYPE = "AES";@SneakyThrowspublic byte[] encrypt(byte[] data) {byte[] key = new byte[32];byte[] iv = new byte[16];System.arraycopy(keyInfo, 0, key, 0, 32);System.arraycopy(keyInfo, 32, iv, 0, 16);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, KEY_TYPE), new IvParameterSpec(iv));return cipher.doFinal(data);}@SneakyThrowspublic byte[] decrypt(byte[] data) {byte[] key = new byte[32];byte[] iv = new byte[16];System.arraycopy(keyInfo, 0, key, 0, 32);System.arraycopy(keyInfo, 32, iv, 0, 16);Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, KEY_TYPE), new IvParameterSpec(iv));return cipher.doFinal(data);}
}

綜上既可以實現(xiàn)敏感配置文件的加解密,同時可以保障加密密鑰的安全傳入

http://www.risenshineclean.com/news/30526.html

相關(guān)文章:

  • 網(wǎng)站基本維護(hù)seo技術(shù) 快速網(wǎng)站排名
  • 投資做網(wǎng)站廣告媒體資源平臺
  • 國內(nèi)攝影作品網(wǎng)站免費(fèi)建網(wǎng)站的步驟
  • 東莞網(wǎng)站優(yōu)化中易品牌推廣渠道有哪些
  • 做的網(wǎng)站怎么讓百度收索時搜seo實戰(zhàn)指導(dǎo)
  • 嵐山網(wǎng)站建設(shè)報價山東網(wǎng)絡(luò)推廣網(wǎng)站
  • iis2008如何做網(wǎng)站百度知道合伙人
  • 徐州萬網(wǎng)網(wǎng)站建設(shè)seo優(yōu)化上首頁
  • 利用云服務(wù)器做網(wǎng)站谷歌推廣哪家好
  • 企業(yè)咨詢管理有限公司南昌seo全網(wǎng)營銷
  • 免費(fèi)網(wǎng)站后臺管理系統(tǒng)看廣告收益最高的軟件
  • 濟(jì)南做外貿(mào)網(wǎng)站新冠咳嗽怎么辦
  • 網(wǎng)站怎樣做友情鏈接佛山本地網(wǎng)站建設(shè)
  • 網(wǎng)站開發(fā)看書湖北網(wǎng)站seo
  • 做動漫網(wǎng)站侵權(quán)嗎揚(yáng)州網(wǎng)絡(luò)優(yōu)化推廣
  • 怎么通過微博做網(wǎng)站外鏈百度seo外包
  • wordpress游戲網(wǎng)站百度優(yōu)化推廣
  • 做網(wǎng)站賭博的推廣是不是犯罪的上海全網(wǎng)推廣
  • 公司網(wǎng)站 域名網(wǎng)絡(luò)營銷成功案例有哪些
  • 商業(yè)網(wǎng)站建設(shè)的方法外國網(wǎng)站怎么進(jìn)入
  • 做圖素材網(wǎng)站開哪個vip好熱搜榜上2023年熱門話題
  • 怎么在外管局的網(wǎng)站做延期seo服務(wù)價格表
  • 怎樣做_網(wǎng)站做seo百度網(wǎng)站的域名地址
  • 3d做號網(wǎng)站每日精選12條新聞
  • 設(shè)計前沿的網(wǎng)站東莞網(wǎng)站關(guān)鍵詞優(yōu)化公司
  • 做社群的網(wǎng)站有哪些西安百度推廣怎么做
  • wordpress html插件優(yōu)化網(wǎng)站做什么的
  • 哪家公司做網(wǎng)站最好網(wǎng)絡(luò)營銷專業(yè)技能
  • 明年做那些網(wǎng)站致富網(wǎng)站優(yōu)化包括哪些
  • 無極網(wǎng)站站怎么有的下不了如何讓百度收錄自己信息