当前位置: 首页 > news >正文

彩虹表攻击与Nest密码存储

文章目录

  • 前言
    • 🧨 什么是彩虹表攻击?
    • 📷 图中解析
      • 左侧是彩虹表:
      • 右侧是用户数据库中的数据:
    • 🔐 如何防御彩虹表攻击?
      • ✅ 1. **使用 Salt 加密(推荐)**
      • ✅ 2. **使用强哈希函数(如 bcrypt、scrypt、argon2)**
      • ✅ 3. **不要用明文密码或简单哈希算法(如 md5/sha1)**
    • ✅ 总结推荐实践
  • Prisma + bcrypt 加密存储密码 实战示例
    • ✅ 1. Prisma 模型定义
    • ✅ 2. 安装 bcrypt
    • ✅ 3. 注册:加密后存入数据库
    • ✅ 4. 登录:验证密码是否匹配
    • ✅ 5. 测试示例
    • 🔐 安全建议
  • **NestJS + Prisma + bcrypt + JWT 登录授权系统** 实战模板
    • 📦 技术栈
    • ✅ 1. 安装依赖
    • ✅ 2. 用户模型(Prisma)
    • ✅ 3. AuthModule 结构
    • ✅ 4. DTO 文件
    • ✅ 5. JWT 策略(jwt.strategy.ts)
    • ✅ 6. AuthService(auth.service.ts)
    • ✅ 7. AuthController(auth.controller.ts)
    • ✅ 8. AuthModule 配置(auth.module.ts)
    • ✅ 9. 使用 JWT 守卫保护路由(可选)
    • ✅ 10. JWT Guard(jwt-auth.guard.ts)
    • 🧪 示例请求
      • 注册
      • 登录
      • 登录成功后返回


前言

一种常见的密码破解方式:彩虹表攻击(Rainbow Table Attack),我们一步步解释:


🧨 什么是彩虹表攻击?

彩虹表攻击是一种基于预计算哈希值反查密码的攻击方式:

  1. 攻击者先构建一个表格:记录常见密码及其哈希值(如 MD5/SHA1);
  2. 获取某网站数据库中的用户密码哈希值
  3. 在彩虹表中查找匹配的哈希值,反推出原始密码

📷 图中解析

左侧是彩虹表:

明文密码对应哈希值
picture1ab2ca3349e27
hitheree3f49eabe8950
mypassword0b0a91823da1d0
monkeya1d01066dd8036

右侧是用户数据库中的数据:

idemailpassword (hash)
1*a@@a.com0b0a91823da1d0

攻击者对照彩虹表发现这个哈希值对应 mypassword,于是破解成功!


🔐 如何防御彩虹表攻击?

✅ 1. 使用 Salt 加密(推荐)

给每个密码增加一个**随机字符串(Salt)**再进行哈希:

password = "mypassword"
salt = "a1b2c3d4"
hash = SHA256("mypassworda1b2c3d4")

即使两个用户用相同密码,生成的哈希也不同!这样彩虹表根本没法提前计算所有组合。

✅ 2. 使用强哈希函数(如 bcrypt、scrypt、argon2)

这些哈希算法设计为:

  • 计算慢(防止暴力破解)
  • 自带 Salt(内置加盐)
  • 可配置强度(提高成本)

例如使用 bcrypt 存密码:

import bcrypt from 'bcrypt';const saltRounds = 10;
const hash = await bcrypt.hash("mypassword", saltRounds);

验证时用:

await bcrypt.compare("mypassword", hashFromDb); // true or false

✅ 3. 不要用明文密码或简单哈希算法(如 md5/sha1)

这些算法太快太弱,容易被彩虹表破解。


✅ 总结推荐实践

做法是否推荐说明
明文存密码❌ 绝对禁止泄露即全部破防
MD5/SHA1❌ 不推荐无加盐太容易被破解
哈希 + Salt✅ 推荐每个用户不同结果,防彩虹表
bcrypt/scrypt/argon2✅ 推荐更安全的现代密码哈希方法

Prisma + bcrypt 加密存储密码 实战示例

以下是使用 Prisma + bcrypt 实现注册和登录时密码加密与验证的完整示例,适合用在 NestJS、Express、Fastify 等 Node.js 框架中。


✅ 1. Prisma 模型定义

// schema.prisma
model User {id        Int     @id @default(autoincrement())email     String  @uniquepassword  String  // 存加密后的哈希值createdAt DateTime @default(now())
}

✅ 2. 安装 bcrypt

npm install bcrypt
# or
pnpm add bcrypt

✅ 3. 注册:加密后存入数据库

import bcrypt from 'bcrypt';
import { PrismaClient } from '@prisma/client';const prisma = new PrismaClient();
const SALT_ROUNDS = 10;async function register(email: string, plainPassword: string) {const hashedPassword = await bcrypt.hash(plainPassword, SALT_ROUNDS);const user = await prisma.user.create({data: {email,password: hashedPassword,},});console.log('User created:', user);
}

✅ 4. 登录:验证密码是否匹配

async function login(email: string, plainPassword: string) {const user = await prisma.user.findUnique({where: { email },});if (!user) {throw new Error('用户不存在');}const isMatch = await bcrypt.compare(plainPassword, user.password);if (!isMatch) {throw new Error('密码错误');}console.log('登录成功:', user);
}

✅ 5. 测试示例

await register('test@example.com', 'mypassword');
// 存入数据库后为 hashed:$2b$10$... (加密值)await login('test@example.com', 'mypassword'); // ✅ 登录成功
await login('test@example.com', 'wrongpass');  // ❌ 抛出密码错误

🔐 安全建议

项目建议值
SALT_ROUNDS10~12,生产建议 12+
哈希算法bcrypt 是安全主流选择,argon2 更现代但略复杂
防止爆破建议结合 JWT + 登录限速(如 express-rate-limit)

