1

I recently wrote out a small javascript library that allows you to verify identity server password hashes in nodeJS. While I was doing the research I learnt that the type of hash, iterations and salt length is encoded by adding extra bytes to the final hash that is given in base64 afterwards.

Specifically the order is always the same and by reading the initial 25 bytes of data you learn everything about how the Subkey was encoded. Here's an example including the insertion example.

this.writeNetworkByteOrder(outputBytes, 1, 1);
this.writeNetworkByteOrder(outputBytes, 5, 10000);
this.writeNetworkByteOrder(outputBytes, 9, salt.length);

function() writeNetworkByteOrder(buffer, offset, value){
            buffer[offset + 0] = value >> 0;
            buffer[offset + 1] = value >> 8;
            buffer[offset + 2] = value >> 16;
            buffer[offset + 3] = value >> 24;
}

Is this common practice? Should I try and avoid using the default password hasher provided with identity server? How much is given away by knowing this information?


Why this isn't a duplicate

My question is specifically about the encoding that happens on the resulting hash. This is the base64 hash that is the result of the identity server operation. Providing you know the hash is base64 you can readily read the encryption type, iterations and salt length directly from it. I want to know how or if this is safe and if it's considered good security practice.

li x
  • 462
  • 4
  • 11
  • 1
    What are "identity server password hashes"? All I could find is [this](https://github.com/IdentityServer/IdentityServer4) which doesn't appear to hash passwords. – AndrolGenhald Apr 17 '18 at 15:43
  • @AndrolGenhald Identity server is how .net core api's handle authentication – li x Apr 18 '18 at 07:34
  • Aha, [this](https://github.com/aspnet/Identity/blob/85f8a49aef68bf9763cd9854ce1dd4a26a7c5d3c/src/Core/PasswordHasher.cs#L139) appears to be what you're talking about. It's using PBKDF2 with 10,000 iterations by default (which seems a bit low, but that's a separate question). – AndrolGenhald Apr 18 '18 at 13:35
  • 1
    Possible duplicate of [When hashing passwords, is it okay to store the algorithm used right there in the database?](https://security.stackexchange.com/questions/29414/when-hashing-passwords-is-it-okay-to-store-the-algorithm-used-right-there-in-th) – AndrolGenhald Apr 18 '18 at 13:35
  • @AndrolGenhald There's a difference to the question you flagged, the algorithm type, iterations and salt length are encoded directly inside every hash as well part of it alongside a subkey. – li x Apr 18 '18 at 13:50
  • Sorry, I overlooked that you were wondering about the salt as well. [This](https://security.stackexchange.com/q/17421) should answer that. – AndrolGenhald Apr 18 '18 at 13:57
  • I think your misunderstanding my question, this is creating a subkey using PBKDF2 correct, but that is only the subkey. After we've generated that hash we store it as part of a buffer of which the first inital 26 bytes also includes information about the inital encoding before it's turned into base64. Those questions don't answer the security implications of embedding details directly into the output base64 hash. – li x Apr 18 '18 at 14:00
  • Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/76214/discussion-between-li-x-and-androlgenhald). – li x Apr 18 '18 at 14:07

1 Answers1

2

TL;DR yes, when it comes to protecting the password on the server it is secure to store the configuration parameters such as iteration count and salt / salt size on the server. As mentioned in the chat session, it is common to do so for e.g. bcrypt, using a different textual format.


The question is if it is secure to store the configuration parameters of the algorithm, not just the algorithm. And yes, this is secure. The configuration parameters do not give any information on the used password, so storing them with the salt (and possibly password hash, for password verification) doesn't leak any confidential information to an attacker.

And just like the Kerckhoffs principle applies to the algorithm, it is also valid for these kind of configuration parameters. Fortunately, if these parameters are changed then the password verification will simply fail.

Base 64 encoding doesn't play a role in determining the security so it is left out of this answer.


For other functions / configuration parameters the parameter may need additional protection. For instance the size of an authentication tag in authenticated encryption (or simple HMAC) should not be altered by an adversary. This could be an issue in protocol negotiation.

Similarly if the iteration count / work factor is communicated to a client (for partial offloading of the work, for instance) then you may want to protect the iteration count against change. But these kind of parameters are generally just available on the server and passwords / hashes send are generally protected by a TLS connection which you should be using.


Personally I prefer simply storing a single version instead of the explicit parameters. The parameters are then specific to a version (hardcoded), so I don't have to parse / validate any information other than the version. This is less dynamic than storing them separately but often complexity is as much an problem as rigidness.

Maarten Bodewes
  • 4,602
  • 15
  • 29
  • It took me a while, but I did eventually figure out that you've properly interpreted the question right. +1 just for figuring out the question. – Steve Sether Apr 25 '18 at 19:12
  • Thank you this explains what I was wondering completely. – li x Apr 26 '18 at 07:28