android+静态密钥,Android - 更安全地保存静态密钥
轉載請注明出處:https://blog.csdn.net/mythmayor/article/details/107228669
引言
在日常開發中我們經常需要保存一些私密的信息,例如加解密的密鑰等等。這時候我們就要來考慮如何存儲密鑰了。先來簡單介紹幾種存儲方式:
Java硬編碼方式
SharedPreferences存儲
文件存儲
數據庫存儲
以上幾種存儲方式是很不安全的,例如采用硬編碼方式存儲,程序包很容易被反編譯獲取到密鑰。SharedPreferences、文件和數據庫又有可能因為用戶的誤刪操作而丟失密鑰,所以一般很少存儲到這一類的文件中。那么問題來了,我們應該用什么方式來確保密鑰的存儲相對更安全呢?
密鑰存儲方案
在日常開發中,推薦運用若干種方案拼接起完整的密鑰。
在下面的案例中,我將運用以下方式輸出密鑰各部分內容(后面會逐個講解)
Java硬編碼
gradle配置
特殊的算法
利用strings.xml
現在假設我們需要進行AES加解密,按要求來定義一個密鑰,密鑰的形式可能是這樣的:
String AES_KEY = "1234567890!@#$%^";//硬編碼方式定義AES密鑰
是不是已經有同學看不下去了。。。
好吧,更好的方式是這樣的:
String AES_KEY = ProjectUtil.getAESKeyPart1(3, 4)//根據自定義算法輸出密鑰第1部分
+ BuildConfig.AES_KEY_PART2//根據gradle配置輸出密鑰第2部分
+ CommonUtil.getString(R.string.AES_KEY_PART3)//根據string.xml輸出密鑰第3部分
+ MyConstant.AES_KEY_PART4;//根據硬編碼方式輸出密鑰第4部分
String AES_KEY_PART4 = "!@#$%^";
怎么樣?是不是瞬間感覺難懂了一些,下面就來逐一講解。
第一部分:ProjectUtil.getAESKeyPart1(3, 4)
這部分很好說,這里我自定義了一個算法,用以迷惑“有緣人”
public static int getAESKeyPart1(int x, int y) {
for (int i = 1; i <= x * y; i++) {
if (i % x == 0 && i % y == 0)
return i;
}
return x * y;
}
我這里定義的算法主要輸出的是數字,在實際開發中你也可以定義一些類似的算法。
第二部分:BuildConfig.AES_KEY_PART2
這里主要是通過gradle的配置來自動生成AES_KEY_PART2這個常量。具體操作如下:
打開Module下的build.gradle文件,在android標簽下的buildTypes下添加配置。
buildTypes {
release {
buildConfigField "boolean", "LOG_DEBUG", "true"//顯示Log
buildConfigField "String", "AES_KEY_PART2", "\"3456\""
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
buildConfigField "boolean", "LOG_DEBUG", "false"//不顯示Log
buildConfigField "String", "AES_KEY_PART2", "\"3456\""
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
如上所見,我使用buildConfigField關鍵字添加了LOG_DEBUG和AES_KEY_PART2兩個字段。LOG_DEBUG用以控制是否輸出并顯示Log。在添加完配置之后,就可以Rebuild項目了,然后你就可以打開自動生成的BuildConfig類,這時候你添加的常量就在此類當中了。
public final class BuildConfig {
// ...
public static final String AES_KEY_PART2 = "3456";
public static final boolean LOG_DEBUG = false;
}
需要注意的是,在定義字符串(尤其是數字字符串)的時候,一定要定義成:
buildConfigField "String", "AES_KEY_PART2", "\"3456\""
而不是
buildConfigField "String", "AES_KEY_PART2", "3456"
原因是第一種方式的話會在BuildConfig中生成
public static final String AES_KEY_PART2 = "3456";
而第二種方式則會在BuildConfig中生成
public static final String AES_KEY_PART2 = 3456;
第二種自然就會報編譯錯誤了。
第三部分:CommonUtil.getString(R.string.AES_KEY_PART3)
在我的strings.xml中定義了一個字符串:
7890
第四部分:MyConstant.AES_KEY_PART4
在我的MyConstant類中定義了一個常量:
String AES_KEY_PART4 = "!@#$%^";
總結
上面介紹的密鑰存儲方式極大的增加了逆向的難度,輔以代碼混淆等手段,在很大程度上提高了密鑰存儲的安全性。總體來說,在App端保存密鑰并無法完全保證密鑰的安全性,只能通過一些手段增加被反編譯的難度。
總結
以上是生活随笔為你收集整理的android+静态密钥,Android - 更安全地保存静态密钥的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阅读分析下列html,阅读下列说明和HT
- 下一篇: 多用继承 android,Android