I am trying to generate a password using a seed in Python and I want the ability to customize the length
I found the Faker library which let me generate passwords with seed but I am unable to customize the output, code below
from faker import Faker
class Password:
f0 = Faker()
Faker.seed(1234)
print(f0.password())
print(f0.sentence())
print(f0.msisdn())
output:
tA1b&i5ck*
Require suddenly me they.
1871918904814
I could not find documentation for customizing faker length (I can truncate the output sure, but what if I want longer?) in python so are there arguments im missing ?
Else is there another library that generates customizable strings using seeds?
Simply truncate the returned value, as desired.
k = 8
print(f0.password()[:k])
If you want it longer, it isn't hard to go to the trouble
of consulting the
documentation:
password(length: int = 10, special_chars: ...)
Generate a random password of the specified length.
Use
k = 80
print(f0.password(k))
———
Also, sha3() hexadecimal hash output makes for terrific passwords.
https://docs.python.org/3/library/hashlib.html
Related
I have a paradoxon, that I just cannot explain.
In short: I built a python script that is supposed to crack a zipped file, which is password protected.
This is what I've done:
(1) zip the text file:
zip --password bla zip3.zip myZip So the passphrase is "bla".
(2) Then I use the following Python Script:
import zipfile
import itertools
from itertools import *
import string
import time
That's the basic function, that is supposed to check, if a given password works or not:
def crack(File, pwd):
try:
File.extractall(pwd=str.encode(pwd))
print("\n---- SUCCESS! {0} ----".format(pwd))
except:
print("{0} did not work.".format(pwd))
pass
Here I specify, which characters I want to use for trying:
myLetters = string.ascii_letters
Here I specify, which zip-file I want to crack:
File = zipfile.ZipFile("PATH/TO/MY/zip3.zip", 'r')
Here I specify, how long the password-phrase is:
pwd_len = 3
here I specify, how many possible combinations of the charactes exist:
all_poss = (len(myLetters)**pwd_len)
Here is the procedure for concrete password cracking:
count = 0
start_time = time.time()
for i in range(0,pwd_len+1):
for j in map(''.join, itertools.product(myLetters, repeat=i)):
crack(File, j)
count += 1
print(round((count/all_poss)*100, 1), end='\r')
res_time = time.time() - start_time
print("\n--- {} ---".format(round(res_time,2)))
I use a nested loop, to try every password. If it works, I should get the Success-message. Else I should only see the "doesn't work message".
However...
If I type in my terminal: python3 pwdCracker.py >> out I get a long text file, which contains many many "does not work messages", BUT I also get a whole bunch of "Success-messages", although only ONE ("bla") should be correct.
Here is a little extract:
wN did not work.
---- SUCCESS! wO ----
wO did not work.
wP did not work.`
So apparently "wO" is working.. But why?? I set the password to "bla"! I really can open the file with "wO"... why can that happen??
Hope you can help!
The default zip encryption is known to be weak, and I think you are seeing hash collisions 1,2.
Most encryption methods (including those used in zip files) need a fixed length key, and so the password is hashed to give that key. The hash function used in zip is crc32 (specified here, although it details a different attack) which was designed for error checking rather than cryptographic hashing. Therefore it will be vulnerable to this type of attack.
The old zip format contains a check byte to quickly verify if your password is right or wrong. This check byte is verified against the last byte of the decrypted 'decryption header'.
Since the check byte is, well, only one byte, false positives happen quite frequently (1/256). What bruteforce crackers usually do in these cases is to check against multiple files from the same archive (hence using multiple check bytes).
From PkWare's APPNOTE.TXT:
After the header is decrypted, the last 1 or 2 bytes in Buffer SHOULD
be the high-order word/byte of the CRC for the file being decrypted,
stored in Intel low-byte/high-byte order. Versions of PKZIP prior to
2.0 used a 2 byte CRC check; a 1 byte CRC check is used on versions after 2.0.
This can be used to test if the password supplied is correct or not.
So what you are seeing is just that, false positives.
I have a problem with generating the random string in robot. I am very new in robot and really dont know how to figure it out..
I found some solutions here and I tried to follow then, but I am doing something wrong obviously..
I got this error message in console: No keyword with name '${random_string} = Generate Random String' found.
My test case:
*** Settings ***
Library String
Resource resource.robot
*** Test Cases ***
Add New Project
${random_string} = Generate Random String 12 [LOWER]
Fill In Project Mandatory Fields ${random_string} descriptiondunno
Verify Added Project
[Teardown] Close Browser
In the resource file I have defined the keywords I am using in test:
Fill In Project Mandatory Fields
[Arguments] ${random_string} ${description}
Wait Until Element Is Visible ${PROJECT TITLE}
Input Text ${PROJECT TITLE} ${random_string}
and also:
Verify Added Project
[Arguments] ${random_string}
Click Element ${PROJECTS}
Table Should Contain ${GRID} ${random_string}
I really appreciate any help, because I am really lost in this now :(
Thanks!
What are you using as a separator? Just spaces? If so, maybe increase to using four spaces to clearly separate things
Based on the error it seems to think
${random_string} = Generate Random String 12 [LOWER]
is a keyword, this is not what you want, you only want it to consider Generate Random String a keyword.
Try the below and let us know what happens:
${random_string}= Generate Random String 12 [LOWER]
I need to generate a API key and Secret that would be stored in a Redis server. What would be the best way to generate a key and secret?
I am develop a Django-tastypie framework based app.
If you're on Python 3.6 or later, the secrets module is the way to go:
The secrets module is used for generating cryptographically strong random numbers suitable for managing data such as passwords, account authentication, security tokens, and related secrets.
In particular, secrets should be used in preference to the default pseudo-random number generator in the random module, which is designed for modelling and simulation, not security or cryptography.
e.g. to generate a 16 byte token:
>>> import secrets
>>> secrets.token_urlsafe(16)
'zs9XYCbTPKvux46UJckflw'
>>> secrets.token_hex(16)
'6bef18936ac12a9096e9fe7a8fe1f777'
For python3.6+
import secrets
generated_key = secrets.token_urlsafe(length)
For older versions of python:
for a very secure way of generating random number, you should use urandom:
from binascii import hexlify
key = hexlify(os.urandom(length))
this will produce bytes, call key.decode() if you need a string
For general non-secure random strings, with more settings, you can just generate keys of your desired length the python way:
import random
import string
def generate_key(length):
return ''.join(random.choice(string.ascii_letters + string.digits) for _ in range(length))
And then you can just call it with your desired length key = generate_key(40).
You can specify what alphabet you want to use, for example using only string.ascii_lowercase for key consisting of only lowercase letters etc.
There is also Model for Api authentication in tastypie, might be worth checking out https://django-tastypie.readthedocs.org/en/latest/authentication.html#apikeyauthentication
you can also use following module to generate random string
1 - os.urandom(64).encode('hex') #from os module
2 - uuid.uuid4() # from uuid module
3 - get_random_string(length=32) #from django.utils.crypto
4 - secrets.token_hex(64) #from secrets >= python 3.6
Adding answer as I can't comment on T. Opletals answer.
You should not use random.choice as random isn't cryptographically secure. A better option would be random.SystemRandom() which uses the system source of randomness, on linux this would be urandom.
def generate_key(length):
char_set = string.ascii_letters + string.punctuation
urand = random.SystemRandom()
return ''.join([urand.choice(char_set) for _ in range(length)])
If you want an easy-to-use but highly customisable key generator, use key-generator pypi package.
Here is the GitHub repo where you can find the complete documentation.
Here's an example:
from key_generator.key_generator import generate
custom_key = generate(2, ['-', ':'], 3, 10, type_of_value = 'char', capital = 'mix', seed = 17).get_key()
print(custom_key) # ZLFdHXIUe-ekwJCu
Hope this helps :)
Disclaimer: This uses the key-generator library which I made.
I am trying to retrieve the password and authenticate from the Galaxy framework. I successfully retrieve the password it's in hashed(sha1) format. How do I authenticate this with the password input by the user? My first guess would be converting hashed(sha1) into normal string and authenticating. Is that possible? If it is, how can I convert it into the string?
You can't. It would be extremely hard to get the plain text from its hash code, that's exactly the reason why we had invented hash. Try the opposite: convert the plain text to hash and then compare.
How to convert:
import hashlib
s = "plain"
h = hashlib.sha1(s).hexdigest()
... My first guess would be converting hashed(sha1) into normal string ...
That's what cryptographic hash functions try to prevent (among other things) - this property is called pre-image resistance.
The basic steps would be the other way around:
take user input
compute hash over user input
compare hashed user input to stored credentials/hashes
I need to arrange some kind of encrpytion for generating user specific links. Users will be clicking this link and at some other view, related link with the crypted string will be decrypted and result will be returned.
For this, I need some kind of encryption function that consumes a number(or a string) that is the primary key of my selected item that is bound to the user account, also consuming some kind of seed and generating encryption code that will be decrypted at some other page.
so something like this
my_items_pk = 36 #primary key of an item
seed = "rsdjk324j23423j4j2" #some string for crypting
encrypted_string = encrypt(my_items_pk,seed)
#generates some crypted string such as "dsaj2j213jasas452k41k"
and at another page:
decrypt_input = encrypt(decypt,seed)
print decrypt_input
#gives 36
I want my "seed" to be some kind of primary variable (not some class) for this purpose (ie some number or string).
How can I achieve this under python and django ?
There are no encryption algorithms, per se, built in to Python. However, you might want to look at the Python Cryptography Toolkit (PyCrypt). I've only tinkered with it, but it's referenced in Python's documentation on cryptographic services. Here's an example of how you could encrypt a string with AES using PyCrypt:
from Crypto.Cipher import AES
from urllib import quote
# Note that for AES the key length must be either 16, 24, or 32 bytes
encryption_obj = AES.new('abcdefghijklmnop')
plain = "Testing"
# The plaintext must be a multiple of 16 bytes (for AES), so here we pad it
# with spaces if necessary.
mismatch = len(plain) % 16
if mismatch != 0:
padding = (16 - mismatch) * ' '
plain += padding
ciph = encryption_obj.encrypt(plain)
# Finally, to make the encrypted string safe to use in a URL we quote it
quoted_ciph = quote(ciph)
You would then make this part of your URL, perhaps as part of a GET request.
To decrypt, just reverse the process; assuming that encryption_obj is created as above, and that you've retrieved the relevant part of the URL, this would do it:
from urllib import unquote
# We've already created encryption_object as shown above
ciph = unquote(quoted_ciph)
plain = encryption_obj.decrypt(ciph)
You also might consider a different approach: one simple method would be to hash the primary key (with a salt, if you wish) and store the hash and pk in your database. Give the user the hash as part of their link, and when they return and present the hash, look up the corresponding pk and return the appropriate object. (If you want to go this route, check out the built-in library hashlib.)
As an example, you'd have something like this defined in models.py:
class Pk_lookup(models.Model):
# since we're using sha256, set the max_length of this field to 32
hashed_pk = models.CharField(primary_key=True, max_length=32)
key = models.IntegerField()
And you'd generate the hash in a view using something like the following:
import hashlib
import Pk_lookup
hash = hashlib.sha256()
hash.update(str(pk)) # pk has been defined previously
pk_digest = hash.digest()
lookup = Pk_lookup(hashed_pk=pk_digest,key=pk)
lookup.save()
Note that you'd have to quote this version as well; if you prefer, you can use hexdigest() instead of digest (you wouldn't have to quote the resulting string), but you'll have to adjust the length of the field to 64.
Django has features for this now. See https://docs.djangoproject.com/en/dev/topics/signing/
Quoting that page:
"Django provides both a low-level API for signing values and a high-level API for setting and reading signed cookies, one of the most common uses of signing in Web applications.
You may also find signing useful for the following:
Generating “recover my account” URLs for sending to users who have lost their password.
Ensuring data stored in hidden form fields has not been tampered with.
Generating one-time secret URLs for allowing temporary access to a protected resource, for - example a downloadable file that a user has paid for."