Large number of malformed JWS verification error

Hi,
I’m developing an ACME client library.
When testing against the staging server, I get a lot of “malformed JWS verification error” replies.

Here are two examples of the same call briefly after each other (twice very soon after device boot), once with the infamous error, the other a valid call.

Am I overlooking something on my part, or is the staging server throwing a LOT of these ?

Thanks,

Danny

P.S. Source code at https://esp32-acme-client.sourceforge.io .

I (7786) Acme: QueryAcmeDirectory: ok
I (9476) Acme: RequestNewAccount(mailto:dannybackx@telenet.be) msg {
“termsOfServiceAgreed”: true,
“contact”: [
mailto:dannybackx@telenet.be
],
“onlyReturnExisting”: true
}
I (10586) Acme: RequestNewAccount : msg {
“protected”: “eyJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9uZXctYWNjdCIsICJqd2siOiB7Imt0eSI6ICJSU0EiLCAibiI6ICJ3ZUJFOUVZM21lRkdjbTYwTnpQdWhGSHVZemh6QnUxMXR6aUx0ZVlwVERxTGs2ZnF2ZTNjM3lJRDNwZXExXzJKV1psOGt5VVg3Y3NSVkNiWUFheHRsbDNnbGx5QnR4ekhjZlJrYl9iREdDT2J1cDFFS2ZpNDIwUnNiSHoxbEZmVEE3enA3XzMwQWhrOWNVd3F1MG1DdDlIeFVOQjFyNVJTSDRhZEptY0NrOE84dWZhUkZVdlRTVU5vcGlZRURqci0zM1BmS0hSX1dNdUZ1MGZvb21HamVHbGwyanVHR09iU1Vud29TRWxRcmZlLXRINXU5Q0ZiSmJHOFpfSGRrN3o1SG5XQ2lIZWtFTEVWcGU0Yk5fTXN4QS1RRF9Vb3NKVVI4T1M2eF81U1RiRzNaMEwtcmJ4X1pXanVuZFlQTmhRTnM5N2EzcDlMdFF3VzB3Z09jVU92ZnciLCAiZSI6ICJBUUFCIn0sICJhbGciOiAiUlMyNTYiLCAibm9uY2UiOiAiMDAwMWJDUDN2ekFjb3lmazg2RTEtODlaOERqX0RTdzRTTjZqRDhFd0pfZmVIZDAifQ”,
“payload”: “ewogICJ0ZXJtc09mU2VydmljZUFncmVlZCI6IHRydWUsCiAgImNvbnRhY3QiOiBbCiAgICAibWFpbHRvOmRhbm55YmFja3hAdGVsZW5ldC5iZSIKICBdLAogICJvbmx5UmV0dXJuRXhpc3RpbmciOiB0cnVlCn0”,
“signature”: “kDDJphCq0BpoDxAQdMMRBrNUwBbuldRAoLEU3Q7F1wQjciaSws4KmjBC9RQgKSH_IkC73yRvpOcZqBwjZOMNL6BycEaPmz6hhTm8akve2sDNyZB7ZjfmFkKpQBQmWnTFl7OIdRLKCfrIoNjpOAM4YawOuk_VxR24okhvA38GtflrI85b2eU”
}
I (12026) FTP Server: 28-12-2019 17:01:06 : 220 LightFTP server v2.0a ready
I (12546) Acme: HttpEvent: header Server value nginx
I (12546) Acme: HttpEvent: header Date value Sat, 28 Dec 2019 16:01:07 GMT
I (12546) Acme: HttpEvent: header Content-Type value application/problem+json
I (12556) Acme: HttpEvent: header Content-Length value 107
I (12566) Acme: HttpEvent: header Connection value keep-alive
I (12566) Acme: HttpEvent: header Cache-Control value public, max-age=0, no-cache
I (12576) Acme: HttpEvent: header Link value https://acme-staging-v02.api.letsencrypt.org/directory;rel=“index”
I (12586) Acme: HttpEvent: header Replay-Nonce value 0002emKJAuIhmoKQYqIAWzyFvTG81Yk261qpUOWxC-5R8Vg
I (12606) Acme: RequestNewAccount : JSON opened
E (12606) Acme: RequestNewAccount: failure 400 urn:ietf:params:acme:error:malformed JWS verification error
I (12626) Acme: ReadCertificate: we have a certificate in /spiffs/acme/certificate.pem

