[Bug]: step ca certificate <subject> cert.crt cert.key --password-file=<private-key-passphrase-file> fails with the error "failed to decrypt JWE: invalid password"
Steps to Reproduce
I'm unable to issue passphrase protected certificate with the key using step ca certificate command. If I use command like below:
step ca certificate test-cert test-cert.crt test-cert.key --password-file=test-pass where test-pass contains any string as passphrase to encrypt certificate key, the command fails with the error: failed to decrypt JWE: invalid password
Steps to reproduce:
- create password file using command:
echo "test123" > test-pass - create certificate using command
step ca certificate test-cert test-cert.crt test-cert.key --password-file=test-pass
Your Environment
- OS - Client: Ubuntu 24.04 (WSL2),
step-cliVersion:Smallstep CLI/0.27.2 (linux/amd64)step-caVersion: step-ca-hsm:latest docker image ({ "version": "0.27.2"})
Expected Behavior
- Certificate and key should be created
- Key should be encrypted by passphrase
Actual Behavior
Certificate issuance failed with the error: failed to decrypt JWE: invalid password.
This error makes me evidence that the --password-file option is the synonym of --provisioner-password-file option.
Additional Context
No response
Contributing
Vote on this issue by adding a 👍 reaction. To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).
Hey @tregubovav-dev, I know in some places we reuse the value from the --password-file for the provisioner password, if --provisioner-password-file is not set. Can you try specifying both options, with the latter set to your provisioner password?
Using both, '--password-file' and '--provisioner-password-file' generates certificate pair without error. However, generated certificate key is not encrypted.
Please see a matrix of option combination results (using kpass file as a certificate key passphrase and jpass as a JWT encryption key. These files consist of different single string):
- step ca certificate test-cert test-cert.crt test-cert.key --password-file=kpass --provisioner=test
✔ Provisioner: test (JWK) [kid: Cv_YSjKlqmvOjokVFDqLasn2hGt_TnLNEAUMvvehnBI]
failed to decrypt JWE: invalid password
Certificate enrolment failed as password is invalid - step ca certificate test-cert test-cert.crt test-cert.key --provisioner-password-file=jpass --provisioner=test
✔ Provisioner: test (JWK) [kid: Cv_YSjKlqmvOjokVFDqLasn2hGt_TnLNEAUMvvehnBI]
✔ CA: https://pki.test.tld:9000
✔ Certificate: test-cert.crt
✔ Private Key: test-cert.key
- Certificate pair is enrolled with unencrypted certificate key (ar requested)
- openssl ec -check -in test-cert.key --noout read EC key EC Key valid.
- step ca certificate test-cert test-cert.crt test-cert.key --provisioner-password-file=jpass --password-file=kpass --provisioner=test
✔ Provisioner: test (JWK) [kid: Cv_YSjKlqmvOjokVFDqLasn2hGt_TnLNEAUMvvehnBI]
✔ CA: https://pki.test.tld:9000
✔ Certificate: test-cert.crt
✔ Private Key: test-cert.key
- Certificate pair is enrolled with unencrypted certificate key. However, encrypted key has been requested,
- openssl ec -check -in test-cert.key --noout read EC key EC Key valid.
Hey @tregubovav-dev 👋. Thanks for opening the issue!
First off, our team discussed the bug report and we agree that the current behavior is confusing.
There's a few things going on here, so I'll try to do a quick summary.
- The
--password-fileflag for this command was never meant as an input for encrypting the key file. It's original use was as an input to decrypt the JWK provisioner. However, as the CLI grew we introduced more commands that required a password for encryption and decryption and the name--password-filewas too generic. Later, we introduced the flag--provisioner-password-fileexplicitly for decrypting provisioners. For backwards compatibility we alias'ed the flag--password-fileto be equivalent to--provisioner-password-file. Changing the usage for--password-filewould break backwards compatibility which is something we're very, very careful about. - There are two general methods for getting an encrypted key when generating a certificate using Step CA:
- First generate the CSR, using
step certificate create --csr --password-file <subject> <crt-file> <key-file>, then sign it withstep ca sign .... - Create the cert/key pair with
step ca certificate <subject> <crt-file> <key-file>, then usestep crypto change-pass <key-file>to encrypt the key file.
So, in terms of next steps.. Since this isn't technically a bug (closer to a feature request) and there are workarounds to achieve the same result, it's not something we have the capacity to prioritize in the short term. That said, we agree that this is confusing and we would like to change the usage and functionality of --password-file to match your expectation. As this would be a breaking change, it will need to come in a minor version release. We will add it to the roadmap for the next minor release, with the understanding that, because this is not high priority, it may get bumped to a future minor release.
Cheers 🍻
I appreciate this clarification. In reality this is minor issue and workaround exists. I agree with your decision!