1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889 |
- #!/usr/bin/env python
- #
- # This is a port of classical passgen (provided by jxself) into the python
- # language.
- #
- # Hey, given a portable python installation in Windows, we could even have
- # a graphical version of this program with GTK3
- #
- # Copyright (C) 2016 - kzimmermann <https://quitter.se/kzimmermann>
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- #
- import sys
- import base64 as b64
- import hashlib
- from getpass import getpass
- #---- Standard configuration variables:
- seclevel = 7 # how many times tokens are hashed
- #---- Functions:
- def secure_hash(token):
- """
- Hashes multiple times a given string so as to provide something that should
- not be easy to reverse. Standardized as seven times, but feel free to
- change it to as much as your own paranoia needs.
- Returns a SHA-256 hash.
- """
- temp = str(token)
- for i in xrange(seclevel):
- temp = hashlib.sha256(temp).hexdigest()
- return temp
- def generate(salt, string):
- """
- Generates a 32-char long password based on algorithm v1 (hash then encode).
- Arguments are a password seed (called a salt) and a service-specific string
- so all passwords generated will be different.
- The 32 characters are sampled from a different position depending on the
- salt used. This should always work provided that the salt isn't too long.
- """
- # So that the sampling is not that obvious ;)
- start = len("%s%s" % (salt, string))
- temp = secure_hash("%s%s" % (salt, string))
- return b64.b64encode(temp)[start:start+32]
- def main():
- """
- Main interaction when module has not been imported
- """
- while True:
- seed = getpass("Enter your salt: ")
- seed_confirm = getpass("Confirm: ")
-
- if seed == seed_confirm:
- break
- else:
- print "Salts don't match. Try again."
- if len(sys.argv) == 1:
- string = raw_input("Enter your string: ")
- elif len(sys.argv) == 2:
- string = sys.argv[1]
- print generate(seed, string)
- if __name__ == "__main__":
- main()
- sys.exit(0)
|