Secrets

Secrets can either by obscured or generated.

Obscured Secrets

Obscured secrets are secrets that are those that are given to Avendesora to securely hold. The may be things like account numbers or existing passwords. There are several ways for Avendesora to hold a secret, presented in order of increasing security.

Hide

This marks a value as being confidential, meaning that it will be protected when shown to the user, but value is not encoded or encrypted in any way. Rather, it accounts on the protections afforded the accounts file to protect its secret.

Hide(plaintext, secure=True)
plaintext (str):
The secret in plain text.
secure (bool):
Indicates that this secret should only be contained in an
encrypted accounts file. Default is True.

Example:

account = Hide('9646-3440')

Hidden

This obscures but does not encrypt the text. It can protect the secret from observers that get a quick glance of the encoded text, but if they are able to capture it they can easily decode it.

Hidden(encoded_text, secure=True, encoding=None)
encoded_text (str):
The secret encoded in base64.
secure (bool):
Indicates that this secret should only be contained in an
encrypted accounts file. Default is True.
encoding (str):
The encoding to use for the deciphered text.

Example:

account = Hidden('NTIwNi03ODQ0')

To generate the encoded text, use:

> avendesora conceal

GPG

The secret is fully encrypted with GPG. Both symmetric encryption and key-based encryption are supported. This can be used to protect a secret held in an unencrypted account file, in which case encrypting with your key is generally preferred. It can also be used to further protect a extremely valuable secret, in which case symmetric encryption is generally used.

GPG(ciphertext, encoding=None)
ciphertext (str):
The secret encrypted and armored by GPG.
encoding (str):
The encoding to use for the deciphered text.

Example:

secret = GPG('''
    -----BEGIN PGP MESSAGE-----
    Version: GnuPG v2.0.22 (GNU/Linux)

    jA0ECQMCwG/vVambFjfX0kkBMfXYyKvAuCbT3IrEuEKD//yuEMCikciteWjrFlYD
    ntosdZ4WcPrFrV2VzcIIcEtU7+t1Ay+bWotPX9pgBQcdnSBQwr34PuZi
    =4on3
    -----END PGP MESSAGE-----
''')

To generate the cipher text, use:

> avendesora conceal -e gpg

The benefit of using symmetric GPG encryption on a secret that is contained in an encrypted account file is that the passphrase will generally not be found in the GPG agent, in which case someone could not walk up to your computer while your screen is unlocked and successfully request the secret. However, the GPG agent does retain the password for a while after you decrypt the secret. If you are concerned about that, you should follow your use of Avendesora with the following command, which clears the GPG agent:

> killall gpg-agent

Scrypt

The secret is fully encrypted with Scrypt. You personal Avendesora encryption key is used (contained in ~/.config/avendesora/.key.gpg). As such, these secrets cannot be shared. This encryption method is only available if you have installed scrypt on your system (pip3 install –user scrypt). Since the Scrypt class only exists if you have installed scrypt, it is not imported into your accounts file. You would need to import it yourself before using it.

Script(ciphertext, encoding=None)
ciphertext (str):
The secret encrypted by scrypt.
encoding (str):
The encoding to use for the deciphered text.

Example:

from avendesora import Scrypt
...
secret = Scrypt(
    'c2NyeXB0ABAAAAAIAAAAASfBZvtYnHvgdts2jrz5RfbYlFYj/EQgiM1IYTnX'
    'KHhMkleZceDg0yUaOWa9PzmZueppNIzVdawAOd9eSVgGeZAIh4ulPHPBGAzX'
    'GyLKc/vo8Fe24JnLr/RQBlTjM9+r6vbhi6HFUHD11M6Ume8/0UGDkZ0='
)

To generate the cipher text, use:

> avendesora conceal -e scrypt

Generated Secrets

Generated secrets are secrets for which the actual value is arbitrary, but it must be quite unpredictable. Generated secrets are generally used for passwords and pass phrases, but it can also be used for things like personal information requested by institutions that they have no need to know. For example, a website might request your birth date to assure that you are an adult, but then also use it as a piece of identifying information if you ever call and request support. In this case they do not need your actual birth date, they just need you to give the same date every time you call in.

Password

Generates an arbitrary password by selecting symbols from the given alphabet at random. The entropy of the generated password is length*log2(len(alphabet)).

