1. 程式人生 > >Android安全/應用逆向--34--加密演算法基礎

Android安全/應用逆向--34--加密演算法基礎

7-11、加密演算法基礎

1、加密演算法概念

一種對映函式,即:明文+金鑰→密文,密文+金鑰→明文。 具體的對映形式可能會有所變化,例如單向加密演算法,無金鑰的加密演算法等。

2、如何實現加密

加密實現的機制是“混亂和擴散”,即明文或金鑰中每一個二進位制位的改變,應當引起密文中平均一半二進位制位的改變,且這種改變不具有線性分佈。

3、為何能夠保護資料

由於加密對映不具有線性分佈,從密文中無法單獨推算出明文或金鑰的區域性資訊。因此,唯一的辦法就只有窮舉金鑰。這樣一來,只要金鑰足夠長,攻擊者就無法線上性時間內從密文恢復出明文或金鑰。

4、加密演算法分類

對稱加密演算法:加密和解密使用相同金鑰的加密演算法。 優點:

加解密的高速度和使用長金鑰時的難破解性。 缺點:對稱加密演算法的安全性取決於加密金鑰的儲存情況。金鑰丟失則安全破滅。 破解方案:設法從程式碼常量、資料檔案、網路流量中找出金鑰,或者將其修改為已知值。

==========================================================

DES:是一種分組密碼,以64位為分組對資料加密,它的金鑰長度是56位 3DES:是DES加密演算法的一種模式,它使用3條56位的金鑰對資料進行三次加密。 DESX:是一個變異的DES(資料加密標準) Blowfish:是一個64位分組及可變金鑰長度的對稱金鑰分組密碼演算法 IDEA:(國際資料加密演算法) 發展IDEA也是因為感到DES具有金鑰太短等缺點。IDEA的金鑰為128位 RC4:速度可以達到DES加密的10倍左右,且具有很高級別的非線性。 RC5:引數可變的分組密碼演算法,三個可變的引數是:分組大小、金鑰大小和加密輪數。在此演算法中使用了三種運算:異或、加和迴圈 RC6:在RC5的基礎上設計的,以更好地符合AES的要求,且提高了安全性,增強了效能 AES:AES加密演算法是密碼學中的高階加密標準,該加密演算法採用對稱分組密碼體制,金鑰長度的最少支援為128、192、256,分組長度128位,演算法應易於各種硬體和軟體實現

==========================================================

非對稱加密演算法:加密和解密使用不同金鑰的加密演算法,也稱為公私鑰加密。 優點:公鑰加密私鑰解。使用者只要保管好自己的私鑰就是安全的,同時加密金鑰的分發將變得十分簡單。 缺點:加解密速度要遠遠慢於對稱加密。 破解方案:非對稱加密中只取得一個金鑰往往不能解決問題。除了取得或修改金鑰外,通常還要對協議進行攻擊(如中間人攻擊)。

==========================================================

RSA:RSA是第一個能同時用於加密和數宇簽名的演算法,它能夠抵抗到目前為止已知的所有密碼攻擊。 ECC(移動裝置用):橢圓曲線密碼體制是目前已知的公鑰體制中,對每位元所提供加密強度最高的一種體制。 Diffie-Hellman:一種確保共享KEY安全穿越不安全網路的方法,它是OAKLEY的一個組成部分。 El Gamal:基於1984年提出的公鑰密碼體制和橢圓曲線加密體系。既能用於資料加密也能用於數字簽名 DSA(數字簽名用):基於整數有限域離散對數難題的,其安全性與RSA相比差不多。

==========================================================

Hash演算法(單項雜湊演算法):它是一種單向演算法。使用者可以通過Hash演算法對目標資訊生成一段特定長度的唯一的Hash值,卻不能通過這個Hash值重新獲得目標資訊。 用途:不可還原的密碼儲存、資訊完整性校驗等。 破解方案:想要穩定地從密文中還原單向雜湊加密前的明文幾乎是很困難的。但反過來講,單向雜湊演算法通常沒有金鑰,一般來說直接模仿演算法即可進行加密。

