使用python hashlib模块给明文字符串加密,以及如何撞库破解密码

本文涉及的产品
视觉智能开放平台,视频资源包5000点
视觉智能开放平台,图像资源包5000点
视觉智能开放平台,分割抠图1万点
简介: `hashlib` 是 Python 中用于实现哈希功能的模块,它可以将任意长度的输入通过哈希算法转换为固定长度的输出,即散列值。该模块主要用于字符串加密,例如将用户名和密码转换为不可逆的散列值存储,从而提高安全性。`hashlib` 提供了多种哈希算法,如 `md5`、`sha1`、`sha256` 等。

1 hashlib介绍

1、Hash,译做“散列”,也有直接音译为“哈希”的。把任意长度的输入,通过某种hash算法,变换成固定长度的输出,该输出就是散列值,也称摘要值。该算法就是哈希函数,也称摘要函数

2、hash函数的主要目的就是对字符串进行加密,比如:我们注册的用户名和密码,都是明文(就是我们自己能看的明白的)需要先通过hash进行加密,然后生成一串固定长度的字符串(这样连我们自己也看不出来了),存入到数据库中,我们再下次登录的时候只需要到数据中比对对应的hash值即可,这样即使数据中的hash值数据泄露了,被人拿到也是不知道我们的用户名和密码的,因此hash值有这样的特性:

  • 同样的字符串,每次生成的hash值也是一样的
  • hash值是不可反解的,即我们知道了hash值也是不可能反解出其对应的明文的!

2 hashlib模块使用

下面使用的hexdigest(): 表示,生成的哈希值的数字签名,hex表示是十六进制digest表示生成hash的数字签名

2.1 查看hashlib中有哪些hash算法

在hashlib模块中,sha1()、sha224()、sha256()、sha384()、sha512()和blake2b()、blake2s()方法总是存在的。md5安全安全性并不是很高!

1、查看hashlib下支持的hash算法有哪些

hashlib.algorithms_available:返回hash算法名的集合

注意:相同的hash函数算法可能出现不同的名字(大小写)而多次出现

>>> import hashlib

>>> alg_set1 = hashlib.algorithms_available
>>> alg_set1
{
   'md4', 'sha3_512', 'sha512_224', 'ripemd160', 'sha512', 'md5-sha1', 'sha3_224', 'blake2s', 'md5', 'sha256', 'blake2b', 'mdc2', 'sha384', 'sha1', 'shake_128', 'sha512_256', 'sha3_384', 'sm3', 'sha224', 'shake_256', 'whirlpool', 'sha3_256'}
>>> len(alg_set1)
22

>>> alg_set2 = hashlib.algorithms_guaranteed
>>> alg_set2
{
   'sha3_512', 'sha3_224', 'blake2s', 'md5', 'shake_128', 'sha256', 'sha224', 'sha384', 'sha1', 'shake_256', 'sha512', 'sha3_256', 'blake2b', 'sha3_384'}
>>> len(alg_set2)
14

>>> alg_12 = alg_set1 & alg_set2
>>> alg_12
{
   'sha3_512', 'sha3_224', 'blake2s', 'md5', 'sha256', 'sha224', 'sha384', 'sha1', 'shake_256', 'sha512', 'shake_128', 'blake2b', 'sha3_384', 'sha3_256'}
>>> len(alg_12)
14

hashlib.algorithms_guaranteed:返回hash算法名的集合,返回的集合是hashlib.algorithms_available返回集合的子集!

2.2 对字符串进行加密

1、对字符串使用md5进行加密

注意需要先对加密的字符串进行编码转换,否则会报错:TypeError: Unicode-objects must be encoded before hashing,如下,三种转换写法都可以:

  • md5.update('hello'.encode('utf-8'))
  • md5.update(b'hello')
  • md5.update(bytes('hello', encoding='utf-8')) # 使用bytes转换为二进制
import hashlib


def str_encryption_md5():
    password_str = 'Tom888'
    md5 = hashlib.md5()
    # md5.update(password_str)  # TypeError: Unicode-objects must be encoded before hashing

    md5.update(password_str.encode('utf-8'))  # 注意转码
    # md5.update(bytes(password_str, encoding='utf-8'))
    # md5.update(b'Tom888')

    print(md5.digest_size)  # 16  # 生成hash结果大小,单位字节
    print(md5.block_size)  # 64  # hash算法的内部快大小,单位字节

    res = md5.hexdigest()
    # 字符串 Tom888(明文)被加密成一串 32位长的字符串
    print('md5加密结果:', res, len(res))  # md5加密结果: 5a2b7072fbe5c1216be444fe30d965e8 32


if __name__ == '__main__':
    str_encryption_md5()