Password(
length=12, alphabet=DISTINGUISHABLE, master=None, version=None,
sep=’’, prefix=’’, suffix=’’
)
length (int):
The number of items to draw from the alphabet when creating the
password. When using the default alphabet, this will be the
number of characters in the password.
alphabet (str):
The reservoir of legal symbols to use when creating the
password. By default the set of easily distinguished
alphanumeric characters are used. Typically you would use the
pre-imported character sets to construct the alphabet. For
example, you might pass:
ALPHANUMERIC + ‘+=_&%#@’
master (str):
Overrides the master seed that is used when generating the
password. Generally, there is one master seed shared by all
accounts contained in an account file. This argument overrides
that behavior and instead explicitly specifies the master seed
for this secret.
version (str):
An optional seed. Changing this value will change the generated
password.
shift_sort(bool):
If true, the characters in the password will be sorted so that
the characters that require the shift key when typing are placed
last, making it easier to type. Use this option if you expect to
be typing the password by hand.
sep (str):
A string that is placed between each symbol in the generated
password.
prefix (str):
A string added to the front of the generated password.
suffix (str):
A string added to the end of the generated password.

Example:

passcode = Password(10)

Passphrase

Similar to Password in that it generates an arbitrary pass phrase by selecting symbols from the given alphabet at random, but in this case the default alphabet is a dictionary containing about 10,000 words.

Passphrase(
length=4, dictionary=None, master=None, version=None, sep=’ ‘,
prefix=’’, suffix=’’
)
length (int):
The number of items to draw from the alphabet when creating the
password. When using the default alphabet, this will be the
number of words in the passphrase.
dictionary (str, [str], or callable):
The reservoir of legal symbols to use when creating the
password. If not give, or if ‘default’ is given, this is a
predefined list of 10,000 words. If given as ‘bip39’ or
‘mnemonic’, this is a predefined list of the 2048 bitcoin BIP-39
seed words. Any other string is treated as a path to a file
that would contain the words. A list is taken as is. Finally, you can
pass a function that returns the list of words, in which case the
calling of the function is deferred until the words are needed, which is
helpful if creating the list is slow.
master (str):
Overrides the master seed that is used when generating the
password. Generally, there is one master seed shared by all
accounts contained in an account file. This argument overrides
that behavior and instead explicitly specifies the master seed
for this secret.
version (str):
An optional seed. Changing this value will change the generated
pass phrase.
sep (str):
A string that is placed between each symbol in the generated
password.
prefix (str):
A string added to the front of the generated password.
suffix (str):
A string added to the end of the generated password.

Example:

passcode = Passphrase()
verbal = Passphrase(2)

PIN

Similar to Password in that it generates an arbitrary PIN by selecting symbols from the given alphabet at random, but in this case the default alphabet is the set of digits (0-9).

PIN(length=4, alphabet=DIGITS, master=None, version=None)
length (int):
The number of items to draw from the alphabet when creating the
password. When using the default alphabet, this will be the
number of digits in the PIN.
alphabet (str):
The reservoir of legal symbols to use when creating the
password. By default the digits (0-9) are used.
master (str):
Overrides the master seed that is used when generating the
password. Generally, there is one master seed shared by all
accounts contained in an account file. This argument overrides
that behavior and instead explicitly specifies the master seed
for this secret.
version (str):
An optional seed. Changing this value will change the generated
PIN.

Example:

pin = PIN(6)

Question

Generates an arbitrary answer to a given question. Used for website security questions. When asked one of these security questions it can be better to use an arbitrary answer. Doing so protects you against people who know your past well and might be able to answer the questions.

Similar to Passphrase() except a question must be specified when created and it is taken to be the security question. The question is used rather than the field name when generating the secret.

Question(
question, length=3, dictionary=None, master=None, version=None,
sep=’ ‘, prefix=’’, suffix=’’, answer=None
)
question (str):
The question to be answered. Be careful. Changing the question
in any way will change the resulting answer.
length (int):
The number of items to draw from the alphabet when creating the
password. When using the default alphabet, this will be the
number of words in the answer.
dictionary (str, [str], or callable):
The reservoir of legal symbols to use when creating the
password. If not give, or if ‘default’ is given, this is a
predefined list of 10,000 words. If given as ‘bip39’ or
‘mnemonic’, this is a predefined list of the 2048 bitcoin BIP-39
seed words. Any other string is treated as a path to a file
that would contain the words. A list is taken as is. Finally, you can
pass a function that returns the list of words, in which case the
calling of the function is deferred until the words are needed, which is
helpful if creating the list is slow.
master (str):
Overrides the master seed that is used when generating the
password. Generally, there is one master seed shared by all
accounts contained in an account file. This argument overrides
that behavior and instead explicitly specifies the master seed
for this secret.
version (str):
An optional seed. Changing this value will change the generated
answer.
sep (str):
A string that is placed between each symbol in the generated
password.
prefix (str):
A string added to the front of the generated password.
suffix (str):
A string added to the end of the generated password.
answer:
The answer. If provided, this would override the generated
answer. May be a string, or it may be an Obscured object.

Example:

questions = [
    Question('Favorite foreign city'),
    Question('Favorite breed of dog'),
]

