SHA 系列算法教程

1. SHA 算法简介

SHA(Secure Hash Algorithm)是一组密码学哈希函数,由美国国家安全局(NSA)设计,美国国家标准与技术研究院(NIST)发布。

2. 主要 SHA 算法对比

算法输出长度安全性应用场景
SHA-1160位已破解不推荐使用
SHA-224224位安全一般用途
SHA-256256位安全最常用
SHA-384384位安全高安全性
SHA-512512位安全极高安全性
SHA3-256256位安全新一代算法

3. Python 中使用 SHA 算法

基本用法

import hashlib

# 创建哈希对象
hash_object = hashlib.sha256()

# 更新数据(可以分多次)
hash_object.update(b"Hello")
hash_object.update(b" World")

# 获取哈希值
hex_digest = hash_object.hexdigest()
print(hex_digest)

所有 SHA 算法示例

import hashlib

def demo_all_sha_algorithms():
    data = b"Hello World"
    
    print("=== SHA 算法演示 ===")
    print(f"原始数据: {data.decode()}")
    print()
    
    # SHA-1 (不推荐使用)
    sha1 = hashlib.sha1(data).hexdigest()
    print(f"SHA-1:    {sha1}")
    
    # SHA-2 系列
    sha224 = hashlib.sha224(data).hexdigest()
    print(f"SHA-224:  {sha224}")
    
    sha256 = hashlib.sha256(data).hexdigest()
    print(f"SHA-256:  {sha256}")
    
    sha384 = hashlib.sha384(data).hexdigest()
    print(f"SHA-384:  {sha384}")
    
    sha512 = hashlib.sha512(data).hexdigest()
    print(f"SHA-512:  {sha512}")
    
    # SHA-3 系列 (需要Python 3.6+)
    if hasattr(hashlib, 'sha3_256'):
        sha3_256 = hashlib.sha3_256(data).hexdigest()
        print(f"SHA3-256: {sha3_256}")
        
        sha3_512 = hashlib.sha3_512(data).hexdigest()
        print(f"SHA3-512: {sha3_512}")

demo_all_sha_algorithms()

4. 文件哈希计算

import hashlib

def calculate_file_hash(filename, algorithm='sha256'):
    """计算文件的哈希值"""
    hash_func = getattr(hashlib, algorithm)()
    
    try:
        with open(filename, 'rb') as f:
            # 分块读取大文件,避免内存不足
            for chunk in iter(lambda: f.read(4096), b""):
                hash_func.update(chunk)
        return hash_func.hexdigest()
    except FileNotFoundError:
        return None

# 使用示例
file_hash = calculate_file_hash('example.txt', 'sha256')
print(f"文件哈希: {file_hash}")

5. 密码验证系统

import hashlib
import os

class PasswordManager:
    def __init__(self):
        self.salt_length = 16
    
    def generate_salt(self):
        """生成随机盐值"""
        return os.urandom(self.salt_length)
    
    def hash_password(self, password, salt=None):
        """哈希密码(加盐)"""
        if salt is None:
            salt = self.generate_salt()
        
        # 密码 + 盐值
        salted_password = password.encode() + salt
        # 多次哈希增加安全性
        hashed = hashlib.sha256(salted_password).digest()
        hashed = hashlib.sha256(hashed + salted_password).hexdigest()
        
        return hashed, salt
    
    def verify_password(self, password, stored_hash, salt):
        """验证密码"""
        test_hash, _ = self.hash_password(password, salt)
        return test_hash == stored_hash

# 使用示例
pm = PasswordManager()

# 注册用户
password = "mysecret123"
hashed_password, salt = pm.hash_password(password)
print(f"哈希密码: {hashed_password}")
print(f"盐值: {salt.hex()}")

# 验证密码
is_valid = pm.verify_password("mysecret123", hashed_password, salt)
print(f"密码验证: {is_valid}")

is_valid_wrong = pm.verify_password("wrongpass", hashed_password, salt)
print(f"错误密码验证: {is_valid_wrong}")

6. 批量文件完整性检查

import hashlib
import json
from pathlib import Path


class FileIntegrityChecker:
    def __init__(self):
        self.checksums = {}

    def create_checksum_file(self, directory, output_file='checksums.json'):
        """创建文件的校验和记录"""
        directory = Path(directory)

        for file_path in directory.rglob('*'):
            if file_path.is_file():
                file_hash = self.calculate_file_hash(file_path)
                relative_path = str(file_path.relative_to(directory))
                self.checksums[relative_path] = file_hash

        with open(output_file, 'w') as f:
            json.dump(self.checksums, f, indent=2)

        print(f"已生成 {len(self.checksums)} 个文件的校验和")

    def verify_integrity(self, directory, checksum_file='checksums.json'):
        """验证文件完整性"""
        with open(checksum_file, 'r') as f:
            original_checksums = json.load(f)

        changes = {'modified': [], 'added': [], 'deleted': []}
        directory = Path(directory)

        # 检查现有文件
        for relative_path, original_hash in original_checksums.items():
            file_path = directory / relative_path

            if not file_path.exists():
                changes['deleted'].append(relative_path)
            else:
                current_hash = self.calculate_file_hash(file_path)
                if current_hash != original_hash:
                    changes['modified'].append(relative_path)

        # 检查新增文件
        current_files = {str(p.relative_to(directory)) for p in directory.rglob('*') if p.is_file()}
        original_files = set(original_checksums.keys())
        changes['added'] = list(current_files - original_files)

        return changes

    def calculate_file_hash(self, file_path, algorithm='sha256'):
        """计算文件哈希"""
        hash_func = getattr(hashlib, algorithm)()
        with open(file_path, 'rb') as f:
            for chunk in iter(lambda: f.read(4096), b""):
                hash_func.update(chunk)
        return hash_func.hexdigest()