I (6226) Acme: QueryAcmeDirectory: ok
I (7916) Acme: RequestNewAccount(mailto:dannybackx@telenet.be) msg {
“termsOfServiceAgreed”: true,
“contact”: [
mailto:dannybackx@telenet.be
],
“onlyReturnExisting”: true
}
I (9026) Acme: RequestNewAccount : msg {
“protected”: “eyJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9uZXctYWNjdCIsICJqd2siOiB7Imt0eSI6ICJSU0EiLCAibiI6ICJ3ZUJFOUVZM21lRkdjbTYwTnpQdWhGSHVZemh6QnUxMXR6aUx0ZVlwVERxTGs2ZnF2ZTNjM3lJRDNwZXExXzJKV1psOGt5VVg3Y3NSVkNiWUFheHRsbDNnbGx5QnR4ekhjZlJrYl9iREdDT2J1cDFFS2ZpNDIwUnNiSHoxbEZmVEE3enA3XzMwQWhrOWNVd3F1MG1DdDlIeFVOQjFyNVJTSDRhZEptY0NrOE84dWZhUkZVdlRTVU5vcGlZRURqci0zM1BmS0hSX1dNdUZ1MGZvb21HamVHbGwyanVHR09iU1Vud29TRWxRcmZlLXRINXU5Q0ZiSmJHOFpfSGRrN3o1SG5XQ2lIZWtFTEVWcGU0Yk5fTXN4QS1RRF9Vb3NKVVI4T1M2eF81U1RiRzNaMEwtcmJ4X1pXanVuZFlQTmhRTnM5N2EzcDlMdFF3VzB3Z09jVU92ZnciLCAiZSI6ICJBUUFCIn0sICJhbGciOiAiUlMyNTYiLCAibm9uY2UiOiAiMDAwMWtpdkRBYW0wSDVpQldVVEhVR3JvcjlWa2g0b2FvQjZzYVhUSUlRUUVneHMifQ”,
“payload”: “ewogICJ0ZXJtc09mU2VydmljZUFncmVlZCI6IHRydWUsCiAgImNvbnRhY3QiOiBbCiAgICAibWFpbHRvOmRhbm55YmFja3hAdGVsZW5ldC5iZSIKICBdLAogICJvbmx5UmV0dXJuRXhpc3RpbmciOiB0cnVlCn0”,
“signature”: “SO-yJ4iee4lb5e1sJyuRVjBlLLwiKdq40kfJnPg9BSKP636wbnKWi7Mnz3y9zbJVilKqVoljos5jhImQFu04gRJKo2DCaOhzSm2jwp2Ntbscp3WtGg7YtyMk9a7Cy0c3z5EV3OmuXdB0bKPn3Ea0s9LlRXhRqyabc-8XbUwGR_H-Qmg1I7kTbwZb_QPc5YR-mw-FrTgdoOwmSE3nDc4CMEsv267nVS2J3bh5EzOSNpuQWeZwXvA5kdv9xr1SPjHKrcdHUAmHckcwAlTQr1vllwGtMmZXw_cu93BaISwunEnoZEBnUqIWjnc9HHlJ2u4E6OZpjsdI9OQFVrTlgc_lzA”
}
I (10526) FTP Server: 28-12-2019 17:04:10 : 220 LightFTP server v2.0a ready
I (10996) Acme: HttpEvent: header Server value nginx
I (10996) Acme: HttpEvent: header Date value Sat, 28 Dec 2019 16:04:11 GMT
I (10996) Acme: HttpEvent: header Content-Type value application/json
I (10996) Acme: HttpEvent: header Content-Length value 575
I (11006) Acme: HttpEvent: header Connection value keep-alive
I (11016) Acme: HttpEvent: header Cache-Control value public, max-age=0, no-cache
I (11026) Acme: HttpEvent: header Link value https://acme-staging-v02.api.letsencrypt.org/directory;rel=“index”
I (11036) Acme: HttpEvent: header Location value https://acme-staging-v02.api.letsencrypt.org/acme/acct/11649655
I (11046) Acme: HttpEvent: header Replay-Nonce value 0002StVNqIs-HRnTwNvCUjktajWyPP5akus9wjMPjGc_tYo
I (11056) Acme: HttpEvent: header X-Frame-Options value DENY
I (11056) Acme: HttpEvent: header Strict-Transport-Security value max-age=604800
I (11076) Acme: RequestNewAccount : JSON opened
E (11076) Acme: RequestNewAccount: reply_status ‘valid’
I (11086) Acme: ReadCertificate: we have a certificate in /spiffs/acme/certificate.pem

