I have problems with my new ACME2 client. Switched key from my test key to production and now it don’t generate certificates anymore. Seems there is some issues with my private key? Since it works with the test key but not real key…
root@sebastian-desktop:/etc/nsd# ./certbot2
Creating challenge for sebbe.eu
Creating challenge for sebbe.eu
Writing challenges to zone file
Signing DNSSEC data…
Submitting challenges for validation…
Getting validation results…
Passed authorization for sebbe.eu
Passed authorization for sebbe.eu
Generating certificate…
Unable to generate certificate --> Possible failed some validation for sebbe.eu or exceeded rate limits
root@sebastian-desktop:/etc/nsd#
Net::ACME2::ACME: “https://acme-v02.api.letsencrypt.org/acme/finalize/81135719/2722922570” indicated an ACME error: 400 Bad Request (400 urn:ietf:params:acme:error:malformed (The request message was malformed) (Error finalizing order :: certificate public key must be different than account key)).
==> Net::ACME2::Generic::new(‘Net::ACME2::ACME’, ‘“https://acme-v02.api.letsencrypt.org/acme/finalize/81135719/2722922570” indicated an ACME error: 400 Bad Request (400 urn:ietf:params:acme:error:malformed (The request message was malformed) (Error finalizing order :: certificate public key must be different than account key)).’, HASH(0x557993ffcb58)) (called in /usr/local/share/perl/5.26.1/Net/ACME2/X/ACME.pm at line 31)
==> Net::ACME2::ACME::new(‘Net::ACME2::ACME’, HASH(0x557993ffcb58)) (called in /usr/local/share/perl/5.26.0/X/Tiny.pm at line 169)
==> X::Tiny::create(‘Net::ACME2::X’, ‘ACME’, HASH(0x557993ffcb58)) (called in /usr/local/share/perl/5.26.1/Net/ACME2/HTTP.pm at line 159)
==> Net::ACME2::HTTP::_request(Net::ACME2::HTTP=HASH(0x5579933193a8), ‘POST’, ‘https://acme-v02.api.letsencrypt.org/acme/finalize/81135719/2722922570’, HASH(0x557993ffc9a8), HASH(0x557993fe7640)) (called in /usr/local/share/perl/5.26.1/Net/ACME2/HTTP.pm at line 181)
==> Net::ACME2::HTTP::_request_and_set_last_nonce(Net::ACME2::HTTP=HASH(0x5579933193a8), ‘POST’, ‘https://acme-v02.api.letsencrypt.org/acme/finalize/81135719/2722922570’, HASH(0x557993ffc9a8), HASH(0x557993fe7640)) (called in /usr/local/share/perl/5.26.1/Net/ACME2/HTTP.pm at line 108)
==> Net::ACME2::HTTP::_post(Net::ACME2::HTTP=HASH(0x5579933193a8), ‘create_key_id_jws’, ‘https://acme-v02.api.letsencrypt.org/acme/finalize/81135719/2722922570’, HASH(0x557993fe8cb0)) (called in /usr/local/share/perl/5.26.1/Net/ACME2/HTTP.pm at line 88)
==> Net::ACME2::HTTP::post_key_id(Net::ACME2::HTTP=HASH(0x5579933193a8), ‘https://acme-v02.api.letsencrypt.org/acme/finalize/81135719/2722922570’, HASH(0x557993fe8cb0)) (called in /usr/local/share/perl/5.26.1/Net/ACME2.pm at line 555)
==> Net::ACME2::_post_url(Net::ACME2::LetsEncrypt=HASH(0x557992bd4f00), ‘https://acme-v02.api.letsencrypt.org/acme/finalize/81135719/2722922570’, HASH(0x557993fe8cb0)) (called in /usr/local/share/perl/5.26.1/Net/ACME2.pm at line 423)
==> Net::ACME2::finalize_order(Net::ACME2::LetsEncrypt=HASH(0x557992bd4f00), Net::ACME2::Order=HASH(0x557992d63488), '-----BEGIN CERTIFICATE REQUEST-----
MIIDPjCCAiYCAQAwga4xCzAJBgNVBAYTAlNFMQ0wCwYDVQQIDARub25lMQ0wCwYD
VQQHDARub25lMQ4wDAYDVQQRDAU0MzY0NTEdMBsGA1UECQwUSHVsdEFzZW4gMTUg
TEdIIDEwMDIxDTALBgNVBAoMBG5vbmUxDTALBgNVBAsMBG5vbmUxETAPBgNVBAMM
CHNlYmJlLmV1MSEwHwYJKoZIhvcNAQkBFhJzZWJhc3RpYW5Ac2ViYmUuZXUwggEi
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDC6rA7dp88RBatmwbj71cJmIgn
eMqDlhI+mV2DXhEUxK71Z22ZUK0MZmrVI2kszYgn0R05RhPykM3BBgH1cvdeLEg4
sAI5ZWufoGaVrwIoc9pnY4LSLSad+6C5sdr08bclNZAcfQaGsi69HfYFgNCgJAdo
2TVqLEcOIS81ftyqfn5P7Fr489NG7psHjGMJyp+aKf/Qc3CYlodYubEzrEGAFmDu
uNzGKLBlTUl8Ku+Ot0gnV+EobjTnwFzNdGSbGxRscojlfjEuKzCsI4JnpzXRCkM0
H4+Ujfd4F28CSqMcT0IE+bhfWhdebD0L9ibWJ8ZrDmFcLnm3w0rKGEECPXyrAgMB
AAGgSjBIBgkqhkiG9w0BCQ4xOzA5MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgXgMB8G
A1UdEQQYMBaCCiouc2ViYmUuZXWCCHNlYmJlLmV1MA0GCSqGSIb3DQEBCwUAA4IB
AQBilaxvefhHssi1QawFdz77XAxhlfaqqk9yc2Qk2XZmSOi6OWvceV2djV2WwSMX
neSN/uXaQVAtVfbXDIP3o0jSz+pzR4ILmZsMA2tmgdYO7ni4DL2Y44WefucbEvQF
IbyJ6iwvHLXSrBs6bC5F6TX63WCeT+hozuJfENRnpglltvczAtcvai8xX40D8VoA
YFu1Cww57bRf4BgDRQWuyh1bU6IR+PGlUfCYonw9OVsm+5a8mCUb+k/UrRFZMZoo
j4P8SdZJYNf/8ujBzElICBmkHXQdnfrdCtTFyihVDq5us7il26SpP+/pULcXWFij
3hi3wwk5cE6ogk1FPwUvbScM
-----END CERTIFICATE REQUEST-----
') (called in ./certbot2 at line 151)
OMG its that stupid limitation again… “certificate public key must be different than account key”
Tought that stupid limitation was deleted in ACME2.
Its just so arbitary… like restricting which private keys that can be used. It wouldn’t hurt security to allow account and certificate private keys to be equal.
Could understand requiring a minimum keylength, but not requiring different keys.
It's good cryptographic engineering practice to use each key for only one purpose. This mitigates a number of risks.
protocol confusion and similar oracle attacks, in which someone can trick you in the course of one protocol or application into signing data that has a different meaning in the context of another¹
target aggregation in which there is a heightened incentive to break a particular key because doing so will achieve multiple goals
target aggregation in terms of the ability to keep different keys on different devices where they're needed, so that a compromise of one device won't compromise all of the other applications (e.g. if one ACME account provisions keys for many different servers under the same domain, the ACME account key can be kept on the certificate provisioning server and the subject keys can be kept on the individual servers where they're actually used, so neither one can directly compromise the other's role!)
selective revocation of a particular credential without requiring the revocation of other credentials that use the same key
ability to choose different key types or key strengths for different applications that may have different requirements (e.g., perhaps choosing longer keys for purposes that require longer-term validity)
ergonomics about confirming that software developers and system administrators who are responsible for keys understand the nature and purpose of each one
detecting severe software bugs, such as PRNG initialization bugs, that cause the same private key to be generated repeatedly
You can read about some fairly similar considerations in
and a number of similar forum threads about PGP's use of multiple keys (signing key, encryption key, long-term identity key).
I think the intuition about keeping keys that represent different roles, capabilities, or functions separate is a powerful idea in the evolution of cryptography. It's one that's mitigated real attacks and also one that's allowed revocation of credentials to be targeted narrowly when keys are compromised or suspected to be compromised.
If you're not persuaded by these considerations, I can offer a completely different account of why this might be useful: the "brown M&M" theory.
So, when I would walk backstage, if I saw a brown M&M in that bowl … well, line-check the entire production. Guaranteed you’re going to arrive at a technical error. They didn’t read the contract. Guaranteed you’d run into a problem. Sometimes it would threaten to just destroy the whole show. Something like, literally, life-threatening.
Having specific and detailed rules may also serve as a good check that implementers are paying attention to the other rules, even when they might not understand the importance or purpose of those rules. Cryptography and PKI are so easy to get wrong and so it's worthwhile to try to make sure that people are being detail-oriented.
¹ I think this is the most fundamental cryptographic reason here. An interesting example is DROWN attack - Wikipedia and other literature on cryptographic cross-protocol attacks, but see also Related-key attack - Wikipedia for another kind of issue. A useful conclusion is that you probably don't want two different kinds of software/application/protocol implementation to have access to the same private key because an operation that can be done legitimately in one context may be usable as an oracle to attack another context.