為什麼這麼多商業Android開發者不混淆代碼?

最近蜻蜓FM數據造假搞得滿城風雨,最讓我大跌眼鏡的是蜻蜓FM居然沒有混淆代碼!!!反編譯下再修復幾十處語法錯誤就還原整個項目了。之前還發現過一個小米的項目沒有混淆,兩天就能把APK徹底還原為完整項目。不過小米這項目是沒有推廣的,估計已廢,情有可原。但是最近找工作了解公司資料時又發現一個百萬級用戶的APP沒有混淆,頓時感覺眼睛都瞎了,混淆這種 一兩天就可以搞定的事情為什麼這麼多程序員不做,不混淆代碼外泄不說,還有很嚴重的安全風險。上面這三例的公司都不是小公司額,第三個也是比較出名的公司,裡面的程序員必然不是菜鳥,但是為什麼這麼大意,學Java的人應該都知道中間位元組碼是很容易被逆向工程的,難道這個世界真有這麼多人神經大條到這種程度?求解,前面說的都是完完全全沒有一點混淆的。

--------------------------------------------------------

以下是補充,我發現部分人只說了意見,沒分析相關影響的大小差別,應不應該混淆取決於收益是否大於 代價,說下實踐中知道 的好處,第三點是重點

1、縮小包體,我的情況是可以縮小兩成包體

2、保護代碼不被競爭對手輕易使用,我寫的項目裡面有 幾個功能是花了 兩三天才找到實現思路的,如果被別人直接看到代碼一天內就可以把代碼移值過去,節省大量時間。

3、增加破解難度,提高安全性,完全沒混淆半個鐘就可以看到所有代碼,有很大風險,很容易造成漏洞被利用,現在有做支付之類機密功能的應用很多。蜻蜓FM如果有混淆,恐怕他的底褲不會被揭的那麼徹底。我看了源碼,數據作假的代碼分布還是挺廣的,只是沒混淆, 很容易從命名上猜出裡面有貓膩逐步翻出問題。

壞處我目前只知道一點就是一年裡面要花 兩三個工作日左右(多項目)寫和改混淆腳本, 收益還是大於代價的。以後其他項目還可以快速利用。至於難調試我認為是不存在的,混淆可以留行號和代碼文件對應的類名。即使我沒辦法杜絕破解,但是我花一天時間搞個混淆使得破解者多花了幾天時間,還是很賺的,能讓大部分破解者擔心代價高與收益,從而選擇放棄就已經成功了。

------------------------------------------------------

再補充一句,睡覺前大家都會關門,防不住大盜,總能防住小流氓。


有些答案說的好像混淆了就安全了,不混淆就不安全一樣,我覺得其實沒有必然的聯繫,使用 ProGuard 與否應該根據項目實際情況而定。

混淆不能阻止反編譯,只能增加反編譯以後閱讀理解的難度罷了,安全的代碼依然安全,不安全的代碼不會因為用了 proguard 就變得更安全。你代碼再混淆再加固再怎麼樣怎麼樣最後用 http 傳輸、最後明文傳輸密碼、最後自己開了後門、最後把數據保存在了 external storage,不還是白費?最近看了 Twidere 作者 @Mariotaku 的推,他的想法是把 StringBuilder 替換了,每次 toString 的時候 log 下來,這種時候底褲都被人看去了,什麼 so 啊 jni 啊混淆啊加固啊都沒有用,不如好好考慮一下伺服器端以及通信協議的安全。

開發 Android 沒有人不知道 Jake Wharton 大神吧,也沒有人沒用過 Square 的開源庫吧?Jake 除了寫開源軟體(當然沒必要混淆)以外,也寫商業 app。他對於 ProGuard 的態度就很有意思 —— 完全不去用。感興趣的可以搜搜他的 Twitter 和一些播客的採訪;而 Square ——一家做支付的公司 在他們的 Android Apps 中也沒有用使用 ProGurad 或者做任何混淆,原因很簡單:他們的價值不在 client 而在 server 端,並且無論 client 還是 server 的安全性都相對較好。

