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

Math.random() is not cryptographically secure #12

Open
hacklschorsch opened this issue Sep 7, 2021 · 2 comments
Open

Math.random() is not cryptographically secure #12

hacklschorsch opened this issue Sep 7, 2021 · 2 comments

Comments

@hacklschorsch
Copy link

Math.random() is used for cryptography, but it is not a suitable source of randomness:

cryptographic_key = cryptographic_key.concat(String.fromCharCode(Math.floor(Math.random()*26) + 65));

These two articles illustrate the problem quite well:

TIFU by using Math.random() by Mike Malone, Betable CTO, 2015-11-19

Many random number generators in use today are not very good. — Donald Knuth

The current algorithm, which appears to have been passed down from one programmer to another, is comparatively unsatisfactory (and arguably completely broken) due to subtle, non-intuitive degenerate behavior that is likely to be encountered under realistic circumstances.

and

There’s Math.random(), and then there’s Math.random() by Yang Guo, v8 Engineer at Google, 2015-12-17

For use cases such as hashing, signature generation, and encryption/decryption, ordinary PRNGs are unsuitable. The Web Cryptography API introduces window.crypto.getRandomValues, a method that returns cryptographically secure random values, at a performance cost.

I thus propose to use the Web Cryptography API instead.

klml added a commit that referenced this issue Sep 11, 2021
@klml
Copy link
Owner

klml commented Sep 11, 2021

@hacklschorsch what do you think about 74b5e1a

@hacklschorsch
Copy link
Author

Hi! Sorry for the delay, I overlooked your activity here. Even though I think invoking this API once per byte is a bit much overhead - it can yield up to 64 KB of randomness in one go - I think we shouldn't be worrying about performance yet.

More of a worry to me is this documentation on getRandomValues() on MDN:

Don't use getRandomValues() to generate encryption keys. Instead, use the generateKey() method. There are a few reasons for this; for example, getRandomValues() is not guaranteed to be running in a secure context.

There is no minimum degree of entropy mandated by the Web Cryptography specification.

Maybe you can use a key derivation function like PBKDF2 to get some more bits out of this generateKey() method and not do the whole key generation shebang for every byte?

Since I am treading on rather thin ice here - my own crypto kung foo isn't very strong - I would like refer to the warning from the beginning of the docs to the SubtleCrypto interface:

Even assuming you use the basic cryptographic functions correctly, secure key management and overall security system design are extremely hard to get right, and are generally the domain of specialist security experts.

And of course there's to note that you cannot generate a one time pad with a pseudo random number generator.

So maybe this is good as a demonstration - but it's not a real one time pad, but rather a not very efficient stream cipher?

Maybe there is some silver bullet? Quick Googling yielded this paper: Implementation of One-Time Pad Cryptography but quick skimming looks like it's all bull?

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