1 Like

Hi @dannybackx

the only difference of the two blocks is the nonce.

So your nonce may be invalid / expired.

2 Likes

Thanks, I’ll track that before anything else.

Danny

1 Like

Here’s such an example. I’ve added code to write the nonce specified by the server, and obviously my code asks for a nonce after boot.

This time, there were two failures before a valid reply.

Danny

I (6496) Acme: QueryAcmeDirectory: ok
I (8186) Acme: setNonce(0001qdd3rfk_–4il5M1btz696-PR-1wVGPRH_7YZq7ErRY)
I (8196) Acme: RequestNewAccount(mailto:dannybackx@telenet.be) msg {
“termsOfServiceAgreed”: true,
“contact”: [
mailto:dannybackx@telenet.be
],
“onlyReturnExisting”: true
}
I (9296) Acme: RequestNewAccount : msg {
“protected”: “eyJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9uZXctYWNjdCIsICJqd2siOiB7Imt0eSI6ICJSU0EiLCAibiI6ICJ3ZUJFOUVZM21lRkdjbTYwTnpQdWhGSHVZemh6QnUxMXR6aUx0ZVlwVERxTGs2ZnF2ZTNjM3lJRDNwZXExXzJKV1psOGt5VVg3Y3NSVkNiWUFheHRsbDNnbGx5QnR4ekhjZlJrYl9iREdDT2J1cDFFS2ZpNDIwUnNiSHoxbEZmVEE3enA3XzMwQWhrOWNVd3F1MG1DdDlIeFVOQjFyNVJTSDRhZEptY0NrOE84dWZhUkZVdlRTVU5vcGlZRURqci0zM1BmS0hSX1dNdUZ1MGZvb21HamVHbGwyanVHR09iU1Vud29TRWxRcmZlLXRINXU5Q0ZiSmJHOFpfSGRrN3o1SG5XQ2lIZWtFTEVWcGU0Yk5fTXN4QS1RRF9Vb3NKVVI4T1M2eF81U1RiRzNaMEwtcmJ4X1pXanVuZFlQTmhRTnM5N2EzcDlMdFF3VzB3Z09jVU92ZnciLCAiZSI6ICJBUUFCIn0sICJhbGciOiAiUlMyNTYiLCAibm9uY2UiOiAiMDAwMXFkZDNyZmtfLS00aWw1TTFidHo2OTYtUFItMXdWR1BSSF83WVpxN0VyUlkifQ”,
“payload”: “ewogICJ0ZXJtc09mU2VydmljZUFncmVlZCI6IHRydWUsCiAgImNvbnRhY3QiOiBbCiAgICAibWFpbHRvOmRhbm55YmFja3hAdGVsZW5ldC5iZSIKICBdLAogICJvbmx5UmV0dXJuRXhpc3RpbmciOiB0cnVlCn0”,
“signature”: “RVDphECCYjxF69kwZMH1fxQwD6WN0ope_-GfU27auuzAuHpenYCM8xfwV0mzD60vNg”
}
I (10596) FTP Server: 28-12-2019 20:06:06 : 220 LightFTP server v2.0a ready
I (11466) Acme: HttpEvent: header Server value nginx
I (11466) Acme: HttpEvent: header Date value Sat, 28 Dec 2019 19:06:07 GMT
I (11466) Acme: HttpEvent: header Content-Type value application/problem+json
I (11476) Acme: HttpEvent: header Content-Length value 107
I (11486) Acme: HttpEvent: header Connection value keep-alive
I (11486) Acme: HttpEvent: header Cache-Control value public, max-age=0, no-cache
I (11496) Acme: HttpEvent: header Link value https://acme-staging-v02.api.letsencrypt.org/directory;rel=“index”
I (11506) Acme: HttpEvent: header Replay-Nonce value 0002wJd2M5gAVLxDxeqeLoIY6t3CkJBRxdT7xirtg4SCByM
I (11516) Acme: setNonce(0002wJd2M5gAVLxDxeqeLoIY6t3CkJBRxdT7xirtg4SCByM)
E (11526) Acme: RequestNewAccount: failure 400 urn:ietf:params:acme:error:malformed JWS verification error
I (11546) Acme: ReadCertificate: we have a certificate in /spiffs/acme/certificate.pem

