[數據安全] 一個簡潔快速的去數據特征的混淆算法(obfuscate)


[注]本文為作者原創文章,轉載請注明出處。謝謝。 

 

問題1,什么是特征

  這個人長個馬臉,那個妹子胸大,這都是特征。顯然,特征越明顯,我們越容易對其進行辨識。

問題2,什么是數據特征

  數據特征,就是說,某段數據具有的特征。

    比如,通迅的雙方(A <-> B ),在建立連接后,A發給B的第一個包,長度總是固定的,有時候甚至值都是固定的(在協議握手階段尤其如此)。 

問題3,為什么要去掉這些特征

  我們在講網絡安全的時候,絕大部分的人能想到數據加密,然而僅僅加密還不足於保護我們的。下面我舉幾個例子。

    1,某FW在對數據包進行檢測的時候,可以通過特征的學習及辨識去決定要不要reset這個連接。

    2,瀏覽網站時產生的流量數據,帶有明顯的網頁字節數特征,通過對這個特征的學習,第三方可以大概知道瀏覽網站的人都訪問過哪些網站,甚至知道訪問了哪些頁面。 

問題4,怎么去數據特征

  通過粗略的分析,我們至少有兩個辦法可以使數據特征不明顯。

    1,改變數據長度。主要通過在數據流中加入一些隨機長度的隨機值。

    2,通過增加冗余位,增加數據中具體位的隨機性。 

一種冗余位Obfuscate方案

  我們知道一個字節通常由8個bit組成。確定的值,它的bit平面(低位到高位所呈現的0101序列)總是確定的。如果我們讓這個確定變成不確定,我們的目的就達成了。

  下面,我介紹一個簡單的通過冗余位達到混擾的目的。

  以uint8_t -> uint32_t 為實例進行一個大概的算法描述  

  uint8_t   占8bit

  uint32_t   占32bit  

  uint8_t中

    01位置於uint32_t 第一個byte,

    23位置於uint32_t第二個byte,

    45位置於uint32_t第三個byte,

    67位置於uint32_t第四byte

 

    具體的算法:

     取uint32_t中每個byte的高3位,得到一個數值p, p mod 5 = z, z就是這個byte中起始有效bit位,從這個位開始,順序存儲(從底位到高位)2個uint8_t中的位 (見下圖)

   

  

 C代碼實現

//UINT_X's width must be less than sizeof(uint32_t), it can be uint8_t or , uint16_t
template <typename UINT_X>
inline static uint32_t obfuscate(UINT_X const& val, uint32_t const& r_u32) {
	if (sizeof(uint32_t) <= sizeof(UINT_X)) return val;
	uint32_t rr = 0;
	uint8_t b[sizeof(UINT_X) * 8];
	uint8_t bii[sizeof(UINT_X) * 8];

	//per bytes contain bit count
	uint8_t pbcbc = (sizeof(UINT_X) * 8) / (sizeof(uint32_t) / sizeof(uint8_t));

	for (int i = 0; i < (sizeof(UINT_X) * 8); i++) {
		if ((i%pbcbc) == 0) {
			b[i] = ((r_u32 >> ((5 + ((i / pbcbc) << 3))) & 0x7) % 5) & 0xFF;
			bii[i] = b[i];
		} else {
			b[i] = ((b[i - 1] + 1) % 5);
			bii[i] = bii[i - 1];
		}

		uint8_t bi = 0;
		if (val&(0x01 << i)) {
			bi |= (0x01 << b[i]);
		}
		bi |= ((0x7 & bii[i]) << 5);
		rr |= ((0xFFFFFFFF & bi) << ((i / pbcbc) << 3));
	}
	return rr;
}

template <typename UINT_X>
inline static UINT_X deobfuscate(uint32_t const& val) {
	UINT_X r = 0;
	uint8_t pbcbc = (sizeof(UINT_X) * 8) / (sizeof(uint32_t) / sizeof(uint8_t));
	UINT_X b[sizeof(UINT_X) * 8];

	for (int i = 0; i < (sizeof(UINT_X) * 8); i++) {
		if ((i%pbcbc) == 0) {
			b[i] = ((val >> ((5 + ((i / pbcbc) << 3))) & 0x7) % 5) & 0xFF;
		} else {
			b[i] = ((b[i - 1] + 1) % 5);
		}
		r |= (((val >> (b[i] + ((i / pbcbc) << 3))) & 0x1) << i);
	}
	return r;
}

namespace wawo { namespace security {
	inline static uint32_t u8_obfuscate(uint8_t const& val, uint32_t const& r_u32) {
		return obfuscate<uint8_t>(val,r_u32);
	}
	inline static uint32_t u16_obfuscate(uint16_t const& val, uint32_t const& r_u32) {
		return obfuscate<uint16_t>(val, r_u32);
	}
	inline static uint8_t u8_deobfuscate(uint32_t const& val) {
		return deobfuscate<uint8_t>(val);
	}
	inline static uint16_t u16_deobfuscate(uint32_t const& val) {
		return deobfuscate<uint16_t>(val);
	}
}}

  

  

 

   

 

 

 

 

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM