Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Questions about algorithm #9

Closed
juev opened this issue May 18, 2021 · 6 comments
Closed

Questions about algorithm #9

juev opened this issue May 18, 2021 · 6 comments

Comments

@juev
Copy link

juev commented May 18, 2021

Hello,

thank you for this scrambler!

I have some questions:

  1. We have several aes encoding:
    firstly we got file content, password and login for work:
        # first thing first, fail if seed file does not exist
        with open( args.file, 'rb' ) as fd:
            raw = fd.read()

        password = getpass.getpass()
        key = scramble( password, args.func )    
        vec = scramble( args.login, args.func )

        aes_out1 = aes_encrypt( vec, key, raw )

These data used for geting aes coding. If we have file/password/login we can generate long password, but why we encode these data again?

      sha_digest = hashlib.sha512(aes_out1).digest()
      passlen    = len(password) % len(sha_digest)
      key2       = sha_digest[passlen: passlen+32]

      aes_out2 = aes_encrypt( key, key2, aes_out1 )

and only after this we generate password:

      start    = key[0] % len(aes_out2)
      portion  = aes_out2[start:]
      result   = hashlib.sha512(portion).digest()
      longpass = base64.b64encode(result)
      longpass = longpass[0:args.length]
      longpass = convert_to_charset(longpass,  sorted(args.special, reverse=True))

what point for second encoding?

  1. I don't understand how you chose special character. We use base64 encoding for pasword:
      longpass = base64.b64encode(result)
      longpass = longpass[0:args.length]
      longpass = convert_to_charset(longpass,  sorted(args.special, reverse=True))

as result we have base64 string, by default is alphanumeric string with several special symbols. As I can see, we only replace these symbols to our special_symbols. What point? Why we don't use aes encoded string for converting? For example?

  1. We have some arguments in our cli, as length, special_symbols, scramble_func. How you can remember, what arguments do you used for generating password?
@hasherezade
Copy link
Owner

Hi!
Thank you for your interest.
I will try to answer your questions.

  1. Indeed AES is encryption is used twice. In fact the number of rounds is arbitrary, the only criteria is that we must have several strong encryption + hashing algorithms combined in an unusual way, so that cracking them/looking them up in the public database will not be easy.
    For example: if you use just md5(short_password) as your password, it is too weak, because there are plenty of databases of hashes with common passwords, which can be used as a dictionary to brutforce. On the other hand, something a bit more complex, like: sha512(aes(short_password,sha512(short_password),login)) will be much better - probably not listed in many hash databases - yet still it can be brutforced knowing the login and having a good dictionary. In order to avoid the brutforce possibility, the seed file was introduced.
    Yet, in some variants of this tool, the file is not compulsory. Although it is recommended, there are users who just want to proceed without it, for some temporary or unimportant accounts, when they want simplicity above all.
    The second AES round was introduced to make the algorithm more complicated for the cases if the seed file was not filled.
  • First we encrypt the seed file content, using the (processed) password and the the login as appropriately the key and IV.

    • If the seed file was given (as recommended), the output of this function is: base64.b64encode( iv + cipher.encrypt( raw ) ) - we can say this buffer has a strong enough entropy, and further processing is not needed.
    • But if the seed file was not provided, we will get only base64.b64encode( iv + cipher.encrypt( padding ) ) . There was no file content to be encrypted, only the padding. To make it further more complicated, I decided to make the second round.
  • In the second round we encrypt the output of the first round again - with a different password and IV. We gain yet another layer of mixing things together. What if we drop it? In the case with no seed file we would just make a SHA512 hash of the: base64.b64encode( iv + cipher.encrypt( padding ) ) - Base64 encoded, IV + AES encrypted padding. Would it suffice? Probably yes. But why not to go few steps further than the minimum?

This scrambler is just to showcase some idea, but you can make various combinations of algorithms just as you wish.

  1. I replaced the special characters of Base64 because when I was testing it, in some services those particular characters were not accepted.
  2. You don't have to change them for each service where you generate a password for. You can just define one preset for yourself and use it all the time. But making such details changeable across various users is yet another thing that makes brutforcing more difficult, and the whole thing more secure in case if the weaker variant (without the seed file) has been used.

I hope it answers your questions.

@juev
Copy link
Author

juev commented May 27, 2021

Thank you!

  1. I understand now. 😄
  2. I know how you replacing special characters in longpassword. But base64 example:
    RXZzeXVrb3YgRGVuaXM=, we have only one character what is not alphanumeric, and only one characters will replaced with our character array element. How you get several special symbols?
  3. I got it! 😄 But we can have one site,when we cannot to use special characters in password, for example. And another site, when this restrictions is not exist. How we can remember this points?

@hasherezade
Copy link
Owner

  1. It is not really just one character: look at the Base64 charset, i.e. here. There are 3 special characters:+/=. And two of them can occur inside the string, not just at the end as a padding.
    Also, the model of replacing them is not just a simple substitution (such as + always replaced by _) but by the order of occurrence (i.e. assuming that the special charset to use is $%^&#, the first special character that is not in the charset, i.e. + will be replaced with the first character of the charset: $, them next + with % and so on...). By this way we can have even more special characters in the output charset than in the input charset.
  2. Do you mean that on the site (https://hasherezade.github.io/passcrambler/) this features of the Python version are not present? This is true, currently only the basic version of the scrambler is implemented in JavaScript. But I am planning to enrich it in the future, to achieve full compatibility.

Please let me know if everything is clear now.

@juev
Copy link
Author

juev commented May 29, 2021

  1. I got it 😄
  2. No, I mean, you told to me:

    You can just define one preset for yourself and use it all the time
    If I use one preset, it can not work on another site with specific requirements. How I can resolve this issue?

@juev
Copy link
Author

juev commented May 30, 2021

jFYI: I created passcrambler on Rust.
I used some different ideas. For example, I use AES hash for seeding random numbers. And passcrambler always run only with file.

Maybe I'm wrong, and this algorithm not secure.

@juev
Copy link
Author

juev commented Jun 5, 2021

Thank you!

@juev juev closed this as completed Jun 5, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants