撞库与加盐

109 阅读4分钟

什么是撞库?

撞库是一种网络攻击手段,攻击者通过收集已泄露的用户名和密码信息,尝试在其他网站或服务上登录,以获取用户的账户权限。由于许多用户在不同网站上使用相同的密码,这使得撞库攻击变得尤为有效。

一些常见的撞库方法

  1. 使用密码字典撞多个账号

    • 攻击者创建一个包含可能密码的列表(密码字典),然后使用这个列表对大量账号进行尝试登录。
    • 如果用户在不同网站上使用相同的密码,攻击者就有可能成功登录。
  2. 使用少数密码尝试撞多个账号

    • 攻击者可能只使用几个常见的密码(如“123456”、“password”等)去尝试登录大量账号。
    • 这种方法依赖于大量用户使用简单或常见密码的事实。
  3. 使用泄露的凭证信息

    • 如果攻击者能够从其他网站或数据泄露事件中获得用户的凭证信息,他们会使用这些凭证在其他网站上尝试登录。
  4. 自动化脚本和工具

    • 攻击者使用自动化脚本和工具来执行撞库攻击,这些工具可以快速地对大量账号进行登录尝试。
  5. 利用API漏洞

    • 如果网站的API存在安全漏洞,攻击者可能会利用这些漏洞来执行撞库攻击,通过API提交登录请求。
  6. 使用代理IP和VPN

    • 为了规避IP被封禁的风险,攻击者可能会使用代理IP或VPN来隐藏自己的真实IP地址。
  7. 利用验证码绕过机制

    • 有些攻击者会尝试绕过或自动化解决验证码,以继续进行撞库攻击。
  8. 利用社工库

    • 社工库是黑客用来记录攻击手段和方法的数据库,其中可能包含大量用户信息,攻击者利用这些信息进行撞库。
  9. 彩虹表和时间-记忆-数据权衡攻击

    • 彩虹表是一种预先计算好的密码哈希值表,可以快速匹配密码哈希,而时间-记忆-数据权衡攻击则是在彩虹表的基础上进一步优化存储和查询效率。

应对撞库的加盐方法

为了应对撞库攻击,我们可以采用"加盐"(Salting)的方法。加盐是一种密码存储技术,通过在密码上添加随机数据,使得即使两个用户使用相同的密码,存储的密码哈希值也不同。

加盐的步骤

  1. 生成盐:为每个用户生成一个唯一的随机盐值。
  2. 密码与盐的组合:将用户的密码与盐值进行组合。
  3. 哈希处理:对组合后的字符串进行哈希处理,生成密码哈希值。
  4. 存储:将盐值和哈希值一起存储在数据库中。

Python实现加盐

来,给个登录程序,展示如何实现加盐过程(其中还使用getpass来隐藏密码):

import os
import hashlib
import getpass

# 全局变量,存储盐值
SALT = os.urandom(16)  # 生成一个16字节的随机盐值

def hash_password(password, salt):
    """使用盐值对密码进行哈希处理"""
    password_salt = password.encode('utf-8') + salt
    hash_obj = hashlib.sha256(password_salt)
    hashed_password = hash_obj.hexdigest()
    return hashed_password, salt

def save_user_data(username, hashed_password, salt):
    """将用户名、哈希密码和盐值保存到文件"""
    with open('user_data.txt', 'a') as file:
        file.write(f"{username},{hashed_password},{salt.hex()}\n")

def register():
    """注册用户功能"""
    username = input("请输入用户名: ")
    password = getpass.getpass("请输入密码: ")  # 使用getpass隐藏密码输入
    hashed_password, salt = hash_password(password, SALT)
    save_user_data(username, hashed_password, salt)
    print("注册成功!")

def login():
    """用户登录验证功能"""
    username = input("请输入用户名: ")
    password = getpass.getpass("请输入密码: ")
    user_found = False
    try:
        with open('user_data.txt', 'r') as file:
            for line in file:
                stored_username, stored_hash, stored_salt = line.strip().split(',')
                if stored_username == username:
                    hashed_password, _ = hash_password(password, bytes.fromhex(stored_salt))
                    if hashed_password == stored_hash:
                        print("登录成功")
                        user_found = True
                        break
    except FileNotFoundError:
        print("用户数据文件不存在")
    if not user_found:
        print("用户名或密码错误")

def main():
    """主函数,提供用户选择注册或登录"""
    while True:
        print("\n请选择操作:")
        print("1. 注册")
        print("2. 登录")
        print("3. 退出")
        choice = input("请输入选项(1-3): ")

        if choice == '1':
            register()
        elif choice == '2':
            login()
        elif choice == '3':
            print("退出程序。")
            break
        else:
            print("无效的输入,请重新选择。")

if __name__ == "__main__":
    main()