I (7676) Acme: QueryAcmeDirectory: ok
I (9266) Acme: setNonce(0002j0ECrsFYbErEThQBxqd-RbtWDeR0yjH1GygkQnOr058)
I (9276) Acme: RequestNewAccount(mailto:dannybackx@telenet.be) msg {
“termsOfServiceAgreed”: true,
“contact”: [
mailto:dannybackx@telenet.be
],
“onlyReturnExisting”: true
}
I (10376) Acme: RequestNewAccount : msg {
“protected”: “eyJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9uZXctYWNjdCIsICJqd2siOiB7Imt0eSI6ICJSU0EiLCAibiI6ICJ3ZUJFOUVZM21lRkdjbTYwTnpQdWhGSHVZemh6QnUxMXR6aUx0ZVlwVERxTGs2ZnF2ZTNjM3lJRDNwZXExXzJKV1psOGt5VVg3Y3NSVkNiWUFheHRsbDNnbGx5QnR4ekhjZlJrYl9iREdDT2J1cDFFS2ZpNDIwUnNiSHoxbEZmVEE3enA3XzMwQWhrOWNVd3F1MG1DdDlIeFVOQjFyNVJTSDRhZEptY0NrOE84dWZhUkZVdlRTVU5vcGlZRURqci0zM1BmS0hSX1dNdUZ1MGZvb21HamVHbGwyanVHR09iU1Vud29TRWxRcmZlLXRINXU5Q0ZiSmJHOFpfSGRrN3o1SG5XQ2lIZWtFTEVWcGU0Yk5fTXN4QS1RRF9Vb3NKVVI4T1M2eF81U1RiRzNaMEwtcmJ4X1pXanVuZFlQTmhRTnM5N2EzcDlMdFF3VzB3Z09jVU92ZnciLCAiZSI6ICJBUUFCIn0sICJhbGciOiAiUlMyNTYiLCAibm9uY2UiOiAiMDAwMmowRUNyc0ZZYkVyRVRoUUJ4cWQtUmJ0V0RlUjB5akgxR3lna1FuT3IwNTgifQ”,
“payload”: “ewogICJ0ZXJtc09mU2VydmljZUFncmVlZCI6IHRydWUsCiAgImNvbnRhY3QiOiBbCiAgICAibWFpbHRvOmRhbm55YmFja3hAdGVsZW5ldC5iZSIKICBdLAogICJvbmx5UmV0dXJuRXhpc3RpbmciOiB0cnVlCn0”,
“signature”: “evpg40zK-CtebTThlmNeVe_L8H42a-10ovtaEw”
}
I (12026) FTP Server: 28-12-2019 20:09:17 : 220 LightFTP server v2.0a ready
I (12136) Acme: HttpEvent: header Server value nginx
I (12136) Acme: HttpEvent: header Date value Sat, 28 Dec 2019 19:09:17 GMT
I (12136) Acme: HttpEvent: header Content-Type value application/problem+json
I (12146) Acme: HttpEvent: header Content-Length value 107
I (12156) Acme: HttpEvent: header Connection value keep-alive
I (12156) Acme: HttpEvent: header Cache-Control value public, max-age=0, no-cache
I (12166) Acme: HttpEvent: header Link value https://acme-staging-v02.api.letsencrypt.org/directory;rel=“index”
I (12176) Acme: HttpEvent: header Replay-Nonce value 0001O3Ei8eqN-KTKD6YsQMhzYB41YDNvnV8Viy8DjPbNelg
I (12186) Acme: setNonce(0001O3Ei8eqN-KTKD6YsQMhzYB41YDNvnV8Viy8DjPbNelg)
E (12196) Acme: RequestNewAccount: failure 400 urn:ietf:params:acme:error:malformed JWS verification error
I (12216) Acme: ReadCertificate: we have a certificate in /spiffs/acme/certificate.pem