用不用 ProGuard 完全是一個成本和收益的權衡,如果公司在 Android 開發上的資源少,依賴的項目多,盲目的使用 ProGuard 並不一定是最佳選擇。線上 bug 的快速處理和 app 功能的快速迭代才是這時期的重點。使用 ProGuard 會增加你每次升級依賴版本、升級 build tools 以及發布以後錯誤報告收集的成本。(本人不才,沒有寫過超大的項目,但是估計有些大公司依然使用較久遠的 SDK Version 一定程度上可能是代碼混淆拖了後腿);如果公司規模較大,或者代碼在公司價值中的比重較重,又或者10%-20%的文件大小很重要,那麼採取 ProGuard 肯定是必須要做的措施之一。

另外我猜測一下為什麼國內環境下混淆以及所謂加殼加固看得那麼重:國內沒有統一規範的 Android 市場:論壇的盜版 apk 橫飛,各種有著不能說的秘密的 ROM;各個市場管理混亂,甚至監守自盜;運營商劫持 apk 下載鏈接,諸多混亂的因素導致了無法像 Square 在國外一樣分發安全可靠的軟體,必然引起這方面的大量安全需求。本人在國外開發 Android,菜鳥一個,最近加了些國內開發的群,感覺牛人多的我數也數不過來,但是總感覺他們為了解決國內特殊環境下的問題,相當多的精力都浪費掉了,如果這些精力用在做更好的 app 上。。。算了不提了。

順便 po 一下上文提到的一些 Tweet:

https://twitter.com/jakewharton/status/410083660545544192

https://twitter.com/JakeWharton/status/524449103451672576

https://twitter.com/mariotaku/status/682096634583322624

播客實在不好搜索,你們自己找吧,Jake Wharton 參與的播客也就那幾個,總共六七集幾百分鐘而已 :p


很多人提到「寫個腳本,或者打個勾順手就混淆了」,但你們就沒想過為什麼這麼簡單他們還不混淆?

僅僅是因為絕大多數人安全意識不夠嗎?

確實,混淆耗費開發人員的開發時間很少,但寫代碼的時間本來就是不大的一塊時間,更多的時間用在開會、討論技術方案、修BUG上。

一年半之前,我們公司APP在0.5%以上的機器產生FC,就當作很嚴重的事故;今天變得更加嚴格了。有些問題測試時不可能發現,出了問題也很難復現,即使用戶告訴你復現的步驟在公司的機器上仍舊不能復現。

我們專門有一套系統來收集APP產生的問題日誌,監測FC情況,同時回傳FC相關信息及日誌。一旦混淆,解bug工作量直線上升啊。

另外,我們每15分鐘進行一次預編譯,每一兩個小時一次完全集成編譯,編譯出錯要及時修復以免影響其他開發人員。混淆了可怎麼辦?又不是一個APP寫完就完了,是要不斷添加新功能的,一周一次有的吧~~

編譯及測試要以最終代碼來進行(和發布產品唯一不同的是release key),代碼明明沒問題,可是混淆之後出問題的情境大把大把的。

終究是個成本與收益的問題,很簡單的混淆能夠提升一大截反編譯的成本。

但是否進行混淆,要綜合考慮業務場景、取得的收益、付出的成本,還有如果不混淆可能產生的危害。

我們公司大部分產品沒有混淆,與隱私活安全相關的APP會進行混淆或者直接打以so文件形式提供。

我不認為國內這麼多APP不混淆都是安全意識的問題。

這是個成本與收益的問題。


我來舉個真實例子說明

1.幾十萬代碼量項目裡面毛有用的東西都沒有,結構混亂自帶混淆,自己找個模塊都找不到。。。

2.產品策劃只看崩潰率,代碼n年經手n個團隊,混淆坑比較大。

3.曾經我把混淆補全,但是居然因為崩潰上報的堆棧不可讀而系統載入mapping文件有bug而否了混淆包。

4.不做那個項目好久現在好像又加回去了。

以上都是借口。

究其原因是

項目不受重視,很多東西就得過且過了。


從後來回過來看,對於大部分人來說,還是有成本的問題。畢竟由於混淆引起的問題太多了,而大部分人不願意花時間處理這種看起來無關緊要的事情。

---------------------------------------------------------------------------------------------

看到這麼多人安全意識這麼差,認為混淆沒什麼卵用也就見怪不怪了。
從整個安全行業來講,很多企業都不注重安全引發的問題少么?想想最近的網易。
再看看烏雲上的曝光的各種漏洞,有多少是因為安全意識不行引起的。

