Search code examples
reactjsencryptionencryption-asymmetric

How to store secret and iv securely for body encryption?


I was trying to make body encryption using AES encryption in react.js. I was keeping secret and iv in .env but security guys found them and said its insecure. My senior decided to make few changes. Firstly, I create secret and iv randomly when user logged in. Then, I encrypt secret and iv by rsa using public key which is returned when user logged in. Then we send the encrypted secret and iv to backend and the keys are ready to use.

The problem is because I create secret and iv randomly, I need to store them somewhere, but I cannot because of the security issues. So, I decided to create secret and iv by SHA256 encryption using my access_token. Now, I do not need to store secret and iv because i have my access_token in localStorage and I know how to obtain the secret and iv.

My senior says its not secure because security guys also can find how I create my secret and iv. I am stuck and I do not how to make it. I need your helps


Solution

  • I was trying to make body encryption using AES encryption in react.js.

    I'll admit I can't think of a good reason for doing this, but browsers do support it, so go on...

    I was keeping secret and iv in .env but security guys found them and said its insecure.

    That's correct. Your .env file is wide-open to the world. Even if your SPA is bundled-and-tree-shaken-not-stirred anything inside .env that's referenced will exist in the final output in some form and can therefore be extracted.

    Firstly, I create secret and iv randomly when user logged in.

    Those values are still accessible to anyone with even a modicum of familiarity with their browser's console or JS debugger - or a browser-extension.

    Then, I encrypt secret and iv by rsa using public key which is returned when user logged in. Then we send the encrypted secret and iv to backend and the keys are ready to use.

    ...why not just use that RSA public-key to perform the encryption you originally wanted to perform anyway?

    The problem is because I create secret and iv randomly, I need to store them somewhere, but I cannot because of the security issues.

    That's right. SPAs - or any JS in the browser - has no way of securely storing secrets, keys, tokens, etc. That's why OAuth2+OIDC consider SPAs "non-confidential" and why implicit auth is gone in OAuth2.1.

    So, I decided to create secret and iv by SHA256 encryption using my access_token. Now, I do not need to store secret and iv because i have my access_token in localStorage and I know how to obtain the secret and iv.

    On the contrary:

    • Your access_token is not being stored securely, and, in-fact, is very vulnerable to exfiltration via XSS or even a benign-looking javascript: bookmarklet; let alone the usual suspects like native/on-device spyware, dodgy browser-extensions, scummy ad-networks, and worse.
    • And uncovering your technique for key-derivation is straightforward: thanks to prettified JS reconstruction in all major browsers' devtools it won't be hard to how your SHA256-based KDF works, which means anyone who captured your access_token can also trivially replicate your AES key.

    My senior says its not secure because security guys also can find how I create my secret and iv.

    Your senior is correct.

    I am stuck and I do not how to make it. I need your helps

    You can't.

    Granted, there are alternatives and workarounds - but they all involve stepping outside of the JS SPA world; such as having a "trusted" localhost web-server, or using (non-JS-accessible) browser HTTP-only Cookies with the "backend-for-frontend" proxy pattern, or even browser-mediated client-side certificates (which honestly might be the best approach here - provided it suits your use-case).

    ...but considering your "use-case" is this:

    For instance, a user can see the body of a request. They can change the "id" and change some other user's information. To prevent this, we need the body encryption

    ...then I'm hesitant to make any concrete suggestions because that is not a use-case at all.