0
$\begingroup$

On my website I display an image. To generate this image, it require a string parameters. For example the string 1234,2423,1231 as the parameter.

Anyone can use my API (no authentication required). For example example.com/generate?param=1234,2423,1231. That is how my API works right now. To generate a different image, all you have to do is provide different numbers and different amount of numbers, like 2342,2423,234.

However, I do not want people to be able to keep generating images by themselves by simply changing the numbers. So if I encrpyt the parameter and then let the user load the image, they would never know how to generate an image themselves. So an example of an encrypted API request would be example.com/generate?param=s97dgfubYVd80fzhgdfufg0894rf which would correspond to example.com/generate?param=1234,2423,1231.

The add on to this problem is, I tell the user "we are going to generate an image with the parameters 1234,2423,1231. Here is the API link to generate this image: example.com/generate?param=s97dgfubYVd80fzhgdfufg0894rf".

So what encryption method can I use.

$\endgroup$
8
  • $\begingroup$ Does not having the key count as "not know how"? It sounds like you're asking for a cipher resistant to known plaintext attacks. Try aes $\endgroup$
    – Marc
    Aug 31 '20 at 5:37
  • $\begingroup$ @Marc The public has LOTS of encrypted strings and their corresponding decrypted string. But the basis of this question is the public can never know how I am encrypting and decrypting strings. I just want them to be able to see both the encrypted and its corresponding decrypted strings. $\endgroup$
    – James
    Aug 31 '20 at 5:40
  • $\begingroup$ @Marc So essentially, if I gave the public an encrypted string and told them to decrypt it, they wouldn't know how. Same with, if I gave the public a decrypted string and told them, encrypt the string, they wouldn't know how. $\endgroup$
    – James
    Aug 31 '20 at 5:41
  • $\begingroup$ To correctly encrypt/decrypt, they would need the key. The question is: can someone figure out the key from the plaintext and the ciphertext. This is a known plaintext attack which AES is resistant to. $\endgroup$
    – Marc
    Aug 31 '20 at 5:43
  • $\begingroup$ @Marc The user doesn't need to encrypt or decrpyt anything. I give them both encrypted & decrypted strings. Thus they don't need the key. I give them both the encrypted string and the decrypted string. That is it. I have an unauthenticated API which requires some parameters. I give the user both the encrypted parameter and the decrypted parameter. The API is visible to the public but I don't want anyone using my API unless without my permission. Thus, the parameters are encrypted. If the parameters are successfully decrypted on my end, then I process the request. If they are not, I ignore it. $\endgroup$
    – James
    Aug 31 '20 at 5:49
1
$\begingroup$

If I understand your question correctly, I (the user) know the image s97dgfubYVd80fzhgdfufg0894rf was generated from the string 1234,2423,1231, but I should not be able to craft another valid parameter.

On the server side, you need to turn the parameter back into 1234,2423,1231.

You have two basic options (and likely more):

  1. with a database available on the backend: just generate a UUID and have a database entry matching 1234,2423,1231 with the image UUID.
  2. without per-image DB entries: encrypt the string with authenticated encryption to provide privacy and data integrity

The former is simple but at the cost of storage. The second means being very careful with how you handle the keys, IVs, and authentication tag sizes.

One algorithm you can use is AES-GCM which provides the following:

  • given a string, the user cannot generate the corresponding parameter (that's the AES part)
  • the user cannot generate a random parameter and have it decrypt into a valid string (that's the GCM part)

You seem to only be asking for the first part but the second part is equally important or users could be DOSing your service by submitting random parameters.

It doesn't have to be AES, any modern authenticated encryption mechanism that works for the data sizes you are talking about will be acceptable.

$\endgroup$
2
  • $\begingroup$ You understood the question correctly. I knew the database option was a route but I didn't like the fact I would have to store things. Well I thought if I decrypt a string and it isn't in the format of [number], [number], ..., [number] or if there are more than 20 numbers, then I ignore the request. I am sort of new to cryptography, how do you combine 2 encryption things together $\endgroup$
    – James
    Aug 31 '20 at 6:30
  • $\begingroup$ You don't, you use a library that has aes-gcm and use it, every language has one. But be very very careful about using it properly. For your use case, this seems entirely overkill, a database (or anything else) to lookup mages will be a lot simpler and safer. Key/IV management is not a trivial thing. $\endgroup$
    – Marc
    Aug 31 '20 at 6:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.