"Parse error reading JWS"

I'm making use of Microsoft.IdentityModel.Tokens in dotnet and am getting the error in this title for my first foray in json tokens.

From one of the other posts, I did set the JsonWebKey.D to null, so that was good to know.

jwt.io likes my test request:


which translated to:

  "alg": "ES256",
  "typ": "JWT",
  "nonce": "TgwGXC18Mlqv3p82dC_Ngw",
  "url": "https://localhost:14000/sign-me-up",
  "jwk": {
    "crv": "P-256",
    "kty": "EC",
    "x": "QATOac8mUfrKekVapnv-5313cD21pdh56gUbLqD6cQ4",
    "y": "poKrj8UMuxFLOn0eAqH9_L7Uk9wv39urSHv8XxXJsV0"
  "termsOfServiceAgreed": "True"
  base64UrlEncode(header) + "." +
  "crv": "P-256",
  "kty": "EC",
  "x": "QATOac8mUfrKekVapnv-5313cD21pdh56gUbLqD6cQ4",
  "y": "poKrj8UMuxFLOn0eAqH9_L7Uk9wv39urSHv8XxXJsV0"


I was hoping pebble would output what it didn't like while parsing, but it kept mum on the issue:

Pebble 2022/07/01 09:41:15 GET /dir -> calling handler()
Pebble 2022/07/01 09:41:16 HEAD /nonce-plz -> calling handler()
Pebble 2022/07/01 09:41:19 POST /sign-me-up -> calling handler()
1 Like

pebble (and presumably boulder) uses jose package - gopkg.in/square/go-jose.v2 - Go Packages package for JWS parse. try parse by that


AH Thanks! That got me something workable:

$ echo eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCIsIm5vbmNlIjoiVGd3R1hDMThNbHF2M3A4MmRDX05ndyIsInVybCI6Imh0dHBzOi8vbG9jYWxob3N0OjE0MDAwL3NpZ24tbWUtdXAiLCJqd2siOnsiY3J2IjoiUC0yNTYiLCJrdHkiOiJFQyIsIngiOiJRQVRPYWM4bVVmcktla1ZhcG52LTUzMTNjRDIxcGRoNTZnVWJMcUQ2Y1E0IiwieSI6InBvS3JqOFVNdXhGTE9uMGVBcUg5X0w3VWs5d3YzOXVyU0h2OFh4WEpzVjAifX0.eyJ0ZXJtc09mU2VydmljZUFncmVlZCI6IlRydWUifQ.fbsa0vZub-IAW5SYKnA1yJ1O1cUehrAHlusJk8RRzfIEFCJzXqSrn4mVTFs2jBHqy4z_S2XRuKs2tVcNuHF02A | jose-util --key key.pem verify

unable to read public key: square/go-jose: parse error, got 'asn1: structure error: tags don't match (16 vs {class:0 tag:2 length:1 isCompound:false}) {optional:false explicit:false application:false private:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} AlgorithmIdentifier @2', 'x509: malformed tbs certificate' and 'invalid character '-' in numeric literal'

Now I can at least delve further into what's up.

Any reason why jwt.io was fine with it, but go-jose was not?

1 Like

@vindicator Never share your PRIVATE KEY!


Oh, I know. That's just a test certificate. But that is actually now making me look there since I deleted the .D field.


ACME protocal doesn't expect PEM key formant, but base64urlencode(DER) format


Looks like @Phil was quick. I was curious if there actually was a LE (prod) certificate using that key and in fact there is!

Revoked for keyCompromise, so the key is blocked now. Cert apparently issued by LE staff themselves, just to block the key :grinning_face_with_smiling_eyes:.


Hm, so if I post the output of for i in seq 1 100; do openssl ecparam -genkey -name prime256v1; done a LE employee will start generating 100 certificates and revoking them? :stuck_out_tongue:


Yes, and that’s not all we would revoke.


Hm, ok.. I'm not sure why tho. As far as I can tell, the baseline requirements always mention a private key in combination with the corresponding public key in a certificate. So I don't think CAs are mandated to do this. Anyone can issue a certificate for a randomly found private key. It's only when the CA is attended on the fact a certificate was issued with a compromised key, the CA has to act.

Also, you might want to doublecheck the private keys in the Boulder repository in that case. test-ee.key was still functional (now revoked). Maybe others are too. Everything from /test/ with "key" in its name is now revoked. :slight_smile:

I wouldn't dare provoking the LE staff obviously :slight_smile: No need to get dramatic/threaten me.. :confused:

Getting a little bit offtopic now however..


@Osiris lets cut them some slack, I would not be surprised if they are under pressure to keep LE safe and reliable. They have to fend off all the evils lurking out there on the internet. And maybe sometimes the community just mildly triggers the system. It is unfortunate that tolerance is not something easily afforded an organization dealing with security. Just asking to look at the comment from their perspective.


Offtopic: I can understand pressure to keep LE safe and reliable. I'm just personally offended James thinks it's necessary to threaten me to prevent me from actually doing something like posting 100 private keys?


I think he's playing with you @Osiris (while also discouraging others from doing something so silly).


I apologize - I was too harsh here, and reflexively assumed you knew how we have to respond to private key compromise reports. (To explain this, without excusing my reaction: We have to treat these as formal incidents, with a short time limit to investigate, engage on-call team members, and verify that the keys are blocked. There's a history of these being reported to us right at the start of holidays.)


There's multiple ways we have of blocking a private key from future issuance. I used this private key leak as a training opportunity for a new junior engineer. We went through investigating the key algorithm, how to geenrate a CSR, issuance via certbot, and ultimately revocation of this leak. We used one of my domains to illustrate the point that if a key is leaked, anyone on the internet could perform this same action. Under the hood the key compromise reason kicks off a chain of events that ultimately revoke every certificate with a matching Subject Public Key Info hash (SPKI).

Typing from the middle of the woods. Sorry for typos.


Have you submitted to https://pwnedkeys.com/ too?


Even if there's no (public) certificate associated with the key (yet)? See edit below.

Apology accepted. :slight_smile:


Well okay, this IS a newsflash for me now. When @Bruce5051 mentioned Never share your PRIVATE KEY, I merely thought that was to say (other than literally just not sharing it) to never use a shared/exposed key. I at least knew that much.

But from all of the hubbub going on in this post, I'm now seeing it's MUCH more than that.
And for that, I humbly apologize for wasting your time in having to create a revocation for something I never had any intention of using outside of testing my program.

Should I take it that no one should include the signature portion of their token? Just the header and payload?
I had looked at all of the error-related posts, like Parse error reading JWS and never saw any comment about them posting their private key.
Was it because I didn't explicitly state from my initial post that it was just a test key (even though I did say test request?
I definitely don't want to be wasting people's time from mistakes like that.

I do find it odd that the "private key" content I posted here from jwt.io is different from the text file that was used from my system.
What was posted here begins with MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQ, which matches the start of my file, but it veers off after that: Here gev...; File gjg.... And it doesn't even contain ANY of the JWK.D value.
If you'd like to see for comparison, I can post the file content here. I just don't want you to have to waste generating another revocation. Again, it's all just a temporary test key while I test my program.

For that matter, where did that private key come from, when I nulled out the JWT.D value prior to sending the token?


The signature does not contain private information. You can show the entire JWT token.

I presume the confusion comes from the fact that jwt.io puts your private key just below the decoded signature, if you've provided it.

I presume that you've pasted the output from jwt.io here, right? That tool allows you to paste your private key into it, which it will use for computations.

From the looks of it, that tool (locally) caches the private key you put into it, so on subsequent requests it doesn't ask again and shows the same private key again.


Signatures are safe to post. They don't contain private data and ultimately are the result of a one-way hash function. So unless an unsafe hash algorithm is used (e.g. SHA-1), signatures are safe. (Even with a SHA1 hash it's safe to post, just not safe to use any longer due to too high chance of collisions.)

Personally, I'm still not convinced it's necessary for CAs to make sure any posted private key can't be used on their system even if there isn't a certificate associated with it. If that's the case, I wish the LE team good luck (sincerely! as it's probably quite labor intensive) with indeed revoking all the private keys posted on this Community (there are A LOT).

It seems does actually mandate this! Although one can argue what the confines of "made aware" is:

The CA SHALL reject a certificate request if one or more of the following conditions are
4. The CA has previously been made aware that the Applicant’s Private Key has
suffered a Key Compromise, such as through the provisions of Section;

So if a LE crewmember does come across a private key, that indeed would mean that the CA SHALL make sure that key can't be used any longer, such as revoking a randomly generated cert and subsequently revoking it, with keycomprimise as reason.

My initial BR search did not find this paragraph, my apologies to James for doubting. Although this does maybe present a problem with all the private keys posted on the Community. Is "made aware" only when an actual crew member comes across the private key or is posting it on the Community "made aware" enough?

If I understand James post correctly, even randomly generated keys which are not intended to be used for anything at all need to be revoked. :confused: So with or without mentioning "test key".