2
$\begingroup$

i sha2-256 hash the password, then i base64 encode the hash (per RFC 2045) , resulting in a 44 bytes string looking like LPJNul+wow4m6DsqxbninhsWHlwfp0JecwQzYpOLmCQ= , then i bcrypt ...crypt() that (using a securely generated salt), and i get something like $2b$10$HyPnAMyB2l1onzLjxEeRHuSioZ/X31I/XP6oHa.SPHA7KxJbR9Jq.

anything obviously wrong/bad with that scheme?

and if you're wondering why i'm doing it like this: bcrypt crypt() (at least the implementation i'm using) has 2 annoyances, most importantly, it can't handle NULL bytes, it thinks "\x00foo" is the same as "\x00bar". secondly, it only considers the first 72 bytes of the input password. sha2-256 don't have the NULL issue, nor the length issue, but the resulting hash can contain NULL bytes, and base64 encoded data never contains NULL bytes, and i thought the resulting 44 bytes string would be a great key for bcrypt...?

$\endgroup$
6
  • $\begingroup$ So... your password can contain NULL bytes? Doesn't it make it key then? Also, 72 bytes is limitation of bcrypt AFAIK. $\endgroup$
    – axapaxa
    Commented Oct 25, 2016 at 16:27
  • $\begingroup$ my passwords can contain NULL bytes indeed, and its still the password. some user accounts may be created by computers, which may just use /dev/urandom to create a secure "password" for its own use, and i dont want those accounts to inadvertently have a very weak password (like a NULL byte) because i used bcrypt $\endgroup$
    – hanshenrik
    Commented Oct 25, 2016 at 16:29
  • $\begingroup$ You can quickly run in trouble with such approach, as web browsers and HTTP expects text to be text, in UTF-8 or other format. raw byte stream isn't such thing. Instead of blocking weird bytes, you decrease entropy for everyone, meanwhile using text-meant-controls to transmit raw bytes. You will run into trouble quicker or slower with this. $\endgroup$
    – axapaxa
    Commented Oct 25, 2016 at 16:53
  • $\begingroup$ @axapaxa there's 2 ways to log in over http, a POST request, with either multipart/form-data encoding, or application/x-www-form-urlencoded encoding , and they're both perfectly capable of encoding and transmitting binary data. i don't expect normal USERS to have binary passwords, i'm merely accounting for the fact that computer-generated accounts may have binary passwords. $\endgroup$
    – hanshenrik
    Commented Oct 25, 2016 at 17:06
  • 1
    $\begingroup$ IMO it's fine and it's pretty much what I'd do myself (I prefer hex for the simplicity and side-channel resistance). $\endgroup$ Commented Oct 25, 2016 at 18:45

1 Answer 1

2
$\begingroup$

I am hesitant to say that this is "okay" because it probably is from a strictly cryptographic point of view, because if I do you will stop reading and go with your solution. Some thoughts:

In the word "password" there's the word "word". Passwords are meant to be typed in by humans, therefore they must at least be printable, therefore ASCII control characters are to be avoided.

If you need automatic accounts to log in (legitimate "bots") then they should not have passwords, instead you should provide an authentication API with an access token and a secret key, that the bot can use to make API calls to do whatever it needs to do on your application. This is the industry standard and you would do well to follow it instead of creating ad-hoc binary password schemes.

Generally it is good practice to separate human users and automated scripts/bots, even if just for auditing purposes.

So, in short:

  • don't give automatic accounts passwords, give them API keys that can easily be tracked and revoked; bots are not humans, they do not behave like humans, and they cannot be treated as humans; treating them the same in your authentication logic is a severe category error;
  • do validate passwords entered by the user, and accept general UTF-8 characters, but reject obviously invalid characters (control characters), for anything else let users sort themselves out with the "forgot password" feature if they mess up;
  • in the future, don't work around ridiculous implementation bugs (such as your bcrypt function not accepting null bytes) by modifying your fundamental design and core application assumptions; fix your implementation instead!!
$\endgroup$
2
  • $\begingroup$ Even if you don't care about the null bytes, there is still the length limitation of bcrypt. Passphrases are a thing. $\endgroup$ Commented Oct 25, 2016 at 18:46
  • $\begingroup$ @CodesInChaos Agreed, I am not saying to use bcrypt on user input directly, I am more arguing that the whole idea of "computer passwords" is an X-Y problem. Although granted my answer would fit better on security.se. $\endgroup$
    – Thomas
    Commented Oct 25, 2016 at 18:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.