不混淆可以認為這個企業的安全意識差,開發人員意識不好。

前面有同學提到混淆會帶來額外開銷,拜託,看下官方文檔好么?

The ProGuard tool shrinks, optimizes, and obfuscates your code by removing unused code and renaming classes, fields, and methods with semantically obscure names. The result is a smaller sized .apkfile that is more difficult to reverse engineer. Because ProGuard makes your application harder to reverse engineer, it is important that you use it when your application utilizes features that are sensitive to security like when you are Licensing Your Applications.

http://developer.android.com/intl/zh-cn/tools/help/proguard.html

Proguard通過移除沒有用到的代碼以及通過特定規則重命名類、變數、方法來壓縮、優化、混淆你的代碼。這樣做可以讓你的apk更小,更難被逆向分析。由於可以提高被逆向分析的難度,對相關功能安全敏感的應用使用它是十分必要的。

簡單的移除沒用到的類以及重命名,哪裡會帶來性能開銷了,哪裡帶來卡頓了。
不是加固好么?加固對性能會有影響,這是由於大部分的加固的原理都是運行時解密相關資源的。

然後說大眾點評沒有混淆的,混淆容易導致問題,看看微信,QQ ,支付寶這些億級用戶量的產品,學學它們,不要老是盯著大眾點評。

沒有什麼卵用,Google閑著蛋疼支持這玩意啊。

這不是能力問題,是安全意識,培養一個好的安全意識不好么?等到某一天終於做一個跟錢打交道的應用,卻發現沒混淆帶來大量損失才後悔莫及?

混淆是必要,當然有些時候特殊需求,比如說熱修復,需要用到反射,可能相關的類不會被混淆。但完全不混淆就是開玩笑好么?

被破解是無法避免的事情,只是難度問題而已。破解與保護,互生互滅。能提高一點是一點。
代碼確實不值錢,反正家裡啥都沒有,就幾件破衣服,隨便拿吧。

這次蜻蜓FM的事情如果混淆了,會被扒的這麼徹底么?想想?從單純的職業道德來講,是不是為企業避免了不少損失?

另外,混淆不需要太多時間,快半天,慢2-3天就完全可以搞定,而且一次混淆,多次復用(其他項目稍作調整即可)。

以上。


混淆代碼的應用場景,就是你的整個業務是靠軟體來直接賺錢的,如PS,3DMAX,軟體開發工具等生產力工具。這類軟體直接賣,就能產品利潤,於是可以說是軟體本身比較重要所以需要保護。

ANDROID軟體,本身在業務上只是解決了產品的問題,它真正的贏利不是通過軟體本身來實現,而是要通過運營,運營才是產生利潤的關鍵,在這種情況下,產品本身的重要性就不是很大了,保不保護也就並不重要,更何況,代碼混淆保護的其實是偏重於技術,而目前又有哪個技術是就你會別人都不會的呢,所以混淆代碼在ANDROID上不流行,主要是沒這個必要。


普通程序員如果說代碼混淆沒啥用還能理解,但是樓上一個名號是「安全諮詢顧問」的說出這句話就讓我有點疑惑「顧問」的職業水平到底如何。安全對抗向來只是成本之間的對抗,你搞再高級的防禦手段總是有人能把你給破解了。舉個例子,微軟在vista之後的系統加入了ASLR地址隨機化機制,但是從那之後還是有很多利用能夠繞過這個機制,難道就說ASLR沒用?增加的安全機制只是為了增加破解和系統被利用的難度,讓想破解的人成本更高,當獲取的利益少於攻擊成本的時候系統本身的安全性能就可以說比較高。而代碼混淆就是安全機制的一種,雖然比較弱。

再回到安卓這件事上,去年研究了幾個月的安卓APP安全狀況,別說加殼這種高端一些的了,即使是題主說的代碼類名混淆都很少有APP做到,這就導致了分析其網路協議很簡單,同時安卓的很多數據都是APP自己放在SD卡目錄下,所有的APP都能讀取到,獲得源碼之後能夠輕鬆的獲取這些數據,雖然很多都是加密,但是要麼是演算法自己實現很容易逆向要麼密鑰直接硬編碼在代碼里,還是比較容易獲取的。雖然這些本來就有安全問題,是不應該這麼做的,但是你如果加入代碼混淆甚至是加殼換so文件等能讓能夠逆向出你代碼機制的人更少,不會出現一個剛接觸逆向的人就把你的代碼看的一乾二淨,數據、網路協議也都輕鬆獲取到。真正想要逆向你這個代碼混淆的人也會掂量掂量成本是不是會太高。

