0

In my system I'm generating URLs with query params that represent IDs. I want to encrypt these IDs so that they are not plainly manipulated in the URL. These will be public facing URLs and I don't want users to be able to manipulate the URL and be able to get other users' data, so I want to encrypt these IDs.

I'll be encrypting the IDs within a Java application and then decrypting them in a Javascript app. Is there some common encryption algorithm I can use in both places? Are there libraries available that would do this sort of thing in Java and Javascript?

I realize both my application will need access to a common "password" or decryption key, I will store this in a keystore location that both apps will have access to.

5
  • By public facing, do you mean that the page could actually be opened by unlogged users, and it should work this way ? Commented Sep 10, 2020 at 18:12
  • Manipulated how? You're using contiguous integer IDs, and you don't want someone to go from shop.com/product/1 to shop.com/product/2 by just incrementing the number? Better yet, don't use contiguous integer IDs in the first place Commented Sep 10, 2020 at 18:13
  • @Michael yes, that is what I mean. They're not contiguous integers, they're strings, but the same concept applies. I can't really change that part of the design. Commented Sep 10, 2020 at 18:25
  • @FTW yes, you do not need to log in to access the page Commented Sep 10, 2020 at 18:26
  • You may not have to encrypt the query parameters. Use a server side HMAC to authenticate that critical query values have not been tampered with. You would not need to add anything client side. Commented Sep 10, 2020 at 18:34

2 Answers 2

1

IMO you should generate a public/private key by your own then (OpenSSL, Java keytool...).

  1. Using javascript to encrypt your data with the public key
  1. On Server-side - Java, you can use the private key to decrypt your data to execute your business behaviour. There are many examples/library to decrypt by the private key such as

You're should read how the RSA algorithm to understand more how it works. Basically you need to encrypt data by your public key (front end part) and decrypt (backend part)by your private key that it.

Not recommend: If you're still wanna decrypt on front-end side via javascript, mean that you have to public your private key where javascript can read to decrypt. Technically is fine but It may have a security issue

Another solution:

  • You can encrypt your data like (Id, secret_data.....) into an encrypted string then send that string as a parameter of an URL (generate at server-side)
  • When end-user clicks that URL you will decrypt parameter by private key (server-side) to get actual data (Id, secret_data...)
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks. I'm actually generating the URLs in the Java code so that's where the encryption is happening, and it will be decrypted in some backend Javascript code. I imagine the same concept applies though?
Yes, but should not decrypt at the front end side. If you send your URL to somewhere why not send like domain.abc?query=<encrypted_data> - One end-user click your link, you can decrypt at backend side, so basically end user cannot see you actual data, cannot collect some sensitive data which you don't wanna to share
If you're using some server rendering like React, VueJS and Angular. I think there's no problem when u put the private key on that, then you can easy to decrypt your data without security issues
Yeah ok, that's the plan. This all seems a bit over compllicated for what I'm trying to do though. I was envisioning just doing something like myCryptoLib.encrypt(encryptionKey, value) and then on the other side doing myCryptoLib.decrypt(encryptionKey, encryptedValue)
As I said, technically is fine, but you may face security issues, or you can minimize your secret js file, so nobody can see the source code <private key or secret string), That can consider as a workaround if you already have a plan to use SPA
|
0

Unless your values actually need to be secret use an HMAC. This way you can authenticate that url provided has not been tampered with without actually having to share keys or require that the client decrypt data on its own.

Simply generate an hmac for your desired critical values and append the value to the url. When they user accesses the specific path, read the url and compare it to the hmac.

url = 'http://my.site/users/123
signature = hmac(secret_key, url);
signed_url = url.addQueryValue('s', signature);

on the way in, look at the signature and validate it matches the regenerated hmac.

Other things you can do is append claims to the signature such as expiry ect. Claims can be used to track access, as well as revoke access to a url after some time.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.