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

adds sha512 hash functions but does not convert raw password implemen… #2218

Closed
wants to merge 3 commits into from

Conversation

fmoor
Copy link

@fmoor fmoor commented Jun 3, 2016

Description:
adds hash string parsing and password salting and hashing functions, but does not change current raw password string implementation to use hashes. Conversion is left to someone with a much better understanding of the ways that home-assistant uses passwords. (this may be me in the future if no one else gets to it first...)

Related issue (if applicable):
pivotal story: www.pivotaltracker.com/story/show/115886789

Pull request in home-assistant.io with documentation (if applicable): home-assistant/home-assistant.io#

Example entry for configuration.yaml (if applicable):

Checklist:

If user exposed functionality or configuration variables are added/changed:

If code communicates with devices:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • New dependencies have been added to the REQUIREMENTS variable (example).
  • New dependencies are only imported inside functions that use them (example).
  • New dependencies have been added to requirements_all.txt by running script/gen_requirements_all.py.
  • New files were added to .coveragerc.

If the code does not interact with devices:

  • Local tests with tox run successfully. Your PR cannot be merged unless tests pass
  • [x ] Tests have been added to verify that the new code works.

…tation to salted hash

@@ -45,6 +51,54 @@
}, extra=vol.ALLOW_EXTRA)


def collect_hash(config):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

farcy v1.1

  • D400: First line should end with a period (not 'n')

fmoor added 2 commits June 2, 2016 22:52
Conflicts:
	homeassistant/components/http.py
	tests/components/test_http.py
@JshWright
Copy link
Contributor

A single round of SHA512 doesn't buy you much. Python has a kdf in the stdlib; it would be better to use that.

https://docs.python.org/3.4/library/hashlib.html#key-derivation

@JshWright
Copy link
Contributor

I'm not altogether clear what the goal of this PR is...

@fmoor
Copy link
Author

fmoor commented Jun 3, 2016

I was working with @rmkraus yesterday on www.pivotaltracker.com/story/show/115886789 and I wanted to make the progress (if you can call it that) that I made available to others.

or
None if password or hash are not configured
"""
if CONF_API_HASH in config:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally speaking, you'll want to collect all information out of the config in one location. Ideally, this function would have inputs of config_hash and config_password, or something along those lines.

Especially when config options change, it can be troublesome to have the parsing of the config data spread throughout the code.

@rmkraus
Copy link
Contributor

rmkraus commented Jun 4, 2016

@JshWright
The end goal from this is to have the API password be specified as a salted hash rather than a plaintext password. The format used to provide this salted hash should be identical to the format used by *nix systems, like in /etc/shadow files.

@fmoor
Looks good so far. I just had a couple of comments. Once these functions are done, the next step would be to get the server to salt and hash the passwords it is passed and compare them to the hashed password.

@JshWright
Copy link
Contributor

@rmkraus To what end? If the goal is to protect the password in the event the config file in compromised, this is a very tiny improvement...

A single round of SHA512 is meaningless in terms of protecting the password. A modern computer could run through billions of hashes per second.

Additionally, there are already a ton of secrets stored in the config file (various API keys, passwords, etc). I don't think protecting this single password is much of an advantage.

A final consideration... the embedded MQTT server also uses the API password, so it can't go away entirely without migrating that to its own password configuration.

@rmkraus
Copy link
Contributor

rmkraus commented Jun 4, 2016

About multiple rounds of hashing, you're definitely correct. The idea here is to help build things up incrementally while assisting in code review. It is not a finished PR yet.

There are other secrets and not a whole lot that can be done about that outside of encrypting the entire config file and decrypting it at runtime with a known key from the user. I know other options are being discussed too. Like now the yaml files can source environment variables which allows passwords to be pushed to the init script rather than the config file.

The breaking change to the MQTT implementation has been discussed, albeit not on GitHub, and a workaround should be viable. It just hasn't been approached yet in this PR.

alpha_numeric = string.ascii_letters + string.digits
salt = ''.join(random.sample(alpha_numeric, SALT_LENGTH))
assert '$' not in salt, 'salt contains "$"'
hasher = hashlib.sha512()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This algorithm can probably be simplified by using the crypt module. Additionally, other hashes would be automatically supported. Check out this article for an example.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's driving the crypt requirement?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry, I'm not sure I understand the context of your question.

What is driving the requirement to use the crypt module, what is driving the requirement to encrypt passwords at all, what is driving the requirement to encrypt password in this way, or something else that I haven't considered?

Copy link
Contributor

@JshWright JshWright Jun 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm referring to the apparent implicit requirement for crypt(3) compatible hash functions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, gotcha.

Well, no matter how we handle hashing, we will require an external library. I could very well be wrong about this, but I believe all of the hashing in Python is done with an external library. Given that, I think a dependency on Python being compiled with the crypt library is, at least, as reasonable as any other.

Open for discussion though.

Copy link
Contributor

@rmkraus rmkraus Jun 4, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JshWright has pointed me towards a much better function to use for generating the hash via Gitter. Check it out here. It will handle things like iterating through the hash. Thanks to him for pointing it out, I was not previously familiar with this function.

100,000 iterations of the sha-512 algorithm should suffice for our purposes.

@kellerza
Copy link
Member

Is the idea to hash the password for http in the config, or to hash between the server and browser?

If its to protect configuration.yaml, in #2262 I proposed a way to split secrets and store it using one of two methods, hashing could potentially be added as an option the method 1 there, since it can then cover any secret.

The catch would just be to save those hash password (same problem as I'd have for the second method), or do you have a way to generate hashed entries for the config?

@fabaff
Copy link
Member

fabaff commented Jul 2, 2016

#2312 adds keyring support (beside outsourcing values in a separate file) which enables one to store passwords, API keys, tokens, and user names in a secure place without worrying about leaking them if your configuration.yaml is lost.

@balloob
Copy link
Member

balloob commented Jul 13, 2016

I'll close this PR. It seems that with the new keyring support, there is no longer a real need for this.

@balloob balloob closed this Jul 13, 2016
@home-assistant home-assistant locked and limited conversation to collaborators Mar 17, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants