KeyGenerator生成对称密钥需严格遵循安全规范:调用JCE安全随机源、按标准算法(如AES-256、SM4、HmacSHA256)结构化生成,经getInstance→init→generateKey→getEncoded四步获取字节数组,并安全存储与脱敏使用。

KeyGenerator生成对称加密密钥不是“写个随机字符串”那么简单,关键在安全、规范、可复用。它本质是调用JCE内置的密码学安全随机源(如SHA1PRNG),按算法标准结构化产出密钥字节,避免人为引入偏差或弱熵。
选对算法和长度是前提
不同场景对应不同组合,不能一概而论:
- AES最常用:支持128/192/256位,生产环境推荐256位(AES-256)
- SM4国密场景:固定128位,需用
cryptoFramework.createSymKeyGenerator(鸿蒙/可信执行环境) - HMAC类密钥(如HmacSHA256):不强制长度,但建议≥256位,确保抗碰撞强度
- DES已淘汰,3DES也逐步弃用,新项目请绕开
四步生成密钥,缺一不可
标准流程有明确顺序,跳步易出错:
- 获取实例:
KeyGenerator.getInstance("AES")——必须传标准算法名,大小写敏感 - 初始化尺寸:
keyGen.init(256)——单位是比特(bit),不是字节;256位=32字节 - 生成密钥:
SecretKey secretKey = keyGen.generateKey()——返回的是封装对象,非原始字节数组 - 提取编码:
secretKey.getEncoded()——这才是真正用于加解密的byte[],后续可Base64或Hex编码存储
密钥不能明文硬编码或日志打印
生成后立刻做两件事,否则等于裸奔:
-
存储隔离:密钥字节不要存配置文件或数据库明文表;优先进Android KeyStore / iOS Keychain / Java KeyStore(JKS)或鸿蒙
KeyStore服务 -
使用脱敏:调试时打印密钥,务必只打前4位+省略号,例如
Ux7f...aB2k;上线代码中彻底删除所有System.out.println(secretKey)类语句 -
避免toString():
new String(secretKey.getEncoded())会生成不可靠字符串(含控制字符),应始终用Base64或Hex编码转换
常见坑与避坑提示
这些细节不注意,轻则运行报错,重则密钥失效:
-
SecureRandom未显式指定:默认可能用弱随机源(尤其旧JDK),建议显式传入:
keyGen.init(256, new SecureRandom()) -
算法名拼错:写成
"Aes"、"aes-256"或"AES256"都会抛NoSuchAlgorithmException -
密钥复用风险:同一
SecretKey对象不能跨线程并发用于加解密(部分Cipher实现非线程安全),应每次操作新建Cipher实例 -
IV不能省:AES-GCM等AEAD模式下,密钥只是基础,还必须配唯一Nonce/IV——它不通过KeyGenerator生成,需单独用
SecureRandom生成并随密文保存










