小程序解密手机号记录采坑

本文介绍了一种使用Java实现的微信小程序数据解密方法。通过AES-128-CBC算法进行解密,并解决了在解密过程中遇到的IllegalBlockSizeException异常问题。文章详细解释了如何配置解密所需的密钥和初始向量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看到另外一个大哥代码:https://blog.youkuaiyun.com/NepalTrip/article/details/90447798
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.security.Security;

public class WxUtils {
    /**
     *    * 微信 数据解密<br/>
     *    * 对称解密使用的算法为 AES-128-CBC,数据采用PKCS#7填充<br/>
     *    * 对称解密的目标密文:encrypted=Base64_Decode(encryptData)<br/>
     *    * 对称解密秘钥:key = Base64_Decode(session_key),aeskey是16字节<br/>
     *    * 对称解密算法初始向量:iv = Base64_Decode(iv),同样是16字节<br/>
     *    *
     *    * @param encrypted 目标密文
     *    * @param session_key 会话ID
     *    * @param iv 加密算法的初始向量
     *
     */
    public static String wxDecrypt(String encrypted, String session_key, String iv) {
        String result = null;
        byte[] encrypted64 = Base64.decodeBase64(encrypted);
        byte[] key64 = Base64.decodeBase64(session_key);
        byte[] iv64 = Base64.decodeBase64(iv);
        try {
            init();
            result = new String(decrypt(encrypted64, key64, generateIV(iv64)));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     *    * 初始化密钥
     *
     */

    public static void init() throws Exception {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        KeyGenerator.getInstance(WxConstant.AES).init(128);
    }

    /**
     *    * 生成iv
     *
     */
    public static AlgorithmParameters generateIV(byte[] iv) throws Exception {
        // iv 为一个 16 字节的数组,这里采用和 iOS 端一样的构造方法,数据全为0
        // Arrays.fill(iv, (byte) 0x00);
        AlgorithmParameters params = AlgorithmParameters.getInstance(WxConstant.AES);
        params.init(new IvParameterSpec(iv));
        return params;
    }

    /**
     *    * 生成解密
     *
     */
    public static byte[] decrypt(byte[] encryptedData, byte[] keyBytes, AlgorithmParameters iv)
            throws Exception {
        Key key = new SecretKeySpec(keyBytes, WxConstant.AES);
        Cipher cipher = Cipher.getInstance(WxConstant.AES_CBC_PADDING);
        // 设置为解密模式
        cipher.init(Cipher.DECRYPT_MODE, key, iv);
        return cipher.doFinal(encryptedData);
    }
}
public class WxConstant {
    public static final String appid = "你的appid";
    public static final String secret = "你的secret";

    public static final String AES = "AES";
    public static final String AES_CBC_PADDING = "AES/CBC/PKCS7Padding";
}

我这边是根据openid缓存sessionkey。

结果报IllegalBlockSizeException:last block incomplete in decryption问题,

public class WeiXinMiniPartybuildController {
    @Inject
    WeixinMiniProgramPlugin weixinMiniProgramPlugin;

    @CrossOrigin
    @GetMapping("/getOpenid")
    public ResponseEntity<?> getOpenid(String code){
        return ResponseEntity.ok(weixinMiniProgramPlugin.getJscode2session(code));
    }

    @CrossOrigin
    @PostMapping(path = "/getPhoneNumber",produces = MediaType.APPLICATION_JSON_VALUE)
    @JsonView(BaseEntity.BaseView.class)
    public ResponseEntity<?> getPhoneNumber(String encryptedData,String iv,String openid){
        String session_key = weixinMiniProgramPlugin.getSessionKey(openid);
        if (StringUtils.isEmpty(session_key)) {
            return Results.UNPROCESSABLE_ENTITY;
        }
        try {
//这里
            encryptedData = URLDecoder.decode(encryptedData, "UTF-8");
            String result = WxUtils.wxDecrypt(encryptedData, session_key, iv);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            System.out.println(e.toString());
        }
        return null;
    }
}

后来看到帖子

<think>首先,用户的问题是:“我想了解如何在小程序云开发中实现用户手机号登录功能请问小程序云开发实现用户手机号登录方法教程”。这涉及到微信小程序云开发,特别是使用云函数来获取用户的手机号并实现登录。从系统级指令中,我需要:-所有行内数学表达式用$...$格式(但这里可能不涉及数学表达式,所以可以忽略)。-独立公式用$$...$$格式(同样,可能不适用)。-LaTeX语法正确(如果使用)。-使用中文回答。-生成相关问题。-在回答中引用的段落末尾添加引用标识,如[^1]。-回答结构清晰,帮助用户逐步解决问题。-参考提供的引用内容。提供的引用内容:-[^1]:介绍了小程序云开发的基本概念,包括云数据库、云函数、云存储、云调用。-[^2]:详细描述了如何通过云函数获取用户手机号,包括前端按钮、云函数代码和调用方式。-[^3]:讨论了云开发的扩展功能,如推送消息,但重点是云函数调用。-[^4]:涉及uni-app中使用Authing获取用户手机号,但用户问题直接针对小程序云开发,所以我应该优先参考[^2]。用户的需求是:在小程序云开发中实现用户手机号登录功能。步骤应该包括:1.前端设置:使用小程序按钮组件获取手机号。2.云函数编写:处理手机号获取。3.登录逻辑:使用手机号进行登录或关联用户。核心步骤基于[^2]:-前端:使用`<buttonopen-type="getPhoneNumber"bindgetphonenumber="getPhoneNumber">获取手机号</button>`。-JavaScript:在`getPhoneNumber`事件中调用云函数。-云函数:使用`cloud.getOpenData`解密手机号。我还需要确保回答真实可靠,基于官方文档或可靠来源。微信官方文档支持通过云函数获取手机号。结构清晰的回答:-引言:简要说明小程序云开发实现手机号登录的优势(无需服务器,安全)。-步骤分解:分步解释如何实现。-步骤1:前端页面设置按钮。-步骤2:编写云函数解密手机号。-步骤3:处理登录逻辑(如存储到云数据库)。-代码示例:提供必要的代码片段。-注意事项:比如云函数部署、权限设置等。-结尾:总结并生成相关问题。生成相关问题:-基于用户问题,生成3-5个相关问题,如性能、优化、应用场景。引用标识:-在回答中引用时,在段落末尾添加[^1]、[^2]等。例如,提到云开发基本概念时引用[^1],提到具体实现时引用[^2]。完整回答大纲:1.**引言**:解释小程序云开发实现手机号登录的便利性,引用[^1]。2.**前置条件**:确保云开发环境已初始化。3.**实现步骤**:-步骤1:前端添加获取手机号按钮。-步骤2:绑定事件,调用云函数。-步骤3:云函数解密手机号。-步骤4:使用手机号登录(如创建用户记录)。4.**代码示例**:提供wxml、js和云函数代码。5.**注意事项**:云函数部署、安全考虑。6.**总结**。7.**相关问题**:生成相关问题。相关问题建议:1.如何在小程序云开发中处理用户认证?2.获取手机号的安全性如何保障?3.云开发中如何关联手机号与用户数据?4.是否有其他登录方式集成?5.如何优化手机号登录的用户体验?确保回答使用中文。</think>### 如何在小程序云开发中实现用户手机号登录功能 在小程序云开发中实现用户手机号登录功能,是一种高效且安全的方案。微信官方提供了原生支持,开发者无需搭建后端服务器,通过云函数即可解密获取用户手机号,并完成登录流程。以下是基于微信小程序云开发的详细教程,步骤清晰、代码可靠,参考了官方文档和实践案例[^2]。 --- #### 前置条件 1. **开通云开发环境**:在小程序管理后台开通云开发服务,获取环境ID(如 `env: 'your-env-id'`)。 2. **初始化云开发**:在 `app.js` 中初始化云环境: ```javascript App({ onLaunch() { wx.cloud.init({ env: 'your-env-id', // 替换为你的环境ID traceUser: true, }); } }); ``` 此步骤确保云函数和云数据库可用[^1]。 --- #### 实现步骤(分步详解) **步骤1:前端添加获取手机号按钮** 在小程序页面的 WXML 文件中,添加一个按钮组件,并绑定 `open-type="getPhoneNumber"`。用户点击后触发事件获取加密手机号。 ```html <!-- 示例:pages/login/login.wxml --> <button open-type="getPhoneNumber" bindgetphonenumber="handleGetPhone">获取手机号并登录</button> ``` **步骤2:前端事件处理(JS 逻辑)** 在页面对应的 JS 文件中,定义 `handleGetPhone` 事件处理函数。通过 `wx.cloud.callFunction` 调用云函数解密手机号,并处理登录逻辑。 ```javascript // 示例:pages/login/login.js Page({ handleGetPhone(e) { // 检查用户授权 if (e.detail.errMsg !== 'getPhoneNumber:ok') { wx.showToast({ title: '授权失败', icon: 'none' }); return; } // 调用云函数解密手机号 wx.cloud.callFunction({ name: 'decryptPhone', // 云函数名称 data: { cloudID: e.detail.cloudID // 传递加密数据 } }).then(res => { const phoneNumber = res.result.list[0].data.phoneNumber; // 解密后的手机号 console.log('用户手机号:', phoneNumber); // 登录逻辑:存储手机号到云数据库或关联用户 wx.cloud.database().collection('users').add({ data: { phone: phoneNumber, createTime: new Date() } }).then(() => { wx.showToast({ title: '登录成功' }); // 后续跳转至主页 }).catch(err => { console.error('数据库写入失败', err); }); }).catch(err => { console.error('云函数调用失败', err); }); } }); ``` **步骤3:编写云函数(解密手机号)** 在云函数目录中创建 `decryptPhone` 函数,使用 `cloud.getOpenData` 解密手机号。确保云函数部署到云端(通过 IDE 右键部署)。 ```javascript // 示例:cloudfunctions/decryptPhone/index.js const cloud = require('wx-server-sdk'); cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV // 自动使用当前环境 }); exports.main = async (event) => { try { // 解密手机号 const result = await cloud.getOpenData({ list: [event.cloudID] // 传入加密数据 }); return result; } catch (err) { return { err }; } }; ``` **步骤4:登录逻辑完善** - **用户关联**:在云数据库中创建 `users` 集合,存储手机号作为用户唯一标识。 - **会话管理**:登录成功后,可使用 `wx.setStorageSync` 缓存用户信息。 - **安全考虑**:手机号解密在云函数中完成,避免前端暴露敏感数据[^2]。 --- #### 注意事项 1. **云函数部署**:每次修改云函数后,必须通过小程序 IDE 部署到云端,否则调用失败[^2]。 2. **用户授权**:首次获取手机号需用户主动授权,若拒绝需引导重新授权。 3. **权限配置**:在云控制台设置数据库的读写权限(如 `users` 集合需开启写权限)。 4. **错误处理**:添加 `try-catch` 捕获云函数异常,前端展示友好提示。 5. **性能优化**:云函数执行时间一般小于 100ms,适合高并发场景[^1]。 --- #### 总结 通过以上步骤,你可以在小程序云开发中高效实现手机号登录功能,全程无需服务器运维。该方法基于微信原生能力,安全可靠,适用于电商、社交等需要用户认证的场景[^1][^2]。如有疑问,可参考微信官方文档或社区案例。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值