I (7806) Acme: QueryAcmeDirectory: ok
I (9496) Acme: setNonce(00024IfB5HG9dcipE8IiUOSCEvPnBdLhtRRJW3RHgPhvrGM)
I (9506) Acme: RequestNewAccount(mailto:dannybackx@telenet.be) msg {
“termsOfServiceAgreed”: true,
“contact”: [
mailto:dannybackx@telenet.be
],
“onlyReturnExisting”: true
}
I (10606) Acme: RequestNewAccount : msg {
“protected”: “eyJ1cmwiOiAiaHR0cHM6Ly9hY21lLXN0YWdpbmctdjAyLmFwaS5sZXRzZW5jcnlwdC5vcmcvYWNtZS9uZXctYWNjdCIsICJqd2siOiB7Imt0eSI6ICJSU0EiLCAibiI6ICJ3ZUJFOUVZM21lRkdjbTYwTnpQdWhGSHVZemh6QnUxMXR6aUx0ZVlwVERxTGs2ZnF2ZTNjM3lJRDNwZXExXzJKV1psOGt5VVg3Y3NSVkNiWUFheHRsbDNnbGx5QnR4ekhjZlJrYl9iREdDT2J1cDFFS2ZpNDIwUnNiSHoxbEZmVEE3enA3XzMwQWhrOWNVd3F1MG1DdDlIeFVOQjFyNVJTSDRhZEptY0NrOE84dWZhUkZVdlRTVU5vcGlZRURqci0zM1BmS0hSX1dNdUZ1MGZvb21HamVHbGwyanVHR09iU1Vud29TRWxRcmZlLXRINXU5Q0ZiSmJHOFpfSGRrN3o1SG5XQ2lIZWtFTEVWcGU0Yk5fTXN4QS1RRF9Vb3NKVVI4T1M2eF81U1RiRzNaMEwtcmJ4X1pXanVuZFlQTmhRTnM5N2EzcDlMdFF3VzB3Z09jVU92ZnciLCAiZSI6ICJBUUFCIn0sICJhbGciOiAiUlMyNTYiLCAibm9uY2UiOiAiMDAwMjRJZkI1SEc5ZGNpcEU4SWlVT1NDRXZQbkJkTGh0UlJKVzNSSGdQaHZyR00ifQ”,
“payload”: “ewogICJ0ZXJtc09mU2VydmljZUFncmVlZCI6IHRydWUsCiAgImNvbnRhY3QiOiBbCiAgICAibWFpbHRvOmRhbm55YmFja3hAdGVsZW5ldC5iZSIKICBdLAogICJvbmx5UmV0dXJuRXhpc3RpbmciOiB0cnVlCn0”,
“signature”: “c1lSh9q2YvJAG9KW_80JDE_Y9GWCFaqd1dVIhAItKZ7evq-0h88SJJOlhSxnjePXQJ2ND1HENti48jJ4OSuStm2ufKY_Lfvyrzfw7GcSheokvzV2paUM_D9ZeSY6P91mOPIVawJuLTzEL0zlD_BqId0K7e-CQMQliUK8Gg4sf1aA9_gvBYVwR_lsXS80DFTIm8q2Zq00zjkT5FPrOJw5BD-kJxqnrQv0nlroi3aAanKmMK76pVXTWeeYGFDztY-9wGdW_PZbt5SZEws-L6Yv3rgRXF3pKH4nRzeXeYtaAVXdY2W0eFXIL3-eLoFFuV3V8MHjNZ5TbMm-yxSlec3x9A”
}
I (12026) FTP Server: 28-12-2019 20:09:45 : 220 LightFTP server v2.0a ready
I (12576) Acme: HttpEvent: header Server value nginx
I (12576) Acme: HttpEvent: header Date value Sat, 28 Dec 2019 19:09:46 GMT
I (12576) Acme: HttpEvent: header Content-Type value application/json
I (12586) Acme: HttpEvent: header Content-Length value 575
I (12586) Acme: HttpEvent: header Connection value keep-alive
I (12596) Acme: HttpEvent: header Cache-Control value public, max-age=0, no-cache
I (12606) Acme: HttpEvent: header Link value https://acme-staging-v02.api.letsencrypt.org/directory;rel=“index”
I (12616) Acme: HttpEvent: header Location value https://acme-staging-v02.api.letsencrypt.org/acme/acct/11649655
I (12626) Acme: HttpEvent: header Replay-Nonce value 000187DMDD_zxlrKUGXEFbSxAcr5Dnns-MaSiNSRu_IhPM8
I (12636) Acme: setNonce(000187DMDD_zxlrKUGXEFbSxAcr5Dnns-MaSiNSRu_IhPM8)
I (12646) Acme: HttpEvent: header X-Frame-Options value DENY
I (12646) Acme: HttpEvent: header Strict-Transport-Security value max-age=604800
E (12666) Acme: RequestNewAccount: reply_status ‘valid’
I (12676) Acme: ReadCertificate: we have a certificate in /spiffs/acme/certificate.pem

