Reference(s): https://web.archive.org/web/20120219120128/packetstormsecurity.org/files/74448/phpassbrute.py.txt http://scriptserver.mainframe8.com/wordpress_password_hasher.php https://www.openwall.com/phpass/ https://github.com/jedie/django-phpBB3/blob/master/dj
(password, salt, count, prefix, **kwargs)
| 490 | return "%s:%s" % (md5(getBytes(salt) + getBytes(password)).hexdigest(), salt) |
| 491 | |
| 492 | def phpass_passwd(password, salt, count, prefix, **kwargs): |
| 493 | """ |
| 494 | Reference(s): |
| 495 | https://web.archive.org/web/20120219120128/packetstormsecurity.org/files/74448/phpassbrute.py.txt |
| 496 | http://scriptserver.mainframe8.com/wordpress_password_hasher.php |
| 497 | https://www.openwall.com/phpass/ |
| 498 | https://github.com/jedie/django-phpBB3/blob/master/django_phpBB3/hashers.py |
| 499 | |
| 500 | >>> phpass_passwd(password='testpass', salt='aD9ZLmkp', count=2048, prefix='$P$') |
| 501 | '$P$9aD9ZLmkpsN4A83G8MefaaP888gVKX0' |
| 502 | >>> phpass_passwd(password='testpass', salt='Pb1j9gSb', count=2048, prefix='$H$') |
| 503 | '$H$9Pb1j9gSb/u3EVQ.4JDZ3LqtN44oIx/' |
| 504 | >>> phpass_passwd(password='testpass', salt='iwtD/g.K', count=128, prefix='$S$') |
| 505 | '$S$5iwtD/g.KZT2rwC9DASy/mGYAThkSd3lBFdkONi1Ig1IEpBpqG8W' |
| 506 | """ |
| 507 | |
| 508 | def _encode64(input_, count): |
| 509 | output = '' |
| 510 | i = 0 |
| 511 | |
| 512 | while i < count: |
| 513 | value = (input_[i] if isinstance(input_[i], int) else ord(input_[i])) |
| 514 | i += 1 |
| 515 | output = output + ITOA64[value & 0x3f] |
| 516 | |
| 517 | if i < count: |
| 518 | value = value | ((input_[i] if isinstance(input_[i], int) else ord(input_[i])) << 8) |
| 519 | |
| 520 | output = output + ITOA64[(value >> 6) & 0x3f] |
| 521 | |
| 522 | i += 1 |
| 523 | if i >= count: |
| 524 | break |
| 525 | |
| 526 | if i < count: |
| 527 | value = value | ((input_[i] if isinstance(input_[i], int) else ord(input_[i])) << 16) |
| 528 | |
| 529 | output = output + ITOA64[(value >> 12) & 0x3f] |
| 530 | |
| 531 | i += 1 |
| 532 | if i >= count: |
| 533 | break |
| 534 | |
| 535 | output = output + ITOA64[(value >> 18) & 0x3f] |
| 536 | |
| 537 | return output |
| 538 | |
| 539 | password = getBytes(password) |
| 540 | f = {"$P$": md5, "$H$": md5, "$Q$": sha1, "$S$": sha512}[prefix] |
| 541 | |
| 542 | cipher = f(getBytes(salt)) |
| 543 | cipher.update(password) |
| 544 | hash_ = cipher.digest() |
| 545 | |
| 546 | for i in xrange(count): |
| 547 | _ = f(hash_) |
| 548 | _.update(password) |
| 549 | hash_ = _.digest() |