标准库笔记 - 加密:hmac

标准库笔记 - 加密:hmac

hmac 密码消息签名与验证

消息签名(默认是md5)

import hmac

h = hmac.new(b'a-key')
with open('test.txt', 'rb') as fr:
    while True:
        block = fr.read(1024)
        if not block:
            break
        h.update(block)
    
digest = h.hexdigest()
print(digest)

输出: 00541c98e881f71cf431c304bb19719d
text.txt的内容只有一行: hello world.。实际上,如果内容短小,可以这样:

h2 = hmac.new(b'a-key', b'hello world.\n')
print(h2.hexdigest())

输出是一样的: 00541c98e881f71cf431c304bb19719d

SHA1

人们说,SHA1算法更健壮,比MD5好。我不知道,总之用SHA1就是。

h3 = hmac.new(b'a-key', b'hello world.\n', 'sha1')
print(h3.hexdigest())

输出是长一些: 85207b857b8a731d9640b8b3fbc2725277d09dea

base64编码

import base64
import hmac
import hashlib

with open('test.txt', 'rb') as fr:
    body = fr.read()
    
hash1 = hmac.new(b'a-key', body, hashlib.sha1)

digest = hash1.digest()
print(base64.encodebytes(digest))
print(base64.b64encode(digest))    # 比上面少了个换行符 '\n'`

输出:

b'hSB7hXuKcx2WQLiz+8JyUnfQneo=\n'
b'hSB7hXuKcx2WQLiz+8JyUnfQneo='

书中一个复杂的例子(可略过)

这个例子提到io缓冲、腌制什么的,感觉很难,实际看一遍,也还看得懂。

import hashlib
import hmac
import io
import pickle


def make_digest(message):
    h = hmac.new(
        b'secret-shared-key-goes-here',
        message,
        hashlib.sha1,
    )
    return h.hexdigest().encode('utf-8')


# 一个简单的类
class SimpleObject:
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return self.name


# 创建一个BytesIO缓冲区
out_s = io.BytesIO()

# 正确例子:
o = SimpleObject('digest matches')
# 将一个对象串行化
pickled_data = pickle.dumps(o)
# print(pickled_data)
# b'\x80\x04\x95<\x00\x00\x00\x00\x00\x00\x00\x8c\x08__main__\x94\x8c\x0cSimpleObject\x94\x93\x94)\x81\x94}\x94\x8c\x04name\x94\x8c\x0edigest matches\x94sb.'
digest = make_digest(pickled_data)
header = b'%s %d\n' % (digest, len(pickled_data))
print('WRITING: {}'.format(header))
# WRITING: b'2574f41071ee032fa55b17eac7c8be8e5ea36c59 71\n'
out_s.write(header)
out_s.write(pickled_data)

# 错误例子:
o = SimpleObject('digest does not match.')
pickled_data = pickle.dumps(o)
digest = make_digest(b'not the pickled data at all')
header = b'%s %d\n' % (digest, len(pickled_data))
print('WRITING: {}'.format(header))
out_s.write(header)
out_s.write(pickled_data)

out_s.flush()

in_s = io.BytesIO(out_s.getvalue())
while True:
    first_line = in_s.readline()
    if not first_line:
        break
    incoming_digest, incoming_length = first_line.split(b' ')
    incoming_length = int(incoming_length.decode('utf-8'))
    print('\nREAD:', incoming_digest, incoming_length)

    incoming_pickled_data = in_s.read(incoming_length)

    actual_digest = make_digest(incoming_pickled_data)
    print('ACTUAL:', actual_digest)

    if hmac.compare_digest(actual_digest, incoming_digest):
        obj = pickle.loads(incoming_pickled_data)
        print('OK:', obj)
    else:
        print('WARING: Data corruption')

# 输出:
# WRITING: b'2574f41071ee032fa55b17eac7c8be8e5ea36c59 71\n'
# WRITING: b'b01b209e28d7e053408ebe23b90fe5c33bc6a0ec 79\n'
#
# READ: b'2574f41071ee032fa55b17eac7c8be8e5ea36c59' 71
# ACTUAL: b'2574f41071ee032fa55b17eac7c8be8e5ea36c59'
# OK: digest matches
#
# READ: b'b01b209e28d7e053408ebe23b90fe5c33bc6a0ec' 79
# ACTUAL: b'd64506a3bf18b459748c0ccfd4d675c6bed412ae'
# WARING: Data corruption

猜你喜欢

转载自www.cnblogs.com/qydw000/p/12839638.html