2、对字符串使用sha1进行加密

import hashlib

def str_encryption_sha1():
    password_str = 'Tom888'
    sha1 = hashlib.md5()
    sha1.update(password_str.encode('utf-8'))  # 注意转码

    print(md5.digest_size)  # 16  # 生成hash结果大小,单位字节
    print(md5.block_size)  # 64  # hash算法的内部快大小,单位字节

    res = sha1.hexdigest()
    # 字符串 Tom888(明文)被加密成一串 32位长的字符串
    print('sha1加密结果:', res, len(res))  # sha1加密结果: 5a2b7072fbe5c1216be444fe30d965e8 32


if __name__ == '__main__':
    str_encryption_sha1()

3、其他更多加密算法测试

  • 可以看出,不同的加密算法,生成的字符串的长度可能不一样!
import hashlib

def str_encryption_all_alg():
    password_str = 'Tom888'
    all_hash_algorithms = {
   'sha3_512': hashlib.sha3_512,
                           'sha3_224': hashlib.sha3_224, 
                           'blake2s': hashlib.blake2s, 
                           'md5': hashlib.md5, 
                           'shake_128': hashlib.shake_128, 
                           'sha256': hashlib.sha256, 
                           'sha224': hashlib.sha224, 
                           'sha384': hashlib.sha384, 
                           'sha1': hashlib.sha1, 
                           'shake_256': hashlib.shake_256, 
                           'sha512': hashlib.sha512, 
                           'sha3_256': hashlib.sha3_256, 
                           'blake2b': hashlib.blake2b, 
                           'sha3_384': hashlib.sha3_384}

    for hash_alg in all_hash_algorithms.keys():
        print(f'Start hash algorithm: {hash_alg}')
        alg = all_hash_algorithms[hash_alg]()
        alg.update(password_str.encode('utf-8'))
        try:
            res = alg.hexdigest()
            print(f'{hash_alg}加密结果:', len(res), res)
        except TypeError as e:
            pass

    '''
    Start hash algorithm: sha3_512
    sha3_512加密结果: 128 0a4ce5b6e85b206d220b1c25059070e171c7635d2357bb7fe7ac65fcb054cecb1f6bbceda7bd70701ef48a24a4c25e5ac45cecb4e169efb24f8d72d302926bbf
    Start hash algorithm: sha3_224
    sha3_224加密结果: 56 9b13e0708c8577ce37bb8fefa714a38a3e0e57286b501ee3db813e71
    Start hash algorithm: blake2s
    blake2s加密结果: 64 e572b36c0f9c61878fb296883a29df73e567df275d33c6f7a7b78b9950a9798b
    Start hash algorithm: md5
    md5加密结果: 32 5a2b7072fbe5c1216be444fe30d965e8
    Start hash algorithm: shake_128
    Start hash algorithm: sha256
    sha256加密结果: 64 04d016992b2c6d1163861542705bf725d951e83afc5360cc3c97510e2ccc070b
    Start hash algorithm: sha224
    sha224加密结果: 56 3be1b04e03d47a39a14955fd6628d3ebc29cc3e638224254607a4458
    Start hash algorithm: sha384
    sha384加密结果: 96 37940a0bac0de66d5ce44fbde401d5ff6639ab0f24b9a3b80400be5a369df663454b4e2cc224d6e2958bc3d34955b7a5
    Start hash algorithm: sha1
    sha1加密结果: 40 54f3d519f107922e616a336118a1e8e89ec9d25e
    Start hash algorithm: shake_256
    Start hash algorithm: sha512
    sha512加密结果: 128 0806221d502cd98bc9e592668371bcc8a4dc125af262c1aeaf2676bb9ec32776ea8e54cf6a42a76e78b9170d069cb3a5d05e002378a86044a1e9343b644135de       
    Start hash algorithm: sha3_256
    sha3_256加密结果: 64 714c04befcc26385f0ad39bad838af74a7d8a2376e46d11a7f9e20b889ce4bba
    Start hash algorithm: blake2b
    blake2b加密结果: 128 a0daffc1dd95b7d44bb5883053abcee11ab1f25efe61f098f4fe70ae30330b197ccb1bef0c110cb4ba09637a684f9f1538f24b1483a9213f4c3ac7a2b8886df6      
    Start hash algorithm: sha3_384
    sha3_384加密结果: 96 5aad1c17d3e9b1020436a2070bab048f4857e258034eafebac4fe0ea7647eba62d07dc5c58b9e651284ea47c83cfca0c
    '''


if __name__ == '__main__':
    str_encryption_all_alg()

2.3 对于数据比较大,加密可以分块,结果一样

