Angular 6中如何实现同一手机号生成固定加密输出?
同一手机号加密后输出固定值的实现求助
我正在做客户手机号注册功能,需求是把手机号加密后存储,同时在会话里保存这个加密后的手机号。但现在遇到个问题:退出应用重新登录后会话就失效了,没法从会话里拿到加密手机号。所以我想能不能实现一种加密机制,让同一个手机号每次加密输出都完全相同?
以下是我目前在用的加密代码:
public encrypt_mobile(mobile): Observable<any> { var salt = crypto.lib.WordArray.random(128 / 8); var key = crypto.PBKDF2("123", salt, { 256: 256 / 32, 100: 100 }); var iv = crypto.lib.WordArray.random(128 / 8); var encrypted = crypto.AES.encrypt(mobile, key, { // 可尝试替换为某字符串或“9876543210” iv: iv, padding: crypto.pad.Pkcs7, mode: crypto.mode.CBC }); var encrypted_mob = salt.toString() + iv.toString() + encrypted.toString(); console.log("encrypted : ", encrypted_mob); return encrypted_mob; }
解决方案
嗨,这个问题其实很好解决!你当前代码里每次加密结果不一样的核心原因,是每次都生成了随机的salt和iv——这俩值一变,即使同一个手机号,最终加密出来的结果肯定也不一样。要实现同一手机号加密输出固定值,你只需要把salt和iv固定下来就行,不过这里得注意安全细节,我给你拆解一下:
1. 核心修改思路
把原本随机生成的salt和iv换成固定的字符串(注意要符合对应的字节长度要求:128位即16字节),这样每次加密用的密钥和初始向量都一致,同一个手机号的加密结果自然就固定了。
调整后的代码示例:
public encrypt_mobile(mobile): Observable<any> { // 固定salt:16字节(128位),替换成你自己的专属固定字符串 var salt = crypto.lib.WordArray.create('your-secure-fixed-salt', 128/8); // 固定iv:16字节(128位),同样用专属固定值 var iv = crypto.lib.WordArray.create('your-secure-fixed-iv', 128/8); // 用固定salt生成密钥,保证每次密钥完全相同 var key = crypto.PBKDF2("your-secure-key", salt, { keySize: 256 / 32, iterations: 10000 }); var encrypted = crypto.AES.encrypt(mobile, key, { iv: iv, padding: crypto.pad.Pkcs7, mode: crypto.mode.CBC }); // 因为salt和iv是固定的,不需要再拼到加密结果里(解密时直接用固定值即可) var encrypted_mob = encrypted.toString(); console.log("encrypted : ", encrypted_mob); return encrypted_mob; }
2. 关键安全提醒
- 绝对不要把密钥、固定的salt和iv硬编码在前端代码里!如果是前端项目,这些敏感值应该从后端接口安全获取,或者放在受保护的环境变量中,避免被恶意窃取。
- 固定iv会带来小范围安全风险:相同的明文会生成相同的密文。但如果你的场景只是用来在会话失效后匹配手机号,这个风险是可控的;如果是高安全要求场景,建议结合业务做额外处理(比如给手机号拼接固定的业务标识,但这样会破坏“同一手机号加密结果固定”的需求,需要你权衡)。
- PBKDF2的迭代次数建议调高到10000次以上,增强密钥的抗暴力破解能力。
3. 额外优化建议
既然你需要在会话失效后匹配加密手机号,后续可以直接用固定的加密逻辑解密,或者直接用加密后的固定值去数据库查询(因为同一手机号加密结果固定,数据库存储的也是这个值),这样就完全不需要依赖会话了。
内容的提问来源于stack exchange,提问作者Prathish
相关产品推荐
相关产品推荐