==========================================================

MD2和MD4:它是一種用來測試資訊完整性的密碼雜湊函式的實行。已不再使用。 MD5:以512位分組來處理輸入的資訊,且每一分組又被劃分為16個32位子分組,經過了一系列的處理後,演算法的輸出由四個32位分組組成,將這四個32位分組級聯後將生成—個128位雜湊值。 HAVAL:HAVAL加密演算法可以產生不同長度的雜湊值,包括128位、160位、192位、224位、256位 SHA:安全雜湊演算法主要適用於數字簽名標準(DSS)裡面定義的數字簽名演算法(DSA)。 SHA-1:主要適用於數字簽名標準裡面定義的數字簽名演算法。 HMAC:是金鑰相關的雜湊運算訊息認證碼,利用雜湊演算法,以一個金鑰和一個訊息為輸入,生成一個訊息摘要作為輸出。 HMAC-MD5:是從 MD5 雜湊函式構造的一種鍵控雜湊演算法,被用作基於雜湊的訊息驗證程式碼 (HMAC)。 HMAC-SHA1:是從 SHA1 雜湊函式構造的一種鍵控雜湊演算法,被用作 HMAC(基於雜湊的訊息驗證程式碼)

==========================================================

非加密演算法:主要是一些編碼演算法。如:Base64編碼演算法、CRC32校驗演算法等

加密演算法使用建議:

1、要加密大量的資料時,建議採用對稱加密演算法,提高加解密速度 2、對稱加密演算法不能實現簽名,因此簽名只能非對稱演算法 3、當資料量很小時,我們可以考慮採用非對稱加密演算法 4、採用非對稱加密演算法管理對稱演算法的金鑰,然後用對稱加密演算法加密資料 5、根據的實際需要的安全級別來選擇來選擇採用多少位的金鑰。金鑰越長,執行的速度就越慢

5、數字簽名

概念:是能夠讓接收者驗證訊息來源的一種演算法,數字簽名只產生一段附加資料,不會增加保密性,生成和驗證數字簽名需要不同的金鑰,結合非對稱和單向雜湊加密實現,亦有少量專用演算法。

識別數字簽名:數字簽名不修改資料內容,客戶端生成的簽名通常會以附加資料的形式出現,客戶端驗證的簽名則表現為修改服務端返回的流量後客戶端報錯。

程式碼特徵:同時呼叫非對稱加密演算法和單向雜湊加密演算法。少數專用型數字簽名演算法(如DSA)大多和非對稱加密一樣基於有限域的數學難題,也會包含很多模運算。

破解方案:需要破解數字簽名的常見場景有以下

1、服務端會驗證客戶端簽名(多見於網銀交易類功能) 設法從客戶端程式中找到私鑰,然後仿製其演算法。

2、客戶端會驗證服務端簽名(多為驗證服務端SSL證書) 直接修改客戶端程式,去除其驗證功能(JustTrustMe)。 設法讓客戶端接受一個自行生成的金鑰,實施中間人攻擊。

服務端的公鑰大多以證書形式儲存在客戶端程式中,此種情況下需要替換客戶端所使用的服務端的證書。也有一些APP會呼叫作業系統證書鏈來驗證服務端證書,此時只要從Burp/Fiddler中匯出證書,然後新增到Android裝置中即可

6、逆向演算法的一般步驟

1、設定代理進行抓包,傳輸敏感資訊,發現加密包及加密演算法

2、分析加密包,逆向開啟APK(如IDE等),搜尋關鍵字(主要體現在URL的引數中或POST欄位的引數中,如mobileUser),進入相關smali程式碼處。體現為在對應的Java程式碼處為關鍵字集結處。

3、如果以上Java程式碼難讀,拖入JEB進行分析,也是搜尋關鍵字,分析關鍵字處的Java原始碼。通過掃視試圖發現敏感點。反編譯Java的快捷鍵是Q(大寫),JEB的優勢是反編譯的Java程式碼更加清晰明瞭

