Another "Parse error reading JWS"-Issue

Hi there, I'm currently trying to implement an ACME Client using RSA and facing a parsing error where none of the other related threads here helped resolving.

My request:

{
"protected": "eyJhbGciOiJSUzI1NiIsImp3ayI6eyJlIjoiQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQkFBRT0iLCJrdHkiOiJSU0EiLCJuIjoidHRWR0c4VjZ5TGNEUlB4cjFpUzhicVpGaUtXM1RRanVOOGc1X3RuZlZUdVdqYmU2SEFfd2VFRlh2dG10WkZyLVgtaVV2aEVXdHBYQ3RCd2J0cEpIa0NWaUJYZDFVeUFmUGppUk4wZjhtcDlRLUZ0d1FHeW5PT3FMLUhRTGt0bEtKSGYxc1IzWHdVYVl1VFp1b0RDTHR1WVFvZk9sd1hEM1NjaDRuOUJMQ3VvRHkwWVZ5NE9LNmYwTGVpMGtYdDFnTElxM1ptcDFwOUJSdFI1WHUxZllvNzZZZl9tSEwwV2dHdDB3Q3hvWmVqVk5UNmF4M2IxczYxN1RZWkZjNTVudmVNaDhUSEJ5WS13eklYXzZBZkhYeHFfQ1p2YjJBNEMtblFEYjJBaHhDMmNsUHdyNGJuYnp6LU9FblBQLTktNUdjeXBZQlNTbzdFTi0zclBGRUNFMDR3PT0ifSwibm9uY2UiOiJxNGZsNGNfMXJ4TzlBSkVzZS1WZVZRIiwidXJsIjoiaHR0cHM6Ly8wLjAuMC4wOjE0MDAwL3NpZ24tbWUtdXAifQ", 
"payload": "eyJjb250YWN0IjpbIm1haWx0bzp0ZXN0QGV4YW1wbGUuY29tIl0sInRlcm1zT2ZTZXJ2aWNlQWdyZWVkIjp0cnVlfQ",
"signature": "KTIs-f0-jQBX8oY-HkbfiKOZVPlocEjqSBb1bhqT7qaFAK7iN9VqejB0PeUFtsGXesJaX0FIeRTP90fHAKL8rbvgUrWjTrCVh28bZcz2KtyXGCNCxFGde_yEPA6TmFWJMHrwrgXfDWVYlvdmS9gXB3JD858OGkr1GB4BTSFITBUKr_mBtYKL05F7YJ0XXZP7Dat3xXo2Kxg8rdlb4n6H8daQm3PcPdtZCc3YJNLzHn95q2mEINikqEMev3OZwz1C6IYwqYJaRi-OkO3qkUtPZ8--bXelzCLYz-Qw63UKb3ic7RjWVKZ4WRvvim_7rAETBe38iWbEkDkKJ2aGrJeyPg"
}

Decoded proteced:

{
   "alg":"RS256",
   "jwk":{
      "e":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAE=",
      "kty":"RSA",
      "n":"ttVGG8V6yLcDRPxr1iS8bqZFiKW3TQjuN8g5_tnfVTuWjbe6HA_weEFXvtmtZFr-X-iUvhEWtpXCtBwbtpJHkCViBXd1UyAfPjiRN0f8mp9Q-FtwQGynOOqL-HQLktlKJHf1sR3XwUaYuTZuoDCLtuYQofOlwXD3Sch4n9BLCuoDy0YVy4OK6f0Lei0kXt1gLIq3Zmp1p9BRtR5Xu1fYo76Yf_mHL0WgGt0wCxoZejVNT6ax3b1s617TYZFc55nveMh8THByY-wzIX_6AfHXxq_CZvb2A4C-nQDb2AhxC2clPwr4bnbzz-OEnPP-9-5GcypYBSSo7EN-3rPFECE04w=="
   },
   "nonce":"q4fl4c_1rxO9AJEse-VeVQ",
   "url":"https://0.0.0.0:14000/sign-me-up"
}

Using a JWK to PEM Convertor, i get the public key, which is why assume that the JWK is fine.

Decoded payload

{
   "contact":[
      "mailto:test@example.com"
   ],
   "termsOfServiceAgreed":true
}

I assume something is wrong with the signature. But despite many tried options the request remains without success until now.

This is how I sign using python:

def signJWS(encodedProtected, encodedPayload, private_key: rsa.RSAPrivateKey):
    message_to_sign = f"{encodedProtected}.{encodedPayload}".encode('utf-8')
    signature = private_key.sign(
        message_to_sign,
        padding.PKCS1v15(),
        hashes.SHA256()
    )
    signature_base64 = base64Encoding(signature)
    return signature_base64

def base64Encoding(byteArray: bytearray):
    return base64.urlsafe_b64encode(byteArray).rstrip(b'=').decode('utf-8')

def normalizeJsonAndRemoveWhiteSpaces(payload: bytearray):
    return json.dumps(payload,
                      separators=(',', ':'),
                      sort_keys=True).encode('utf-8')

One thing I noticed is the "e" (public exponent) parameter. It must not have zero-padding. So instead of

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAE=

use

AQAB
3 Likes

Thanks for your response!

It indeed looks wrong. I now adjusted in my code through

  e_val = private_key.public_key().public_numbers().e
  e_bytes = e_val.to_bytes((e_val.bit_length() + 7) // 8, byteorder='big')
  e = base64.urlsafe_b64encode(e_bytes).rstrip(b'=').decode('utf-8')

which results in

{
   "alg":"RS256",
   "jwk":{
      "e":"AQAB",
      "kty":"RSA",
      "n":"o0EMhgnA7hIg4XvwRcyygcaKELxVRUI-HAy-ckAz4j7du_aczGNO6BRAzj7jvU-Nrhtn5nS1JTTwTqpbQDRmNukMbDCJTNGEyHGj-_XKB3dYr8B2RLYq_Wf6y_Q_WomVDOwQv7zZSC21C5t2FlqBbgYrDaF9M_Xrd1_lJGTFrnpiVm7Ham_rqDgcRM9lUEJaMJWDpApAVvhvqZj3YR16c0Nk2cfYMxI7hXJNbr-0jzDsKtfc4UzkicArPdEF18ShJsXqk97PRq-fdQ59QGDYYhoDrT1513ah3zP5o1ltb_SuCGSnJjYOAGR5tNTyIq0r65WLT7IhknkF2EK7BSJkGw=="
   },
   "nonce":"yJ8EehJt3--T1c35D-o83Q",
   "url":"https://0.0.0.0:14000/sign-me-up"
}

Unfortunately, I still get the "Parse error reading JWS"-error

I suggest reposting with an executable example that triggers your error. It's impossible to know how/where this is breaking. Your issues could be on the inputs or how you use the outputs.

I have often thought unit tests are good to work out these problems.

Two relevant functions that I've written:

4 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.