如果数据量很大,可以分块多次调用update(),最后计算的结果是一样的:

如下,把一个长字符串分开进行hash,最终得到的hash值的结果是一样的!

import hashlib

def str_encryption_sha256():
    sha256 = hashlib.sha256()
    sha256.update('how to use sha256 in python hashlib?'.encode('utf-8'))
    print(sha256.hexdigest())  # de6cdf7a7e6a68182ce0dba30671e7d81df8208866c8160a77dfc61f9ef89706


    sha256_2 = hashlib.sha256()
    sha256_2.update('how to use sha256 in '.encode('utf-8'))
    sha256_2.update('python hashlib?'.encode('utf-8'))
    print(sha256_2.hexdigest()) # de6cdf7a7e6a68182ce0dba30671e7d81df8208866c8160a77dfc61f9ef89706


if __name__ == '__main__':
    str_encryption_sha256()

2.4 hashlib的高级用法

高级用法,就是为了防止撞库反解。所以,有必要对加密算法中添加自定义key再来做加密。

  • 就是在hashlib.md5(b'key') 其实就是把自己要加密的字符串和这个key拼接在一起,然后再生成一个加密后的字符串
  • 从下面加密的结果可以证实!
def str_encryption_self():
    # 普通加埋
    md5 = hashlib.md5()
    md5.update('alex88888'.encode('utf-8'))
    res = md5.hexdigest()
    print('普通加密结果:', res)  # 普通加密结果: 8c26a75d12ea2a730654679d2061b953

    # 高级加密:自己定义一个key参数
    md5 = hashlib.md5(b'super_encryption')
    md5.update('alex88888'.encode('utf-8'))
    res = md5.hexdigest()
    print('高级加密结果:', res)  # 高级加密结果: 5649795aaa6aaf64deaab659b0a0c63f


    md5 = hashlib.md5()
    md5.update('super_encryption'.encode('utf-8'))
    md5.update('alex88888'.encode('utf-8'))
    res = md5.hexdigest()
    print('加密结果:', res)  # 加密结果: 5649795aaa6aaf64deaab659b0a0c63f

if __name__ == '__main__':
    str_encryption_self()

2.5 校验文件的一致性

