mitsuhiko / mitsuhiko/python-pbkdf2
python3 port
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 149
- Forks
- 28
- PR merge metrics
- No merged PRs in 30d
Description
if I could submit a PR, I would
- the machine I wrote the updated code on is offline behind a non-functional subnet.
- I'm not willing to give Micro$**t the undeserved pleasure of me putting my sources on their platform for them to control by forking a repo, I pulled my sources when they partnered, and I intend to keep things that way.
(call me rude all you like, I'm not the one restricting freedoms and making a profit off my sheep)
but anyways, with that out of the way, here's the updated code:
import hmac
import hashlib
from struct import Struct
from operator import xor
from itertools import starmap
try:
from itertools import izip as zip
except ImportError: pass # py3
try: range = xrange
except NameError: pass # py3
_pack_int = Struct('>I').pack
def pbkdf2_hex(data, salt, iterations=1000, keylen=24, hashfunc=None):
"""Like :func:`pbkdf2_bin` but returns a hex encoded string."""
return ''.join('%02x'%(v if type(v) is int else ord(v)) for v in
pbkdf2_bin(data, salt, iterations, keylen, hashfunc))
def pbkdf2_bin(data, salt, iterations=1000, keylen=24, hashfunc=None):
"""Returns a binary digest for the PBKDF2 hash algorithm of `data`
with the given `salt`. It iterates `iterations` time and produces a
key of `keylen` bytes. By default SHA-1 is used as hash function,
a different hashlib `hashfunc` can be provided.
"""
hashfunc = hashfunc or hashlib.sha1
mac = hmac.new(data, None, hashfunc)
buf = []
for block in range(1, -(-keylen // mac.digest_size) + 1):
h = mac.copy()
h.update(salt + _pack_int(block))
u = h.digest()
rv = list(bytearray(u)) # needs further testing on py2 and could possibly be more performant
for i in range(iterations - 1):
h = mac.copy()
h.update(bytes(u))
u = h.digest()
rv = starmap(xor, zip(rv, list(bytearray(u))))
buf.extend(rv)
return ''.join(map(chr, buf))[:keylen]
I've even ported the tests over and manually verified every expected key with your keys
(it was easier working 2 keyboards for 12 keys than copying the tests over on a flash drive)
all tests have passed.
a few things you may notice:
- removed
_pseudorandom()to improve overhead performance while maintaining namespace security - yes I'm locally overriding zip and range for py2, since this reflects a py3 namespace
(@triggeredpythonists: I wouldn't do this if the original functionality was actually needed, please remain calm)
respect:
- +1 for not following the crowd by using
''%()over''.format();)
tips/advice:
- you might want to
from __future__ import print_functionfor portingprinttoprint()intest()->check()
keep the credit, I care more about security than I care about being the one who ported your code ;)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by locating the existing PBKDF2 implementation and its test suite, then compare them with the Python 3 code and ported tests included in the issue. Done means the port is integrated without breaking the existing behavior and the full test suite passes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- cryptography
- Issue type
- Refactor
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100