沒有絕對的安全!!!

但是代碼混淆確實是比較低級的手法,要在這個基礎上把核心代碼放到so文件裡面,然後java和C/C++代碼都加殼,能夠使得逆向的成本變高,APP也就相對越安全。


因為不會....


這裡面應該是有這些原因存在:

  1. 領導、產品、項管在這方面沒有意識,不重視。
  2. 單靠ProGuard是不夠的, 隨隨便便就被反編譯了,況且一些Activity,Service的名字不能被混淆,混淆後xml文件中相關的類找不到它們了。還有一些反射相關的也不能被混淆,等等…
  3. 混淆後增加了測試成本。
  4. 國內的安全意識普遍沒有那麼高。

其實自動打包時,大多數公司還是會用官方提供的Proguard的默認混淆的(個別公司除外)。蜻蜓FM也混淆了,用的就是Proguard 然而並沒有什麼卵用。

混淆想做到安全,還是需要自己做,或者購買一些第三方專業的混淆工具,比如:

  1. 國外的DexGuard,一年600多刀,效果不錯。混淆後反編譯出來的都是亂碼,但這樣成本並不是一兩天時間,可能會遇到:
    1. 混淆後部分應用市場讀卻不到AndroidManifest.xml中的相關信息,審核失敗的情況
    2. 還有比如有時對gradle打包支持不到位,需要特別寫腳本支持混淆流程的
    3. 接入一些第三方的庫混淆後會有問題等等要解決,
    4. 還需要經常升級混淆程序,所以總體還是會耗費不少時間的。
  2. 像微信連資源文件名都混淆,並且大部分東西都放在.so文件中,估計是自己做的,這個是需要一定精力的。
  3. 國內的沒使用過,有一些什麼梆梆加固,愛加密的,不知道混淆效果如何……

總的來說,並不是像你想像的直接ProGuard 就很快很容易搞定的。


沒必要,安全不是靠混淆就行的。Google的所有gms應用都沒混淆,一樣安全。

混淆只是拿草蓋住洞口。有心人還是能找到。找到了你就大門洞開了。要安全,得裝鎖。


對於整個項目來說,代碼是最不值錢的。


混淆加殼什麼的就是唬一下小白,提高一點門檻,想搞你還是隨便搞,這種事情關鍵還是法律這塊得跟上。

混淆加殼就像是每個人上街都要穿件防彈衣,這能算一個好的解決方法嗎?你是以為防彈衣能防得住大炮導彈?

當然還是要規定殺人是犯罪,會被抓起來判刑,這樣才能防止隨便上街就被殺。不過目前我國程序員法律意識也還比較吊,都覺得殺人不犯法,還要拍視頻寫文章上傳,說他殺了人以後解剖他的屍體發現裡邊藏有毒品,所以他殺人不犯法。


前段時間在一個小型講座上和藍盾在本省的銷售總監聊過這方面的話題,怎麼讓普通大眾或是一個公司意識到信息安全的重要性,總監很無奈說,根本沒有辦法,除非這些人真的受到別人攻擊造成損失後,才會認真對待起這個問題來,

代碼混淆到底有多重要,我估計只有蜻蜓FM的老闆最有資格回答這個問題…


不混淆?開什麼玩笑嘛,一線APP都混淆啊。

至於說破解問題,本來安全就沒有絕對的,增加難度而已。

鑒於我這類渣渣程序員的存在,混淆和不混淆的閱讀難度增加90%以上,能擋掉90%我這類的程序員啊。

而且,混淆基本都是一勞永逸的,即使業務改了,混淆可能就增加那麼幾行而已,沒什麼難度,更談不上有答主說的成本。如果這對程序員都造成成本壓力,那我覺得,這個程序員本身就造成成本壓力,裁掉較好。

何況啊,混淆這個東西一個team,只要一兩個人去負責就好了,別的可以不管啊。當然,如果混淆使用@annotation等這類方法標註混淆方法的,就需要每個開發人員去掌握哪些該混淆哪些不該。

