You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Crypto-JS解密密码结果异常的登录验证问题求助

问题描述

在TypeScript环境下实现用户注册登录功能,使用Crypto-JS加密密码存入MongoDB,注册流程正常,加密后的密码与MongoDB中存储的一致,但登录时始终返回"wrong password"错误。打印日志发现:

  • inputPassword显示正确的输入密码
  • originalPassword仅包含原密码中的数字,顺序混乱且长度翻倍

已尝试搜索相关问题、清理缓存,均未解决。以下是auth.ts代码:

import { Router, Request, Response } from "express";
const authRouter = Router();
const CryptoJS = require('crypto-js');
import * as jwt from 'jsonwebtoken';
import User from "../models/user";

// 注册
authRouter.post('/register', async (request:Request, response:Response)=>{
    const newUser = new User({
        vorname:request.body.vorname,
        nachname:request.body.nachname,
        email:request.body.email,
        username:request.body.username,
        street:request.body.street,
        number:request.body.number,
        plz:request.body.plz,
        city:request.body.city,
        password: CryptoJS.AES.encrypt(
            request.body.password,
            process.env.PASS_SEC
        ).toString(),
    });
    try{
        const savedUser = await newUser.save();
        response.status(200).json(savedUser);
    } catch(error){
        response.status(403)
        throw new Error('Action failed');
    }
});

// 登录
authRouter.post('/login', async (request:Request, response:Response)=>{
    let sec:string = process.env.JWT_SEC as string;
    try{
        const user = await User.findOne({username:request.body.username});

        if(!user){
            return response.status(401).json("Wrong credentials");
        }
        const hashedPassword = CryptoJS.AES.decrypt(user?.password, process.env.PASS_SEC);
        console.log(hashedPassword);
        const originalPassword = hashedPassword.toString(CryptoJS.enc.UTF8);
        console.log(originalPassword);
        const inputPassword = request.body.password;
        console.log(inputPassword);
        if(originalPassword != inputPassword){
            return response.status(401).json("Wrong password");
        } else {
        const accessToken = jwt.sign(
            {id: user!._id,
             isAdmin:user!.isAdmin,
            },
            sec,
            {expiresIn:"30d"}
        )
        const {password, ...others} = user?._doc;
        response.status(200).json({...others, accessToken});
        }
    } catch(error:any){
        response.status(401)
        throw new Error(error)
    }
});

export default authRouter; 
解决方案

1. 修正CryptoJS导入方式

TypeScript环境下建议使用ES模块导入替代CommonJS的require,避免类型不兼容导致的加密解密逻辑异常:

// 替换原require语句
import CryptoJS from 'crypto-js';

2. 验证环境变量密钥的一致性与有效性

  • 在注册和登录逻辑中添加日志,确认process.env.PASS_SEC的取值完全一致:
    // 注册时添加
    console.log('Register PASS_SEC:', process.env.PASS_SEC);
    // 登录时添加
    console.log('Login PASS_SEC:', process.env.PASS_SEC);
    
  • AES加密要求密钥长度为128/192/256位(对应16/24/32个ASCII字符),若密钥长度不符合要求,CryptoJS会自动调整但可能引发解密错误,建议设置符合规范的密钥。

3. 增加解密有效性校验

解密失败时,toString(CryptoJS.enc.UTF8)会返回空字符串或乱码,可在代码中添加判断提前拦截:

const originalPassword = hashedPassword.toString(CryptoJS.enc.UTF8);
// 新增解密失败判断
if (!originalPassword) {
    return response.status(401).json("Password decryption failed");
}

4. 确认MongoDB字段类型

检查User模型中password字段的类型是否为String,避免因类型不匹配导致存储/读取时的字符串损坏:

// user.ts 模型示例
import mongoose from "mongoose";

const UserSchema = new mongoose.Schema({
    vorname: String,
    nachname: String,
    email: String,
    username: String,
    street: String,
    number: String,
    plz: String,
    city: String,
    password: {
        type: String,
        required: true
    },
    isAdmin: {
        type: Boolean,
        default: false
    }
});

export default mongoose.model("User", UserSchema);

内容的提问来源于stack exchange,提问作者Roman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:15:21