4、分析找到原生庫(也就是哪個so檔案,因為一般有多個so檔案),靜態分析so檔案時,先搜尋相關函式。命名規則如下:Java_包名_類名_方法名,建議進入圖形邏輯分析彙編程式碼。

分析左邊圖形邏輯彙編程式碼,同時注意適時下斷點。右鍵點選右側的R1、R2、R3……等 -->jump,即可以在下方檢視具體的值(如加密資料、金鑰等)。右鍵點選右側的PC -->jump,即可跳轉回去(單步除錯過頭了)。只有熟悉ARM彙編才可以看懂整個IDA介面。

5、如果沒有Java開頭的函式,則通常為動態註冊,此時應分析JNI_OnLoad函式。進入該函式後,重點研究RegisterNative三元組(三個資料元素為一個組合)

6、IDA下F5分析C語言程式碼。注意C語言程式碼多不可信,但邏輯基本是可信的,可以通過分析和變數重新命名、新增程式碼註釋等。使得C語言程式碼更加簡便易讀。如果一個暫存器存不下的數(32位),則使用2個暫存器儲存即可(64位,典型體現為立即數後面有個+4)。

7、最可能出現的情況就是:程式碼從Java中跑到so中,再從so跑到Java中,再從Java跑到so中…………

8、定位到關鍵程式碼函式,然後在smali程式碼下插入期望程式碼(即所謂的smali程式碼注入),然後通過除錯日誌等方式即可得到期望資料。插入的期望程式碼通常如下:

#log輸出string型別資料,vx為資料,根據需要更改
	invoke-static {vx}, Lcom/debug;->v_str(Ljava/lang/String;)V

#文字形式寫入string資料到sd卡,檔名為1s.txt
    invoke-static {vx}, Lcom/debug;->txt_str(Ljava/lang/String;)V

#log輸出int型別資料
    invoke-static {vx}, Lcom/debug;->v_int(I)V

#文字形式寫入int資料到sd卡,檔名為1i.txt
    invoke-static {vx}, Lcom/debug;->txt_int(I)V

#注:根據需要將未用到的刪除就行

9、總結:逆向演算法步驟是簡單的,但程式碼分析是非常複雜的,涉及到不斷的下斷點除錯、計算偏移地址、複雜繁瑣的程式碼邏輯分析(主要是熟悉相關加密演算法的加密過程,用以進行逆向演算法分析),目前仍然缺少實踐鍛鍊

7、關於仿製演算法

仿製演算法的原則:

對方是什麼加密演算法,我們就是什麼加密演算法。仿製演算法也可以說是複製演算法(甚至程式碼都可以複製),其和原生演算法是一模一樣的。 我們只仿製核心演算法,拋棄核心演算法以外的限制演算法。

為什麼要仿製演算法:

解決無法抓包、抓包加密、抓包無法修改等問題。仿製的時候通常要仿製其加密演算法,還要仿製其解密演算法。才能使得服務端測試正常進行。

舉例:如繞過輸入限制、繞過傳輸強加密、繞過客戶端伺服器強校驗等。

原則就是讓輸入可見、可修改、可傳輸。

仿製演算法後如何使用:

原生加密演算法存在與手機APP中,仿製的加密演算法存在與PC電腦中。

使用流程:

1、手機APP端進行資料輸入(此時可能存在輸入限制,能輸入啥就輸入啥) 2、輸入的資料經過手機APP原生加密演算法處理 3、處理後資料進入Fiddler抓包處(此時抓取到的是密文或其他不可閱讀和修改的) 4、在PC機上執行仿製的解密演算法 5、將第3步抓取的密文資料放入解密演算法中 6、經過解密演算法運算,輸出明文。此時可以修改明文為攻擊字元 7、執行PC機上仿製的加密演算法(和原生加密演算法等同),將第6步修改的明文加入 8、產生密文輸出(此時為攻擊字元進行了原生加密) 9、將產生的密文放入Fiddler,然後發包即可

整體思路:抓取到密文 --> 解密為明文 --> 修改明文 --> 重加密傳送