The key authorization file from the server did not match Root Cause

So my self written client was working, then it stopped workign with a new Account key.

The failure was :The key authorization file from the server did not match

So in hunting this down it is a problem with the key thumb print matching.
In RFC8555 we have the paragaph under 8.1
The "Thumbprint" step indicates the computation specified in [RFC7638], using the SHA-256 digest [FIPS180-4]. As noted in [RFC7518] any prepended zero octets in the fields of a JWK object MUST be stripped before doing the computation.

RFC7518 does not say that you must you must trim leading zeros in the X or Y portion of an ECDSA key. In fact in the JWK spc is says you must not....

If I trim leading zeros your system rejects the thumbprint.

If I don't trim then your system does not reject the thumbprint...
This does not seem to appear in the RFC8555 erata.

Please share some (compilable/runnable) example code, one working and one failing.

Also, I'm inclined to believe RFC8555 refers to this snippet of RFC 7518 about the RSA public key parameter "n":

Note that implementers have found that some cryptographic libraries
prefix an extra zero-valued octet to the modulus representations they
return, for instance, returning 257 octets for a 2048-bit key, rather
than 256. Implementations using such libraries will need to take
care to omit the extra octet from the base64url-encoded
representation.

RFC 8555 specifically says "prepended zero octets". It doesn't say "trim every leading zero".

4 Likes

Yeah I read that as trim ALL leading zeros, not don't include a leading zero...
So my error... but I do get the error when I trim ECDSA leading octets... so maybe its just me...
In any case my stuff is working now by deleting the leading zero trim..

1 Like

Then why do you do that? Getting an error due to something that isn't supposed to be done isn't that strange if you ask me.

4 Likes

So is that additional ZERO octets....
Or ANY leading zeros?
The X, or Y parameters' in an ECDSA public key is a fixed length fields.
That field MAY have leading zeros (not extra prepended ones, but real part of the the actual number leading zeros.)

I read that paragraph as say one must strip all leading zeros, not just the extra leading zeros...

So if I have a 4 digit number...field...
and I have the number 123...

Than can be 0123
or 123...
Note I've not added an additional number to make the 4 digit number 5 digits..

IE 00123 is clearly wrong for a 4 digit number....

but the paragraph as written makes me think I should hash 123 not 0123.

As for the number 123, 0123 has a prepended 0 even though its supposed to be a four digit number.

The spec calls for octets, not characters.

What language and library are you using to generate the thumbprint? All of this stuff is usually handled in the core libraries that handle JWK computation, and an ACME client will not have to touch it.

4 Likes

Concept is idential...
IE I was illustrating with chars.. but the concept is the same of numbers that are strings of octets...

IE the ECDSA X parameter is a big endian string of octets.
The leading octet can be zero...meaning that the actual numerical number represented by the X has a prepended leading zero octet....

As for the library, I'm using WolfSSL in C/C++ on an embedded device and Wolf has no support for JWK so I wrote a JWK library from scratch.

My Thumbprint routine was trimming leading zero octets and that was the core error...

1 Like

While I'm not a native English speaker, I do not believe this is meant with the word "prepended", as "to prepend" means to actually add something:

prepend

verb [ T ] COMPUTING formal or specialized UK /prɪˈpend/ US /prɪˈpend/

to add something to the beginning of something else, especially a piece of data (= information) to the beginning of a computer instruction:

If the remote machine is Windows based, prepend the address with smb://.

(PREPEND | English meaning - Cambridge Dictionary)

Thus, something NOT specially added in the front should NOT be removed.

Also, the part I've quoted earlier and to which I believe RFC 8555 is referring to is for RSA only, not for ECDSA.

4 Likes

This comment is about thumb prints and is agnostic as per RSA or ECDSA...

In the normal meaning of numbers I would argue that zero octets at the front of a number are prepended...