That's

not the nonce of your protected part:

{"url": "https://acme-staging-v02.api.letsencrypt.org/acme/new-acct", "jwk": {"kty": "RSA", "n": "weBE9EY3meFGcm60NzPuhFHuYzhzBu11tziLteYpTDqLk6fqve3c3yID3peq1_2JWZl8kyUX7csRVCbYAaxtll3gllyBtxzHcfRkb_bDGCObup1EKfi420RsbHz1lFfTA7zp7_30Ahk9cUwqu0mCt9HxUNB1r5RSH4adJmcCk8O8ufaRFUvTSUNopiYEDjr-33PfKHR_WMuFu0foomGjeGll2juGGObSUnwoSElQrfe-tH5u9CFbJbG8Z_Hdk7z5HnWCiHekELEVpe4bN_MsxA-QD_UosJUR8OS6x_5STbG3Z0L-rbx_ZWjundYPNhQNs97a3p9LtQwW0wgOcUOvfw", "e": "AQAB"}, "alg": "RS256", "nonce": "0001qdd3rfk_--4il5M1btz696-PR-1wVGPRH_7YZq7ErRY"}

0002wJd2M5gAVLxDxeqeLoIY6t3CkJBRxdT7xirtg4SCByM
<>
0001qdd3rfk_--4il5M1btz696-PR-1wVGPRH_7YZq7ErRY

If it was a nonce mismatch, it would not produce a JWS error. Nonce is not part of JOSE, it is an opaque part of ACME’s data.