# 使用示例
checker = FileIntegrityChecker()

# 创建校验和
checker.create_checksum_file('./my_folder')

# 验证完整性(稍后运行)
changes = checker.verify_integrity('./my_folder')
print("文件变化:", changes)

7. 性能测试比较

import hashlib
import time
import string
import random


def performance_test():
    """测试不同SHA算法的性能"""
    # 生成测试数据
    test_data = ''.join(random.choices(string.ascii_letters + string.digits, k=1024 * 1024))  # 1MB
    test_data = test_data.encode()

    algorithms = ['sha1', 'sha224', 'sha256', 'sha384', 'sha512']
    if hasattr(hashlib, 'sha3_256'):
        algorithms.extend(['sha3_256', 'sha3_512'])

    results = {}

    for algo in algorithms:
        start_time = time.time()

        # 运行100次取平均
        for _ in range(100):
            getattr(hashlib, algo)(test_data).hexdigest()

        end_time = time.time()
        avg_time = (end_time - start_time) / 100
        results[algo] = avg_time

        print(f"{algo.upper():<8}: {avg_time:.6f} 秒/次")

    return results


# 运行性能测试
performance_test()

8.密码学基础案例 密码 "123456"

# 根据密码123456 推算出来哈希值(SHA-256是单向加密哈希函数)
import hashlib
# hashlib.sha256(b"123456").hexdigest()
hash_result = hashlib.sha256(b"123456").hexdigest()
print(hash_result)
# 输出 '8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92'

9.密码破解方法


# 方法1:已知常见密码尝试
import hashlib


def crack_hash(target_hash):
    # 常见密码列表
    common_passwords = [
        "123456", "password", "123456789", "12345678", "12345",
        "1234567", "1234567890", "qwerty", "abc123", "111111",
        "123123", "admin", "letmein", "welcome", "monkey"
    ]

    for password in common_passwords:
        # 计算哈希值
        hashed = hashlib.sha256(password.encode()).hexdigest()

        if hashed == target_hash:
            print(f"找到密码: {password}")
            return password

    print("未找到匹配的密码")
    return None


# 要破解的哈希值
target_hash = "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92"

# 尝试破解
crack_hash(target_hash)
-----------------------------------------------------------------------------------------
# 方法2:数字组合暴力破解
import hashlib
import itertools


def brute_force_numeric(target_hash, max_length=6):
    """尝试所有数字组合"""
    digits = "0123456789"

    for length in range(1, max_length + 1):
        print(f"正在尝试 {length} 位数字组合...")

        for combination in itertools.product(digits, repeat=length):
            password = ''.join(combination)
            hashed = hashlib.sha256(password.encode()).hexdigest()

            if hashed == target_hash:
                print(f"找到密码: {password}")
                return password

    print("未找到匹配的密码")
    return None


target_hash = "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92"
brute_force_numeric(target_hash)
-----------------------------------------------------------------------------------------
# 方法3:使用彩虹表(预先计算的哈希表)
import hashlib

# 简单的预计算彩虹表
rainbow_table = {
    "123456": "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92",
    "password": "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8",
    "123456789": "15e2b0d3c33891ebb0f1ef609ec419420c20e320ce94c65fbc8c3312448eb225",
    # 可以添加更多预计算的哈希值
}


def crack_with_rainbow_table(target_hash, table):
    for password, hashed in table.items():
        if hashed == target_hash:
            print(f"从彩虹表中找到密码: {password}")
            return password

    print("彩虹表中未找到匹配的密码")
    return None


target_hash = "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92"
crack_with_rainbow_table(target_hash, rainbow_table)
-----------------------------------------------------------------------------------------
# 方法4:完整的密码破解工具
import hashlib
import itertools
import string
import time


class PasswordCracker:
    def __init__(self):
        self.found = False
        self.password = None

    def crack(self, target_hash, charset=None, max_length=8):
        """主破解函数"""
        if charset is None:
            charset = string.digits  # 默认只尝试数字

        start_time = time.time()

        for length in range(1, max_length + 1):
            print(f"尝试长度: {length} 字符")

            for combination in itertools.product(charset, repeat=length):
                test_pass = ''.join(combination)
                hashed = hashlib.sha256(test_pass.encode()).hexdigest()

                if hashed == target_hash:
                    end_time = time.time()
                    print(f"成功! 密码: {test_pass}")
                    print(f"耗时: {end_time - start_time:.2f} 秒")
                    self.found = True
                    self.password = test_pass
                    return test_pass

        print("破解失败")
        return None


# 使用示例
cracker = PasswordCracker()
target_hash = "8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92"

# 只尝试数字(因为知道密码是纯数字)
result = cracker.crack(target_hash, charset="0123456789", max_length=6)

10. 安全建议

  1. 不要使用 SHA-1:已被证明不安全

  2. 推荐使用 SHA-256:平衡安全性和性能

  3. 密码存储必须加盐:防止彩虹表攻击

  4. 考虑使用专门密码哈希函数:如 bcrypt、Argon2

  5. 定期更新算法:跟上密码学发展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

GHY@CloudGuardian

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值