IE (Realize I'm using base 10 numbers here, but the concept is identical with multi octet big endian numbers)

12345 is a number...
I
012345 is the SAME number with a prepended zero.

IE its extra not needed to communicate the value.
All public key crypto is nothing but numbers...
In other crypto environments and encodings its common to strip leading zeros...

When your not supposed to trim leading zeros they tell you so explicitally:
RFC7815 Explicitly Tells you
into octet sequences in big-endian order, with each
array being be 32 octets long. The octet sequence
representations MUST NOT be shortened to omit any leading zero
octets contained in the values.

So when the text explicitly tells you to remove prepended zero octets...
one might be confused by the explicit must not trim zeros and must trim zeros confusion...

Well, I agree it's not talking about specifics, but it is refering to RFC 7518, so ultimately that RFC should be followed I believe.

"leading zero octets" is not the same as "an extra [prefixed] zero-valued octet".

So in conclusion: leave any existing zeros alone, don't prepend any new zeros.

6 Likes

I agree your version is the correct one, I'm just saying its really unclear and if others had the same misunderstanding it would lead to the case...
(That appears on this very forum) when things will work or not work depending on the specic random values on the fields inside a key.

IE I've got 10 instances of X and 9 work and 1 gets the error specified here...
and there are threads many pages long unable to resolve why the error is appearing for one instance...
It might be worthwhile for people to go look at the core JWK thumbprint code in that instance to see if someone else had the same misunderstanding of a very unclear paragraph.

2 Likes

The reason I brought this up is that when looking to find my problem I found this

Here they have the exact same error, the http-01 verification has the correct token part, but the key thumbprint is wrong...
So deep in that code someone may be trimming zeros, or there is a differnt problem with the thumbprint (IE using the wrong key) or some such...

Since I hit the same error I'd made assumptions..

Digging in certbot code... (I hate python and don't write it so take this with a grain of salt..)
In the josepy code..
It looks like the encode_param does not use a fixed length, but enccodes the length needed by the parameter,,,, so an ECDSA key with x, or y having leading zeros will generate the wrong thumbprint here...

My confidence in this is low....
For those of you confident to test these libraries in python I give you the following test case:

Correct Thumb of account key=
6r8E9G0hWMmumh0TkT9EK_KyjKKkGh843-Nsz25YRq4

JWK of account key= {"crv":"P-256","kty":"EC","x":"AHe1to1n4RPq1fi3a_Kitd3KtTO91x4x-0aMBwYAQps","y":"8LI2UdFO6ypVHA497pWbkY10nZZfQnL-jjFOVg3CHTg"}

Incorrect zero trimmed thumbprint = IdQlInkl_9IMi3pbrn4Yq99UfvxhS3cidp60oPR2PR4

Note that this jwk X value has a single leading zero octet.
One way to test this by writing no code is is to regenerate ECDSA keys over and over until one of the public key x,y has a leading zero and then test using certbot against the staging server,

If this is purely random then you should see this error once every 128 key generations as if the leading bit is truly random you will get a leading zero 1/256 tries and since you have two numbers 1/128.

python to_data is used in this library...
Note that if the leading byte of the number has the high bit of the high octet is set, to_data will add an additional byte, this would also screw up the thumbprint...

tests/jwk_test.py::JWKECTest::test_encode_y_leading_zero_p256 y=b"\x00<\t\x7f\x89\x9b\x87\xdf\\\x10~\xcbx\x82T\xd9\xa7\x19)\x10\x8f\xcc\xcc\xd6G\x8e&'\xaa\xb1\x9eK"
josepy.b64encode(key.thumbprint())=b'nxFNLnQduqMK27pqw8Fsqi4NGZxCwtR-pgKi7ZtG5v4'
josepy.b64encode(JWK.from_json(json).thumbprint())=b'nxFNLnQduqMK27pqw8Fsqi4NGZxCwtR-pgKi7ZtG5v4'
7 Likes

I knew this would be done in josepy, but I was looking at the source and you knew the exact test!

4 Likes

Using that key I get:
Thumb=nxFNLnQduqMK27pqw8Fsqi4NGZxCwtR-pgKi7ZtG5v4
So JOSEPY is doing the right thing.
The guy who's problem was linked above^^^^ had a thumbprint mismach so not sure what the issue was. I was trying to help alas my problem is now solved.

Their issue was that they'd hardcoded a thumbprint corresponding to a previous account key into their HTTP-01 challenge response server. Also their problem was back in 2017 :smiley:

7 Likes

Sorry for the false alarm...
Still think the doc should be cleaned up...

I think RFC 8555 could/should(?) have been written more clearly with regard to this aspect. That said, I'm not a RFC expert, but RFCs aren't docs that are easily "cleaned up" I think. An errata containing a clarification might be warrented, but I'm not sure how many people are actually affected.

3 Likes