NestJS + Prisma + bcrypt + JWT 登录授权系统 实战模板

按模块拆解讲解,包含注册、登录、密码加密、JWT 签发与验证。


📦 技术栈

  • @nestjs/jwt:签发和验证 Token
  • bcrypt:密码加密
  • @prisma/client:数据库 ORM
  • Passport:认证策略(JWT)

✅ 1. 安装依赖

npm install @nestjs/jwt @nestjs/passport passport passport-jwt bcrypt
npm install -D @types/passport-jwt @types/bcrypt

✅ 2. 用户模型(Prisma)

model User {id       Int    @id @default(autoincrement())email    String @uniquepassword StringcreatedAt DateTime @default(now())
}

✅ 3. AuthModule 结构

src/
├── auth/
│   ├── auth.module.ts
│   ├── auth.service.ts
│   ├── auth.controller.ts
│   ├── jwt.strategy.ts
│   └── dto/
│       ├── login.dto.ts
│       └── register.dto.ts

✅ 4. DTO 文件

// dto/register.dto.ts
export class RegisterDto {email: string;password: string;
}// dto/login.dto.ts
export class LoginDto {email: string;password: string;
}

✅ 5. JWT 策略(jwt.strategy.ts)

import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { ExtractJwt, Strategy } from 'passport-jwt';@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {constructor() {super({jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),secretOrKey: 'secretKey', // 改为读取 .env 中 JWT_SECRET});}async validate(payload: any) {return { userId: payload.sub, email: payload.email };}
}

✅ 6. AuthService(auth.service.ts)

import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import * as bcrypt from 'bcrypt';
import { JwtService } from '@nestjs/jwt';@Injectable()
export class AuthService {constructor(private prisma: PrismaService,private jwtService: JwtService,) {}async register(email: string, password: string) {const hash = await bcrypt.hash(password, 10);return this.prisma.user.create({data: { email, password: hash },});}async validateUser(email: string, password: string) {const user = await this.prisma.user.findUnique({ where: { email } });if (!user) return null;const isMatch = await bcrypt.compare(password, user.password);return isMatch ? user : null;}async login(user: any) {const payload = { sub: user.id, email: user.email };return {access_token: this.jwtService.sign(payload),};}
}

✅ 7. AuthController(auth.controller.ts)

import { Controller, Post, Body, UnauthorizedException } from '@nestjs/common';
import { AuthService } from './auth.service';
import { RegisterDto, LoginDto } from './dto';@Controller('auth')
export class AuthController {constructor(private authService: AuthService) {}@Post('register')register(@Body() dto: RegisterDto) {return this.authService.register(dto.email, dto.password);}@Post('login')async login(@Body() dto: LoginDto) {const user = await this.authService.validateUser(dto.email, dto.password);if (!user) throw new UnauthorizedException('Invalid credentials');return this.authService.login(user);}
}

✅ 8. AuthModule 配置(auth.module.ts)

import { Module } from '@nestjs/common';
import { JwtModule } from '@nestjs/jwt';
import { PassportModule } from '@nestjs/passport';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { JwtStrategy } from './jwt.strategy';
import { PrismaModule } from '../prisma/prisma.module';@Module({imports: [PrismaModule,PassportModule,JwtModule.register({secret: 'secretKey', // 读取自 .envsignOptions: { expiresIn: '1d' },}),],providers: [AuthService, JwtStrategy],controllers: [AuthController],
})
export class AuthModule {}

✅ 9. 使用 JWT 守卫保护路由(可选)

import { UseGuards, Controller, Get } from '@nestjs/common';
import { JwtAuthGuard } from './jwt-auth.guard';@Controller('profile')
export class ProfileController {@UseGuards(JwtAuthGuard)@Get()getProfile(@Request() req) {return req.user;}
}

✅ 10. JWT Guard(jwt-auth.guard.ts)

import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}

🧪 示例请求

注册

POST /auth/register
{"email": "user@example.com","password": "123456"
}

登录

POST /auth/login
{"email": "user@example.com","password": "123456"
}

登录成功后返回

{"access_token": "eyJhbGciOiJIUzI1NiIsInR..."
}

相关文章:

  • 一些基本的 Vue 规范
  • NEUOJ网格路径
  • 变量在template里不好使,在setup好使?
  • 从并发问题衍生出的Spring的七种事务传播行为
  • 问题:raw.githubusercontent无法访问
  • 《解锁快速记忆法:开启高效学习的大门》
  • 消息中间件RabbitMQ02:账号的注册、点对点推送信息
  • 4.23学习总结
  • 如何设计一个实时数据同步方案
  • 抱佛脚之学SSM六
  • 集成电路过流保护:基于 hiccup 模式的设计与解析
  • MVCWebAPI使用FromBody接受对象的方法
  • Windows上使用Python 3.10结合Appium-实现APP自动化
  • Apache Flink 深度解析:流处理引擎的核心原理与生产实践指南
  • 2025.04.23华为机考第一题-100分
  • 数据库1个
  • Vue3速通笔记
  • QT软件安装(12)
  • VBA批量读取access数据库(.mdb)
  • 淘宝平台关键字搜索接口接入指南(含代码示例及商品标题解析)
  • 著名茶叶专家谢丰镐逝世,享年95岁
  • 云南昭通黄吉庆寻子29年终团聚:儿子在同事鼓励下回乡认亲
  • 养胃不是顿顿喝粥,这份“胃的使用说明书”请收好
  • “全国十大考古”揭晓:盘龙城遗址、周原遗址入围
  • 消费补贴政策力度最大的一届!第六届上海“五五购物节” 4月底启幕
  • 泽连斯基提议乌俄“立即、全面和无条件”停火