Background
When template.SubjectKeyId is empty and template.IsCA is true, CreateCertificate fills it in as the sha1.Sum of the raw public key (without the SubjectPublicKeyInfo algorithm metadata).
This is documented in the CreateCertificate docs as
If SubjectKeyId from template is empty and the template is a CA, SubjectKeyId will be generated from the hash of the public key.
and in an internal comment as
// SubjectKeyId generated using method 1 in RFC 5280, Section 4.2.1.2:
// (1) The keyIdentifier is composed of the 160-bit SHA-1 hash of the
// value of the BIT STRING subjectPublicKey (excluding the tag,
// length, and number of unused bits).
That part of RFC 5280, Section 4.2.1.2 is a SHOULD, and says that other methods are allowed.
RFC 7093 specifies four additional methods: the first 160 bits of the SHA-256, SHA-384, or SHA-512 of the same raw public key, or an unspecified hash of the SubjectPublicKeyInfo.
Let's Encrypt moved to truncated SHA-256 of the raw public key one year ago.
Generally, the SubjectKeyId is an opaque string.
Using SHA-1 is currently panic'ing in fips140=only mode. This can be worked around by specifying an explicit template.SubjectKeyId but the hash input is not trivial to compute for an application.
Proposal
Switch to using the first 160 bits of the SHA-256 of the raw public key. (Hashing the whole SubjectPublicKeyInfo is appealing, but ultimately this field has no security relevance, and we might as well align with Let's Encrypt.)
The behavior can be reverted with GODEBUG=x509sha256skid=0.
I don't think we ever promised the CreateCertificate output to be stable, but I can imagine one risk of this change being applications that regenerate a certificate instead of storing it and expect it to have the same SKID.
Alternatively, we can use SHA-256 only in FIPS 140-3 mode, but that might be even more confusing, and we tried to keep the behavior divergence at a minimum.
Background
When
template.SubjectKeyIdis empty andtemplate.IsCAis true,CreateCertificatefills it in as thesha1.Sumof the raw public key (without the SubjectPublicKeyInfo algorithm metadata).This is documented in the
CreateCertificatedocs asand in an internal comment as
That part of RFC 5280, Section 4.2.1.2 is a SHOULD, and says that other methods are allowed.
RFC 7093 specifies four additional methods: the first 160 bits of the SHA-256, SHA-384, or SHA-512 of the same raw public key, or an unspecified hash of the SubjectPublicKeyInfo.
Let's Encrypt moved to truncated SHA-256 of the raw public key one year ago.
Generally, the SubjectKeyId is an opaque string.
Using SHA-1 is currently panic'ing in
fips140=onlymode. This can be worked around by specifying an explicittemplate.SubjectKeyIdbut the hash input is not trivial to compute for an application.Proposal
Switch to using the first 160 bits of the SHA-256 of the raw public key. (Hashing the whole SubjectPublicKeyInfo is appealing, but ultimately this field has no security relevance, and we might as well align with Let's Encrypt.)
The behavior can be reverted with
GODEBUG=x509sha256skid=0.I don't think we ever promised the CreateCertificate output to be stable, but I can imagine one risk of this change being applications that regenerate a certificate instead of storing it and expect it to have the same SKID.
Alternatively, we can use SHA-256 only in FIPS 140-3 mode, but that might be even more confusing, and we tried to keep the behavior divergence at a minimum.