I am pretty sure that there is something busted about either the RSA key you generated or how you used it to produce a signature.

When I reproduce your first request to a private Boulder instance with some extra verbose logging added, it produces:

boulder_1    | crypto/rsa: verification error
boulder_1    | square/go-jose: error in cryptographic primitive

Check your crypto. The second request is fine.

It is hard to diagnose only knowing {N,E} and the signature. If you can produce a similar log file with the full private key, that would probably be enough to figure out what’s going wrong.

1 Like

Yep, and my idea was wrong. The nonce is set:

that's the same. The second may be the answer nonce. False alarm.

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAweBE9EY3meFGcm60NzPuhFHuYzhzBu11tziLteYpTDqLk6fq
ve3c3yID3peq1/2JWZl8kyUX7csRVCbYAaxtll3gllyBtxzHcfRkb/bDGCObup1E
Kfi420RsbHz1lFfTA7zp7/30Ahk9cUwqu0mCt9HxUNB1r5RSH4adJmcCk8O8ufaR
FUvTSUNopiYEDjr+33PfKHR/WMuFu0foomGjeGll2juGGObSUnwoSElQrfe+tH5u
9CFbJbG8Z/Hdk7z5HnWCiHekELEVpe4bN/MsxA+QD/UosJUR8OS6x/5STbG3Z0L+
rbx/ZWjundYPNhQNs97a3p9LtQwW0wgOcUOvfwIDAQABAoIBAAchIigBdQX5nMeU
fpgRFtJS2PtZFhHJJa0JLUoRHq+o730MjbtSRe8GpzHGTggHUMe0tzoKASlDcG2x
x/u3xYfkB+A/op2DN2pfXFoprt7yYEWqhtksRk/54irTJYzA9geLKOckZZa2KuZB
sMiWWXI9DCy2nb1JLQPvxVOmMhgQ6C+D880qB2UHxmXNRxbVT+I8fBV9gv9r17gw
MI2yIQX2aAgAqe8g7H5lqvlP/aGsvxBTiTvgyIXZ7XaU9350p/xm90ZoYIQ4ijjF
oUqQdcRikNhouchZOxcOnrVF10UjzaEfZPjWypyOsLZrYfxhbYaACG8wkDnH9YQg
a6jcFkECgYEA8AkSr1oTZGtMIwJ8Om6XAGgVmrc0+F3vjDSbcXYsKCPiCqHkLn4p
xfhJDjc7cF5q1vJvOzUXW/LwvfhMEMpg1zbkuLQWF3i4CAMZmBDuwP8Qr2ryjDL7
LvRXgFCDqTIZ7zL2BGrPdk0OiqjGjK9fF24LgzGEpPepbrmuSMQ5NzECgYEAzsVF
QW1FHt/A8jEwLDAQDc9+vOczJ0d2umz6JIrjZoAkJMo4Hnpa7/TYPaddcakp03Ym
1KG4KWh0lduGj+ATbaLX/iiMJzE/if3GDyKVEB1Ws0ogwjE5fq4wadqiVKlk7NwG
pa6piQ7d+TC/lhi4lWdwdHBzTeZeRRbO2pKDBa8CgYAi7w8bGh7sZHlGNxxhXKr5
Uiyiwbsh0noEi7t7vdkbVm2VYo5U/eOSfloTiZJK/lLKSapKkaV+qlLDMxnO78U8
TS7oer0kWVtfPyRAb2ZwDC8feI8oPFs2MDVz5UPkIfiISYBokCr1aq2NHJcY7oUG
YeunAlPttmWgScHFsVkqYQKBgQDGUKyJAQ2ffAnqAMVsTDjJli6/bZxBWyiDy4vr
So6qO9Luukky6jWYGiTglUppfk8QcyzxGZ6xkG7pYGDiU48uw1YYfblWycRgTFcP
IyMHDqyeT0W2G1JCrzzd+gVh4ApdpvZ1KF2QiALcQyYuBs3a9hgEheoBWCcoaqTB
PG6QHwKBgHYEDMpv9mlcInQ9Bhymr3nDLRZg68lEuTsoJg2voT3vsCWwqZeBhzUC
Fmm1jhNkfLZpJO5+RDgUDHVfHaJ9qcEENbv2aokLLFzGZzP3PxA2lXAPUrwHrv3w
jlTPaUz7UTt2ie61MYiAQfbv1CaVLRURRpCRQfs6x0hqlfiOF99x
-----END RSA PRIVATE KEY-----

