python3密码库_Python3标准库:hmac密码信息签名与验证|python基础教程|python入门|python教程...

https://www.xin3721.com/eschool/pythonxin3721/

1. hmac密码信息签名与验证

HMAC算法可以用于验证信息的完整性,这些信息可能在应用之间传递,或者存储在一个可能有安全威胁的地方。基本思想是生成实际数据的一个密码散列,并提供一个共享的秘密密钥。然后使用得到的散列检查所传输或存储的信息,以确定一个信任级别,而不是传输秘密密钥。

1.1 消息签名

new()函数会创建一个新对象来计算消息签名。下面这个例子使用了默认的MD5散列算法。

importhmac

digest_maker=hmac.new(b'secret-shared-key-goes-here')

withopen('lorem.txt','rb')asf:

whileTrue:

block=f.read(1024)

ifnotblock:

break

digest_maker.update(block)

digest=digest_maker.hexdigest()

print(digest)

运行这段代码时,会读取一个数据文件,并为它计算一个HMAC签名。

1.2 候选摘要类型

尽管hmac的默认密码算法是MD5,但这并不是最安全的方法。MD5散列有一些缺点,如冲突(两个不同的消息生成相同的散列)。一般认为SHA1算法更健壮,更建议使用。

importhmac

importhashlib

digest_maker=hmac.new(

b'secret-shared-key-goes-here',

b'',

hashlib.sha1,

)

withopen('demo.py','rb')asf:

whileTrue:

block=f.read(1024)

ifnotblock:

break

digest_maker.update(block)

digest=digest_maker.hexdigest()

print(digest)

new()函数有3个参数。第1个参数是秘密密钥,这个密钥会在通信双方之间共享,使两端都可以使用相同的值。第2个值是一个初始消息。如果需要认证的消息内容很小,如一个时间戳或一个HTTP POST,则把整个消息体都传递到new()而不是使用update()方法。最后一个参数是要使用的摘要模块。默认为hashlib.md5,不过这个例子传入了'sha1',其会让hmac使用hashlib.sha1。

1.3 二进制摘要

前面的例子使用hexdigest()方法来生成可打印的摘要。hexdigest是digest()方法计算的值的一个不同表示,这是一个二进制值,可以包括不可打印的字符(包括NUL)。有些Web服务(Google checkout、Amazon S3)会使用base64编码版本的二进制摘要而不是hexdigest。

importbase64

importhmac

importhashlib

withopen('lorem.txt','rb')asf:

body=f.read()

hash=hmac.new(

b'secret-shared-key-goes-here',

body,

hashlib.sha1,

)

digest=hash.digest()

print(base64.encodebytes(digest))

base64编码串以一个换行符结束,在HTTP首部或其他格式敏感的上下文中嵌入这个串时,通常需要去除这个换行符。

1.4 消息签名的应用

对于所有公共网络服务,在安全性要求很高的地方存储数据,就应当使用HMAC认证。例如,通过一个管道或套接字发送数据时,应当对数据进行签名,然后在使用这个数据之前要检查这个签名。文件hmac_pickle.py中给出了一个扩展例子。

第一步是建立一个函数,计算一个串的摘要,另外实例化一个简单的类,并通过一个通信通道传递。

importhashlib

importhmac

importio

importpickle

importpprint

defmake_digest(message):

"Return a digest for the message."

hash=hmac.new(

b'secret-shared-key-goes-here',

message,

hashlib.sha1,

)

returnhash.hexdigest().encode('utf-8')

classSimpleObject:

"""Demonstrate checking digests before unpickling.

"""

def__init__(self,name):

self.name=name

def__str__(self):

returnself.name

接下来,创建一个ByteIO缓冲区表示这个套接字或管道。这个例子对数据流使用了一种易于解析的原生格式。首先写出摘要以及数据长度,后面是一个换行符。接下来是对象的串行化表示(由pickle生成)。实际的系统可能不希望依赖于一个长度值,毕竟如果摘要不正确,这个长度可能也是错误的。更适合的做法是使用真实数据中不太可能出现的某个终止符序列。

然后示例程序向流写两个对象。写第一个对象时使用了正确的摘要值。

#Simulate a writable socket or pipe with a buffer

out_s=io.BytesIO()

#Write a valid object to the stream:

#digest\nlength\npickle

o=SimpleObject('digest matches')

pickled_data=pickle.dumps(o)

digest=make_digest(pickled_data)

header=b'%s %d\n'%(digest,len(pickled_data))

print('WRITING: {}'.format(header))

out_s.write(header)

out_s.write(pickled_data)

再用一个不正确的摘要将第二个对象写入流,这个摘要是为其他数据计算的,而并非由pickle生成。

#Write an invalid object to the stream

o=SimpleObject('digest does not match'

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值