Android加密解密工具类
Android开发里,加具类加密不是密解密工"加上就行"的事。我见过太多项目,加具类加密工具类写得像摆设——用AES却把密钥硬编码在代码里,密解密工用RSA却把私钥存在assets目录。加具类这等于给保险柜贴了张纸条:密码在门垫下面。密解密工
先看最常用的加具类对称加密AES。写工具类时,密解密工密钥生成必须用SecureRandom,加具类别用Random。密解密工Random的加具类种子是时间戳,攻击者能预测。密解密工还有个坑:Android 7.0以上,加具类SecureRandom默认实现变了,密解密工有些老代码会崩。加具类所以我在工具类里固定用"Crypto"提供者,虽然官方标记过时,但兼容性最好。
public static SecretKey generateKey() throws NoSuchAlgorithmException { KeyGenerator kg = KeyGenerator.getInstance("AES"); kg.init(256, new SecureRandom()); return kg.generateKey(); } 加密模式我推荐GCM,不是CBC。GCM自带认证,密文被篡改能直接检测出来。CBC要额外算MAC,很多人偷懒不算,结果被padding oracle攻击。但GCM有个细节——IV不能重复。同一个密钥下,IV重复一次,攻击者就能还原明文。所以工具类里IV要用随机数,拼接在密文前面存储。
非对称加密RSA更麻烦。Android的RSA实现默认用PKCS#1填充,这没问题。但加密长度限制很多人不知道:1024位密钥只能加密117字节,2048位只能加密245字节。真要加密大文件,得用"RSA加密AES密钥,AES加密数据"的混合方案。我写过一个工具类,加密流程是:生成随机AES密钥→用RSA公钥加密AES密钥→用AES-GCM加密数据→把加密后的密钥和密文打包。解密反过来。这样既安全又能处理任意大小数据。
还有个日常容易忽略的:Base64编码别用Android自带的。android.util.Base64的encodeToString方法,默认会在每76个字符加换行符。这换行符在存储或网络传输时经常被吃掉,导致解密失败。我用java.util.Base64(API 26+),或者干脆自己写个简单的Base64工具,避免平台差异。
最后说个真实案例。上个月接手一个外包项目,对方用我前同事写的加密工具类,解密老报错。查了半天,发现密钥存储用了SharedPreferences,但没做加密处理。虽然密钥是AES加密过的,但加密密钥的密钥存在同一个文件里——这跟把钥匙放在锁旁边没区别。后来我改成用Android Keystore系统存储主密钥,应用进程被root也读不到。
写加密工具类,核心就一句话:别自己发明算法,别忽略平台细节,别把密钥和密文放一起。代码写出来容易,但每个决策背后都是血泪教训。你要是真在乎数据安全,就多花点时间测试边界情况——IV重复、密钥长度、填充模式、Android版本差异,这些坑踩一遍就记住了。






评论专区