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

Is there protection against brute force attacks? #1

Open
cktang88 opened this issue May 20, 2020 · 10 comments
Open

Is there protection against brute force attacks? #1

cktang88 opened this issue May 20, 2020 · 10 comments

Comments

@cktang88
Copy link

For example, a potential attacker could potentially keep on guessing a password many times via brute-force until the link unlocks.

@jstrieb
Copy link
Owner

jstrieb commented May 21, 2020

Thanks for taking a look at the project! Theoretically, that is absolutely possible! Unfortunately, I am not aware of anything I can realistically do to protect against it. For example, given that all encryption and decryption is done client-side, I could not effectively perform rate-limiting.

Out of curiosity, I wrote a quick brute-force tool to try it out. While I know that nobody would actually ever brute-force anything too seriously in their browser, I coded up a web-based brute-forcer that will attempt to decrypt locked URLs by trying all combinations of characters in a user-submitted charset. I made a browser-based implementation simply because I could directly import the APIs I'd already written for the main project.

You can try my brute-forcer here. The code for it is here if you would like to modify it. I have included a link to my brute-force application below. In practice, using this very naive implementation of brute force, it turns out that even relatively short passwords with limited character sets take a very long time to crack! For me it tests about 22 passwords per second.

In the meantime, I will leave this issue open in case others have ideas for how to protect against this.

@jstrieb
Copy link
Owner

jstrieb commented May 22, 2020

In the spirit of openly discussing this issue, I have added the code to brute force locked links directly to the main repository. Users can attempt a brute force in their browser here:

https://jstrieb.github.io/link-lock/bruteforce/

@jstrieb jstrieb pinned this issue Aug 7, 2020
@yogsototh
Copy link

A solution is to use scrypt or bcrypt instead of directly AES.

So you can provide complexity parameters that will make very hard for an attacker to brute force the password.

@jstrieb
Copy link
Owner

jstrieb commented Aug 8, 2020

A solution is to use scrypt or bcrypt instead of directly AES.

Since a user with the password must be able to recover the original URL, I need the encryption to be symmetric, and cannot use a hashing algorithm for this. Thus, I wouldn't actually be able to replace AES with bcrypt or scrypt. I could potentially use those hash functions in place of SHA-256 for secure key derivation, but unfortunately neither algorithm seems to be available in the SubtleCrypto API.

@jstrieb
Copy link
Owner

jstrieb commented Apr 29, 2021

As a fun project while learning Go, I wrote a cross-platform, command-line application to brute force Link Lock URLs. It parallelizes on as many CPU cores as possible. Find it here:
https://github.com/jstrieb/bruteforce-link-lock

Interestingly, while profiling this code, I discovered that (perhaps unsurprisingly) the bottleneck for each attempt is the 100,000 iterations of SHA256 used for PBKDF2 key derivation. What did surprise me is that the Go code's rate of attempts per second per thread does not seem to be significantly better than the browser (both between 15 and 20 password attempts per second), so the only benefit of this new code over the browser-based brute force tool is parallelizing across CPU cores. Turns out the SubtleCrypto API is pretty fast!

@PrinceOfParallax
Copy link

Not seeing that work right the - I have roughly 52 threads and its only running on one.

@cool-dev-guy
Copy link

hey @jstrieb i have a question about where the password is being stored in the client side?(is it inside the url itself)?

@jstrieb
Copy link
Owner

jstrieb commented Sep 11, 2023

hey @jstrieb i have a question about where the password is being stored in the client side?(is it inside the url itself)?

Hi @cool-dev-guy! The password is not stored at all. Only encrypted data is stored. And all of the encrypted data is stored in the URL.

To give a concrete example, here is the structure extracted from one of the example URLs in the README.

jacob@jacob:~$ echo "https://jstrieb.github.io/link-lock/#eyJ2IjoiMC4wLjEiLCJlIjoiZEx3Yi9CNitlK0ZjM1B3ZURrbUY2NjdQWFlIV1dsS3dpclhvZmkvRXBFTXU0ZERlVkJuSmUrN1loS2JxQ3RrPSIsImgiOiIxICsgMSA9ID8iLCJpIjoiRDJYd1MyK1EzaHpuUDV1NyJ9" \ 
  | sed 's/.*#\(.*\)/\1/g' \
  | base64 -d - \
  | jq
{
  "v": "0.0.1",
  "e": "dLwb/B6+e+Fc3PweDkmF667PXYHWWlKwirXofi/EpEMu4dDeVBnJe+7YhKbqCtk=",
  "h": "1 + 1 = ?",
  "i": "D2XwS2+Q3hznP5u7"
}

Within this extracted JSON structure:

  • v is the API version
  • e is the base64-encoded, encrypted bytes
  • h is the (optional) password hint
  • i is the Initialization Vector (IV) for AES-GCM

The password itself is not stored in here, but all of the encrypted data is entirely in the URL. If we go one step further and try to inspect the encrypted data, we'll see that it doesn't have any structure itself, and is just gibberish bytes.

jacob@jacob:~$ echo "https://jstrieb.github.io/link-lock/#eyJ2IjoiMC4wLjEiLCJlIjoiZEx3Yi9CNitlK0ZjM1B3ZURrbUY2NjdQWFlIV1dsS3dpclhvZmkvRXBFTXU0ZERlVkJuSmUrN1loS2JxQ3RrPSIsImgiOiIxICsgMSA9ID8iLCJpIjoiRDJYd1MyK1EzaHpuUDV1NyJ9" \
  | sed 's/.*#\(.*\)/\1/g' \
  | base64 -d - \
  | jq --raw-output .e \
  | base64 -d - \
  | xxd -
00000000: 74bc 1bfc 1ebe 7be1 5cdc fc1e 0e49 85eb  t.....{.\....I..
00000010: aecf 5d81 d65a 52b0 8ab5 e87e 2fc4 a443  ..]..ZR....~/..C
00000020: 2ee1 d0de 5419 c97b eed8 84a6 ea0a d9    ....T..{.......

Hopefully this answers your question!

@cool-dev-guy
Copy link

cool-dev-guy commented Sep 11, 2023

Hopefully this answers your question!

Thanks jstrieb for the answer,it really helped me.

@cool-dev-guy
Copy link

cool-dev-guy commented Sep 28, 2023

hey @jstrieb ,i have a doubt about encryption,is it possible to encrypt a string(length < 280chars) to an encrypted string of length<280 characters?

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

5 participants