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

feat(config): support modern ECDH/AES-GCM encryption #27416

Closed
wants to merge 8 commits into from

Conversation

viceice
Copy link
Member

@viceice viceice commented Feb 19, 2024

Changes

  • Add modern ECDH/AES-GCM encryption.
  • Add Docs
  • build-in function to geneate a private key
  • build-in function to encrypt a secret

Context

Documentation (please check one with an [x])

  • I have updated the documentation, or
  • No documentation update is required

How I've tested my work (please select one)

I have verified these changes via:

  • Code inspection only, or
  • Newly added/modified unit tests, or
  • No unit tests but ran on a real repository, or
  • Both unit tests + ran on a real repository

Copy link
Collaborator

@rarkins rarkins left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this support the same RSA 4096 private/public keys?

@viceice viceice added the ci:fulltest Run full test suite on all platforms label Feb 19, 2024
@viceice
Copy link
Member Author

viceice commented Feb 19, 2024

Will this support the same RSA 4096 private/public keys?

which keys? the gpg keys? no. the key derive is only possible with two ecdh keys.
but we can support rsa encryption too if you like

lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.spec.ts Show resolved Hide resolved
lib/config/decrypt.spec.ts Outdated Show resolved Hide resolved
lib/config/decrypt.ts Outdated Show resolved Hide resolved
* EC JSON Web Key (private key)
* https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/importKey#json_web_key
*/
export const EcJwkPriv = EcJwkPub.extend({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
export const EcJwkPriv = EcJwkPub.extend({
const EcJwkPriv = EcJwkPub.extend({

);

// derive shared secret from our private key and Renovate's public key
const pw = await crypto.subtle.deriveKey(
Copy link
Collaborator

@Churro Churro Feb 24, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks cryptographically problematic to me.

The shared secret derived by an ECDH key agreement is not uniformly random. deriveKey doesn't perform any key stretching or hashing on the shared secret. It is basically the same as calling deriveBits to get a byte array and then passing it to importKey to use as a symmetric key with AES. P-384 generates more output bits than needed, some part will simply be dropped to fit the 256 bits needed for AES.

To derive a cryptographically strong key for AES-GCM, the shared secret needs to be processed via HKDF. An example how to do this can be found here: https://stackoverflow.com/a/67942717/589259
Note that this example uses an empty salt. I'd say it makes sense to use a salt though, as it ensures that reusing the same shared secret for two operations will still yield different encryption keys. I'd suggest prepending it to the ciphertext.

Also see:

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 didn't know that. do we need a separate value for salt, or can we reuse the aes-gcm iv?
We should try to make the encypted object as small as possible but of cause as secure as possible.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Salt and IV are similar in some ways but also need to fulfill different requirements depending on what you want to achieve. I'd suggest to not simply reuse the same values. What you could do in this particular case:

Call deriveBits({ name: "HKDF", ... (as shown in the stackoverflow example above) and produce bits for both the key and the VI. You can use the iv (as it is currently named in your code) as a salt value for the HKDF. When calling deriveBits, increase the length param by the 96 bits you need for the IV, so 256 + 96 bits overall, then use the trailing 96 bits for the IV.

This way you don't need to prepend it to the ciphertext and the HKDF ensures it's uniformly random for use with a symmetric cipher like AES. If you change the salt, the encryption key and IV will change as well. This is generally desirable because it ensures that if you encrypt multiple texts (with different salt values in the HKDF call), a unique encryption key and IV will be used as well.

@viceice
Copy link
Member Author

viceice commented May 7, 2024

closing for now, as we've an alternate pgp implementation

@viceice viceice closed this May 7, 2024
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 7, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
ci:fulltest Run full test suite on all platforms
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Switch from openpgp to node crypto
5 participants