Please revoke that key.

Never share private keys.

1 Like

I’m aware, it’s just for debugging.

This signature seems to be truncated:

“signature”: “evpg40zK-CtebTThlmNeVe_L8H42a-10ovtaEw”

It should be:

“signature”: “evpg40zK-CtebTThlmNeVe_L8H42a-10ovtaEwDla_recyJmoG_vYP2m1PCbXXdIpZYwCn8joZiROUa1uMba7CkvyY3MXpSnWK-ZgZ22dkpy89KaVrFxUHhIsfjeYw0YZ-OFjb3zrIs244GWYZ3ncdVvZpuM02DfGSw_2r5jwR70WURXegyroemHHVTQmE7WxVGdGmfbkP-zr0PhuWH0KhzLEjY6s7D8qI3J9MiF1xKoYQANUFcPCHy02t0xCfYujPAteVsKKQWCyxnredRHO8i2EAY3zynnmoiS-HQpazR0UXikzzToFQB71DmCcJM-TcGG2B9o_CF1DOwpKbePvg”

Edit: and for your first example:

kDDJphCq0BpoDxAQdMMRBrNUwBbuldRAoLEU3Q7F1wQjciaSws4KmjBC9RQgKSH_IkC73yRvpOcZqBwjZOMNL6BycEaPmz6hhTm8akve2sDNyZB7ZjfmFkKpQBQmWnTFl7OIdRLKCfrIoNjpOAM4YawOuk_VxR24okhvA38GtflrI85b2eU

should be:

kDDJphCq0BpoDxAQdMMRBrNUwBbuldRAoLEU3Q7F1wQjciaSws4KmjBC9RQgKSH_IkC73yRvpOcZqBwjZOMNL6BycEaPmz6hhTm8akve2sDNyZB7ZjfmFkKpQBQmWnTFl7OIdRLKCfrIoNjpOAM4YawOuk_VxR24okhvA38GtflrI85b2eUAu6On9zbFvYu9ruGej8fenHZSUM4WpuWmqRAvIvYa3G5Wu9-4j0t8MmnXq_QPdtQhSgHEhZFYESWZqaMfy8EcGuh3YcPWzBkLuYcpC7eBKOma3IAjJZwP1iQ7ZigNxnnYIvqoJHP_AtY7hJjzdYdFTBD7RxUshVz0xA

4 Likes

Nicely spotted.

I noticed that in both cases, the truncation is happening on a NUL byte. So the problem is likely related to one of the uses of strlen, or the construction of String without specifying length.

4 Likes

I found such a line in my code, and the trivial fix does indeed make a difference.
I’ll have to check all of my code for this mistake.

Thanks for pointing me to this !

Danny

3 Likes

I’m sure there have been versions of this bug in thousands of pieces of software, because programmers are so used to dealing with null-terminated strings, especially in assembly and in languages derived from C. Cryptography is tricky here because you sometimes have (1) potentially variable-length objects that (2) need to be serialized and shown to users and/or included inside network protocols, but (3) are pseudorandom data that includes null bytes all over the place. If you get tempted to use a string anywhere instead of a fixed-size structure because of (1), or get tempted to use a string instead of a byte array or byte buffer because of (2), it’s easy to get tripped up when the string-manipulating functions don’t do what you expected with the object.

Some languages make it a lot easier to make this mistake than others, but it’s a good thing to watch out for!

5 Likes

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