1、校验文件的一致性(如何保证下载的文件过程中不丢包,保证下载数据的完整性)(参考

# -----------文件一致校验----------------

'''可以拷贝一个文件放在两个不同的盘中,然后通过判断两个文件的hash值是否相等,判断两个文件是否是同一个文件'''
import hashlib
m = hashlib.md5()
with open(r'G:/logging模块配图.png','rb') as f:
    for line in f:
        m.update(line)
print(m.hexdigest())          #47a6b079cc33a4f312786b46e61e0305


import hashlib

m = hashlib.md5()
with open(r'H:/logging模块配图.png','rb') as f:
    for line in f:
        m.update(line)

print(m.hexdigest())

3 hmac模块的加密方式,于hashlib类似

python 还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密

import hmac

def str_encryption_hmac():
    # key值就是加的salt
    h = hmac.new(key='天王盖地虎'.encode('utf8'), digestmod='md5')  # new里面的参数key就是salt
    h.update('alex88888'.encode('utf-8'))
    print(h.hexdigest())  # 3414e379c15069a81b1e8ca0012fc59d


if __name__ == '__main__':
    str_encryption_hmac()

4 破解用户密码

我们说即使拿到hash的值,就是一串固定的长度的字符串,我们是不能够反解出其对应的明文的,但有没有方法能够获取都明文呢,当前有的,那就是撞库,撞库的原理:

  • 先生成很多常用的字符串
  • 然后根据hash算法,生成这些字符串对应的hash值
  • 构建一个{hash值:字符串,...}的字典(/数据库)
  • 然后就可以去库中找是否有对应的hash值,这样就可以取出对应的明文了!
import hashlib

def break_passward(in_hash_value):
    passwds=[                      #可以通过random实现对passwds中的内容
    'alex3714',
    'alex1313',
    'alex94139413',
    'alex123456',
    '123456alex',
    'a123lex',
    ]

    hash_passwd_dict = {
   }
    for passwd in passwds:
        md5 = hashlib.md5()
        md5.update(passwd.encode('utf-8'))
        hash_passwd_dict[md5.hexdigest()] = passwd

    print(hash_passwd_dict)
    '''
    {'aee949757a2e698417463d47acac93df': 'alex3714', 
     '5dd873761a1ac42d2afbca152ec1e772': 'alex1313', 
     '5e3c46d350ac2780222040b0ed62aa7c': 'alex94139413', 
     '94e4ccf5e2749b0bfe0428603738c0f9': 'alex123456', 
     'd5a3f30371e61ecfb519acfd5f709630': '123456alex', 
     '601b259d02dac6d75686a0b08a00b755': 'a123lex'}
    '''

    if in_hash_value in hash_passwd_dict.keys():
        decode_value = hash_passwd_dict[in_hash_value]
        print('撞库成功')
        print('哈希值:{} 对应明文是:{}'.format(in_hash_value, decode_value))
    else:
        print('撞库失败!')


if __name__ == '__main__':
    break_passward('601b259d02dac6d75686a0b08a00b755')
    # 撞库成功
    # 哈希值:601b259d02dac6d75686a0b08a00b755 对应明文是:a123lex

    break_passward('601b259d02dac6d75686a0b08a00b777')
    # 撞库失败!
目录
相关文章
|
1天前
|
Python
SciPy 教程 之 SciPy 模块列表 6
SciPy教程之常量模块介绍:涵盖公制、二进制(字节)、质量、角度、时间、长度、压强、体积、速度、温度、能量、功率及力学单位。示例展示了角度单位转换为弧度的几个常用常量。
11 7
|
1天前
|
Python
SciPy 教程 之 SciPy 模块列表 7
`scipy.constants` 模块提供了常用的时间单位转换为秒数的功能。例如,`constants.hour` 返回 3600.0 秒,表示一小时的秒数。其他常用时间单位包括分钟、天、周、年和儒略年。
10 6
|
2天前
|
知识图谱 Python
SciPy 教程 之 SciPy 模块列表 5
本教程介绍SciPy常量模块中的单位类型,涵盖公制、质量、时间、长度等单位。示例代码展示了如何使用`scipy.constants`模块获取不同质量单位的千克值,如公吨、磅、盎司、原子质量单位等。
8 1
|
2天前
|
知识图谱 Python
SciPy 教程 之 SciPy 模块列表 5
SciPy常量模块提供了多种单位的转换,包括公制、质量、时间、长度等单位。例如,质量单位中,`constants.gram`返回0.001千克,`constants.lb`返回0.45359237千克,涵盖了从日常到科学计算所需的广泛单位。
5 0
|
2天前
|
Python
SciPy 教程 之 SciPy 模块列表 4
SciPy 常量模块包含了多种单位类型,包括公制单位、质量单位、角度换算、时间单位、长度单位、压强单位、体积单位、速度单位、温度单位、能量单位、功率单位和力学单位。此外,还提供了二进制前缀单位,如 kibi(1024 字节)、mebi(1048576 字节)等。
5 0
|
14天前
|
SQL 安全 算法
网络安全的盾牌与剑:深入理解网络漏洞、加密技术及安全意识
【10月更文挑战第7天】在数字化时代的浪潮中,网络安全成了保护个人隐私和企业资产的关键防线。本文旨在揭示网络安全的重要性,并从网络漏洞识别、加密技术的运用到培养良好的安全意识等方面提供深入浅出的知识分享。通过实例分析,我们将探索如何有效地防范网络攻击,保护信息安全。
|
12天前
|
存储 安全 5G
|
1天前
|
存储 安全 网络安全
网络安全的屏障与钥匙:漏洞防御与加密技术深度解析
【10月更文挑战第20天】在数字世界的迷宫中,网络安全是守护我们数据宝藏的坚固盾牌和锋利钥匙。本篇文章将带您穿梭于网络的缝隙之间,揭示那些潜藏的脆弱点—网络安全漏洞,同时探索如何通过现代加密技术加固我们的数字堡垒。从基本概念到实战策略,我们将一同揭开网络安全的神秘面纱,提升您的安全意识,保护个人信息不受侵犯。
33 25
|
1天前
|
SQL 存储 安全
网络安全与信息安全的现代挑战:漏洞、加密与意识
【10月更文挑战第20天】在数字时代的浪潮下,网络安全和信息安全的重要性日益凸显。本文旨在探讨当前网络安全面临的主要挑战,包括安全漏洞的发现与利用、加密技术的应用与局限,以及提升个人和组织的安全意识的必要性。通过分析这些关键领域,我们不仅能更好地理解网络威胁的本质,还能采取有效措施保护我们的数字资产。文章将提供对网络安全现状的深刻见解,并指出未来研究的方向。
|
15天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【10月更文挑战第6天】在数字化时代,网络安全和信息安全已成为我们生活中不可或缺的一部分。本文将探讨网络安全漏洞、加密技术和安全意识等方面的内容,以帮助读者更好地了解这些主题,并采取适当的措施保护自己的信息安全。我们将通过代码示例来演示一些常见的安全漏洞,并提供解决方案。最后,我们将强调培养良好的安全意识对于维护个人和组织的信息安全的重要性。