安全意識很重要啊,時刻惦記著。


代碼寫的太爛,天生帶混淆。

過幾天自己都看不懂啦。


假設支付寶有一億用戶,混淆後導致的出錯率是萬分之一,也就是可能會有一萬用戶投訴,這個投訴量你試試看~另外混淆帶來的卡頓和性能下降就不說了。


代碼寫的爛,沒臉混淆:)


題主,你說說混淆可以有什麼明顯的好處么?

我來一條一條說混淆可能的好處。

第一個好處呢,是所謂「保護源碼或者項目」。程序員們保護自己的勞動果實,這麼想也是正常的。

但很可惜,在絕大部分互聯網項目中,是商業模式,或者用戶感受,比那個代碼更重要。代碼很容易抄,但抄代碼就能抄到商業模式或者市場份額反超的,極少。

常見的電商和網路代理,在代碼層之下是大量的商業邏輯、合同談判與執行。這不是寫代碼能解決的,而是很多繁重的臟活兒,代碼只是提高了他們的效率,但並沒有決定成敗。

而且關鍵的邏輯實現也不是APP代碼實現的,主要依靠伺服器端,伺服器代碼才是被嚴格保護的。APP端主要負責「好好呈現+提高呈現效率」

第二個好處呢,是保護源碼不被篡改。

從安全防護的角度出發,這是個好點子,也經常被實踐。很多編譯器都支持「安全編譯」,實際上就是做代碼混淆類似的事情。

但是!這種保護是有限的。它的作用更近似於「聊勝於無」。這種混淆是靜態的,有心的傢伙們總是可以慢慢順藤摸瓜,找出邏輯來。想篡改,何必找到所有邏輯,找出保護的那一部分就好了。

現在高安全性的防篡改系統,一般都是依賴於伺服器檢查的,還有依賴於TPM機制或者證書級的簽名機制。改吧,改了就直接用不了了。問題的關鍵不在於防改,而在於改了以後能及時發現並處理。

說夠了好處,可以說壞處了吧?

第一個壞處,就是因為各種額外的花指令的存在,其運行效率下降了。玩具級的程序不怎麼關注效率,規模的商用程序可是很關注的。能在越多的各種性能差異的手機上運行,市場空間佔據可能性就越大!不是有句話「得屌絲者得天下」么。

第二個壞處,就是故障修復極其困難

花指令是雙刃劍,破解者費力,開發者也頭疼。各種調試信息都從程序中去掉了,日誌可能也殘缺得很,萬一出點啥事,怎麼修?

哦,有人說「重新編譯一個正常的」。拜託,目標程序都不一樣了,你確保故障可以重現?

項目規模小點還能忍,多了就不好說了。

第三個壞處,就是順帶著拖慢上市節奏。

都知道市場是「快魚吃慢魚」,「天下武功,唯快不破」。就不多說了。

為了快,大段大段採用開源代碼的事情都能做出來,這種代碼還需要保護什麼…


很多app就和前端網頁一個性質,有什麼要隱藏的嗎,我們的伺服器API都是完全不信任移動端的設計。如果有漏洞混淆只是提高尋找漏洞的成本,從邏輯上完全避免漏洞才是根本。我們現在的渣渣app可以說開源都不會有什麼問題。不過看了很多開源項目都打了混淆,混淆是一個app開發者的素養。


從破解的角度說,混淆增加了破解的時間。混淆後的代碼,方法和變數都變成了各種abcdefghi。。。。可讀性極差,然並卵,還是可以破解。

如果沒有混淆,幾乎是把源碼拱手讓人!所以,關鍵的邏輯還是寫在伺服器端或者打包成.so庫文件


如果把一個系統的安全性託付於終端,那一定是設計的架構有問題


推薦閱讀:

離線攻擊是如何實現的?
whu計算機類的三個專業都有什麼特點?
信息安全專業的發展會受到文憑的限制嗎?
如何評價 2017年5月27日 chrome 插件 infinity new tab 被黑事件?
iphone5被偷了,在不刷機的前提下,小偷是怎麼破解了開機密碼的?

TAG:移動互聯網 | Android開發 | 信息安全 | 移動開發 |