PasswordRecipe

Generates passwords that can conform to the restrictive requirements imposed by websites. Allows you to specify the length of your password, and how many characters should be of each type of character using a recipe. The recipe takes the form of a string that gives the total number of characters that should be generated, and then the number of characters that should be taken from particular character sets. The available character sets are:

l - lower case letters (a-z)
u - upper case letters (A-Z)
d - digits (0-9)
s - punctuation symbols
c - explicitly given set of characters

For example, ‘12 2u 2d 2s’ is a recipe that would generate a 12-character password where two characters would be chosen from the upper case letters, two would be digits, two would be punctuation symbols, and the rest would be alphanumeric characters. It might generate something like: @m7Aqj=XBAs7

Using ‘12 2u 2d 2c!@#$%^&*’ is similar, except the punctuation symbols are constrained to be taken from the given set that includes !@#$%^&*. It might generate something like: YO8K^68J9oC!

PasswordRecipe(
recipe, def_alphabet=ALPHANUMERIC, master=None, version=None,
)
recipe (str):
A string that describes how the password should be constructed.
def_alphabet (list of strs):
The alphabet to use when filling up the password after all the
constraints are satisfied.
master (str):
Overrides the master seed that is used when generating the
password. Generally, there is one master seed shared by all
accounts contained in an account file. This argument overrides
that behavior and instead explicitly specifies the master seed
for this secret.
version (str):
An optional seed. Changing this value will change the generated
answer.
shift_sort(bool):
If true, the characters in the password will be sorted so that
the characters that require the shift key when typing are placed
last, making it easier to type. Use this option if you expect to
be typing the password by hand.

Example:

passcode = PasswordRecipe(‘12 2u 2d 2c!@#$%^&*’)

BirthDate

Generates an arbitrary birth date for someone in a specified age range.

BirthDate(
year, min_age=18, max_age=65, fmt=’YYYY-MM-DD’,
master=None, version=None,
)
year (int):
The year the age range was established.
min_age (int):
The lower bound of the age range.
max_age (int):
The upper bound of the age range.
fmt (str):
Specifies the way the date is formatted. Consider an example
date of 6 July 1969. YY and YYYY are replaced by the year (69 or
1969). M, MM, MMM, and MMMM are replaced by the month (7, 07,
Jul, or July). D and DD are replaced by the day (6 or 06).
master (str):
Overrides the master seed that is used when generating the
password. Generally, there is one master seed shared by all
accounts contained in an account file. This argument overrides
that behavior and instead explicitly specifies the master seed
for this secret.
version (str):
An optional seed. Changing this value will change the generated
answer.

Example:

birthdate = BirthDate(2015, 21, 55)

Base58

Generates an arbitrary Base58 encoded stringa. Base58 is an encoding developed for Bitcoin addresses. It is nice because the characters are limited to standard ASCII numbers and letters, and those characters that could be confused for one another are removed. Specifically, the Base58 character set are all ASCII numbers and letters except for 0, O, I, and l.

Base58 generates the shortest strings for a given amount of entropy of any of the secrets generated by Avendesora.

Base58(
bytes=4, master=None, version=None, is_secret=True,
)
bits (int):
The number of bytes of entropy encoded in the result.
master (str):
Overrides the master seed that is used when generating the
password. Generally, there is one master seed shared by all
accounts contained in an account file. This argument overrides
that behavior and instead explicitly specifies the master seed
for this secret.
version (str):
An optional seed. Changing this value will change the generated
answer.
is_secret (bool):
Should value be hidden from the user unles explicitly requested.

Example:

secret = Base58(8)

OTP

Generates a secret that changes once per minute that generally is used as a second factor when authenticating. It can act as a replacement for, and is fully compatible with, Google Authenticator. You would provide the text version of the shared secret (the backup code) that is presented to you when first configuring your second factor authentication.

OTP(shared_secret, interval=30, digits=6)
shared_secret (base32 string):
The shared secret, it will be provided by the account provider.
interval (int):
Update interval in seconds.
max_age (int):
The number of digits to output.

Example:

otp = OTP('JBSWY3DPEHPK3PXP')

Changing a Generated Secret

It is sometimes necessary to change a generated secret. Perhaps because it was inadvertently exposed, or perhaps because the account provider requires you change your secret periodically. To do so, you would simply add the version argument to the secret and then update its value. version may be a number or a string. You should choose a way of versioning that is simple, easy to guess and would not repeat. For example, if you expect that updating the version would be extremely rare, you can simply number them sequentially. Or, if you you need to update them every month or every quarter, you can name them after the month or quarter (ex: jan19 or 19q1).

Examples:

passcode = PasswordRecipe('16 1d', version=2)
passcode = PasswordRecipe('16 1d', version='19q2')