Skip to content

crypto/x509: use truncated SHA-256 for SubjectKeyId #71746

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

Open
FiloSottile opened this issue Feb 14, 2025 · 2 comments
Open

crypto/x509: use truncated SHA-256 for SubjectKeyId #71746

FiloSottile opened this issue Feb 14, 2025 · 2 comments
Labels
NeedsFix The path to resolution is known, but the work has not been done.
Milestone

Comments

@FiloSottile
Copy link
Contributor

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.

@FiloSottile FiloSottile added Proposal Proposal-Crypto Proposal related to crypto packages or other security issues labels Feb 14, 2025
@gopherbot gopherbot added this to the Proposal milestone Feb 14, 2025
@jcjones
Copy link

jcjones commented Feb 14, 2025

The most significant danger for this change is compatibility with external tools that make assumptions about SKID being SHA-1. We've seen that periodically in the Let's Encrypt community forums, with tooling either:

  1. Assuming that a SKID in a CSR would be copied to the final certificate (which has never been true for us, it merely looked true), or
  2. Breaking because it expected to independently derive the same SKID string.

Neither case has been very common, and the semantics of RFC 5280 are clearly in favor of it being treated as an opaque string.

I think your proposal to use a truncated SHA-256 is a good one.

@rolandshoemaker
Copy link
Member

I'm going to bump this out of the proposal process, since this is an undocumented implementation detail, and should not need a formal proposal. We've previously made changes to this particular behavior without proposals, e.g. see https://go.dev/issue/39429.

It seems plausible that this may break some tooling which assumes the way the SKID is generated, but those things are acting inappropriately, since an external consumer should not be making any assumptions about the format of the SKID, as @jcjones says it's intended to be entirely opaque, with RFC 5280 Section 4.2.1.2 being merely a suggestion.

Let's do it and see what breaks.

@rolandshoemaker rolandshoemaker changed the title proposal: crypto/x509: use truncated SHA-256 for SubjectKeyId crypto/x509: use truncated SHA-256 for SubjectKeyId Mar 19, 2025
@rolandshoemaker rolandshoemaker modified the milestones: Proposal, Go1.25 Mar 19, 2025
@rolandshoemaker rolandshoemaker added NeedsFix The path to resolution is known, but the work has not been done. and removed Proposal Proposal-Crypto Proposal related to crypto packages or other security issues labels Mar 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
NeedsFix The path to resolution is known, but the work has not been done.
Projects
None yet
Development

No branches or pull requests

4 participants