JCS
 
JSON Cleartext Signature
Table of Contents
1. Introduction
2. Sample Signature
3. Signature Scope
4. Normalization and Signature Validation
5. Notation
6. Data Types
7. JCS Objects
Top Level Property
signature
publicKey
signerCertificate
remoteKey
extensions
8. Multiple Signatures
9. Security Considerations
Appendix A: Test Vectors
Appendix B: ECMAScript Mode
Appendix C: Counter Signatures
Appendix D: Usage in Applications
Appendix E: Interoperability
Appendix F: Acknowledgements
Appendix G: References
Appendix H: Document History
Appendix I: Author
1. Introduction
JCS is a scheme for signing data expressed as JSON [RFC7159] objects, loosely modeled after XML DSig's [XMLDSIG] "enveloped" signatures. Compared to its XML counterpart JCS is quite primitive but on the other hand it has proved to be simple to implement and use.
Unlike JWS [RFC7515] which was designed for signing any kind of data, a JCS signature is intended to be an integral part of a JSON object with message centric systems like Yasmin [YASMIN] as the primary target. This concept was not originally considered due to the lack of a standardized normalization method for JSON data. However, version 6 of ECMAScript [ES6] introduced a predictable serialization scheme which enables both data and header information to be provided in plain text.
In order to make library support of JCS straightforward in spite of having a different structure compared to JWS [RFC7515], JCS supports the same algorithms [RFC7518] as well as using JWK [RFC7517] for representing public key data.
Since JCS is rooted in ECMAScript, JCS may also be used for "in-object" JavaScript signatures, making JCS suitable for HTML5 applications. See ECMAScript Mode.
There is also a "companion" specification coined JEF [JEF] which deals with JSON encryption.
2. Sample Signature
The following cryptographically verifiable sample signature is used to visualize the JCS specification:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "ES256",
    "publicKey": {
      "kty": "EC",
      "crv": "P-256",
      "x": "_gow8fcS3Dx9z6j57U5q8tunnRBdrgLU9A7CZTYCnqU",
      "y": "bdfJGraBVL5aPj38TG4tHwxpU2VKwG1XBp0wQfCLOFQ"
    },
    "value": "aRx2MQyCGVOZGViAC_7bEDUp8_CGO1kU1l7Lvp1FHx4qBiPkGs9Z7TKGK774XLTGwaCfUtd1VrscabQhmArCxA"
  }
}
The sample signature's payload consists of the properties above signature. Note: JCS does not mandate any specific ordering of properties like in the sample.
For more examples see Test Vectors.
3. Signature Scope
The scope of a signature (what is actually signed) comprises all properties including possible child objects of the JSON object holding the signature property except for the value property (shaded area in the sample).
4. Normalization and Signature Validation
Prerequisite: A JSON object in accordance with [RFC7159] containing a properly formatted signature sub-object.
Parsing restrictions:The normalization steps are as follows:Applied on the sample signature, a conforming JCS normalization process should return the following JSON string:
{"now":"2017-04-16T11:23:06Z","escapeMe":"$\u000f\nA'B\"\\\\\"/","numbers":[1e+30,4.5,6],"signature":
{"algorithm":"ES256","publicKey":{"kty":"EC","crv":"P-256","x":"_gow8fcS3Dx9z6j57U5q8tunnRBdrgLU9A7CZT
YCnqU","y":"bdfJGraBVL5aPj38TG4tHwxpU2VKwG1XBp0wQfCLOFQ"}}}
The text in red highlights the string normalization process. Note that the output string was folded for improving readability.
The signature value can now be calculated by running the algorithm specified in the algorithm property using the signature key over the UTF-8 representation of the normalized data.
Path validation (when applicable), is out of scope for JCS, but is preferably carried out as described in X.509 [RFC5280].
The next sections cover the JCS format.
5. Notation
JCS consists of a top-level signature property holding a composite JSON object.
JSON objects are described as tables with associated properties. When a property holds a JSON object this is denoted by a link to the actual definition.
Properties may either be mandatory (M) or optional (O) as defined in the "Req" column.
Array properties are identified by [ ] x-y where the range expression represents the valid number of array elements.
In some JSON objects there is a choice from a set of mutually exclusive alternatives.
This is manifested in object tables like the following:
Property selection 1Type selection 1ReqComment selection 1
Property selection 2Type selection 2Comment selection 2
6. Data Types
The table below shows how the data types used by this specification are mapped into native JSON types:
TypeMappingDescription
any"any"Arbitrary JSON type or object
bigintstringBase10-encoded integer with arbitrary precision
stringstringArbitrary string
uristringURI [RFC3986]
byte[]stringBase64URL-encoded [RFC4648] binary data
cryptostringBase64URL-encoded positive integer with arbitrary precision. Note that the value must not contain leading zero-valued bytes
object{}JSON object
Note that "Type" refers to the element type for arrays.
7. JCS Objects
The following tables describe the JCS JSON structures in detail.
Top Level Property
PropertyTypeReqComment
"signature": signatureobjectMMandatory top level property for simple signatures.
"signatures": [signature] 1-nobjectMandatory top level property for Multiple Signatures.
signature
PropertyTypeReqComment
"version": "http://xmlns.webpki.org/jcs/v1"uriOOptional. Signature object version identifier. For future revisions of JCS, this property would be mandatory.
"algorithm": "algorithm"stringMSignature algorithm. The currently recognized JWA [RFC7518] asymmetric key algorithms include:
  • RS256
  • RS384
  • RS512
  • ES256
  • ES384
  • ES512
The currently recognized JWA [RFC7518] symmetric key algorithms include:
  • HS256
  • HS384
  • HS512
Note: If proprietary signature algorithms are added, they must be expressed as URIs.
"keyId": "keyId"stringOOptional. Application specific string identifying the signature key.
"publicKey": publicKeyobjectOptional. Public key object.
"remoteKey": remoteKeyobjectOptional. A single public key or X.509 [RFC5280] certificate path accessible via HTTP.
"certificatePath": ["Sorted Certificate Path"] 1-nbyte[]Optional. Sorted array of X.509 [RFC5280] certificates, where the first element must contain the signature certificate. The certificate path must be contiguous but is not required to be complete.
"signerCertificate": signerCertificateobjectOOptional. Signature certificate attribute data for usage with the certificatePath option.
A compliant JCS implementation must verify that the signerCertificate object matches the first certificate in the certificatePath.
Note: Due to the fact that X.500 name comparisons have turned out (in practice) to be a source of non-interoperability, the signerCertificate option should only be used in specific environments.
"extensions": extensionsobjectOOptional. Object holding custom data like time-stamps, CRLs, and OCSP responses.
"value": "value"byte[]MThe signature data. Note that the binary representation must follow the JWA [RFC7518] specifications.
Note that asymmetric key signatures are not required providing an associated publicKey, remoteKey or certificatePath property since the key may be given by the context or through the keyId property.
publicKey
PropertyTypeReqComment
"kty": "kty"stringMKey type indicator. Currently the following types are recognized:
Additional EC Properties
"crv": "crv"stringMEC curve name. The currently recognized EC curves include:
  • P-256
  • P-384
  • P-521
Note: If proprietary curve names are added, they must be expressed as URIs.
"x": "x"byte[]MEC curve point X. The length of this field must be the full size of a coordinate for the curve specified in the crv parameter. For example, if the value of crv is P-521, the decoded argument must be 66 bytes.
"y": "y"byte[]MEC curve point Y. The length of this field must be the full size of a coordinate for the curve specified in the crv parameter. For example, if the value of crv is P-256, the decoded argument must be 32 bytes.
Additional RSA Properties
"n": "n"cryptoMRSA modulus. Also see the crypto data type.
"e": "e"cryptoMRSA exponent. Also see the crypto data type.
This object represents a subset of JWK [RFC7517].
signerCertificate
PropertyTypeReqComment
"issuer": "issuer"stringMIssuer distinguished name in LDAP [RFC4514] notation.
"serialNumber": "serialNumber"bigintMCertificate serial number.
"subject": "subject"stringMSubject distinguished name in LDAP [RFC4514] notation.
remoteKey
PropertyTypeReqComment
"uri": "uri"uriMURI [RFC3986] which must be dereferencable by an HTTPS GET operation. The returned data must be delivered "as is" (stream of bytes).
"format": "format"stringMCurrently defined format specifiers:See remote key example.
extensions
PropertyTypeReqComment
"...": ...anyMOne or more application specfic extension properties expressed as Property: Arbitrary JSON data.
Extensions intended for public consumption are preferably expressed as URIs, while private schemes are free using any valid property name.
A conforming JCS implementation must reject signatures containing extensions that are not recognized as well as empty "extensions" objects.
Examples:
"extensions": {
  "https://standards.org/pki/jcs/ocspResponse": "DgYDVR0PAQH_BAQDAgEGMB0GA1UdDgQWBBQT...VZI1YQdQFC63ncCTQ3iTAfBgNVHSMEGDAWg"
}

"extensions": {
  "myExt": "foobar",
  "otherExt": {
    "name": "johndoe",
    "role": "client"
  }
}
8. Multiple Signatures
Multiple signatures enable different keys to independently of each other add a signature to a JSON object.
The normalization procedure is essentially the same as for simple signatures but must also take the following in account as well:Also see Counter Signatures and the multiple signature sample.
9. Security Considerations
This specification does (to the author's knowledge), not introduce additional vulnerabilities over what is specified for JWS [RFC7515].
Appendix A: Test Vectors
This section holds test data which can be used to verify the correctness of a JCS implementation.
The Sample Signature can be verified by the public part of the following EC key in JWK [RFC7517] format:
{
  "kid": "20170101:mybank:p256",
  "kty": "EC",
  "crv": "P-256",
  "x": "_gow8fcS3Dx9z6j57U5q8tunnRBdrgLU9A7CZTYCnqU",
  "y": "bdfJGraBVL5aPj38TG4tHwxpU2VKwG1XBp0wQfCLOFQ",
  "d": "4f5C3onScS-l9MmKlvIbOV_M3jcQ9qOd4RoYFVlJUIo"
}
The following signature object which uses a keyId for identifying the public key can be verified with the public part of the key above:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "ES256",
    "keyId": "20170101:mybank:p256",
    "value": "nJgDRESd3-Q5b5xEykEq1uLOe4MSkxLLTylkioC4j2-KG-qkovb9diSf83nsYKX1-wySf66OJSQKxaCr7CNWQg"
  }
}
The following signature object uses the same key as in the previous example but featured in a certificate path:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "ES256",
    "signerCertificate": {
      "issuer": "CN=Payment Network Sub CA3,C=EU",
      "serialNumber": "1494492396421",
      "subject": "CN=mybank.com,2.5.4.5=#130434353031,C=FR"
    },
    "certificatePath": [
      "MIIB-jCCAVmgAwIBAgIGAVv2sDuFMAwGCCqGSM49BAMEBQAwLzELMAkGA1UEBhMCRVUxIDAeBgNVBAMTF1BheW1lbnQgTmV0d29yayBTdWIgQ0EzMB4XDTE3MDEwMTAwMDAwMFoXDTIyMDcxMDA5NTk1OVowMTELMAkGA1UEBhMCRlIxDTALBgNVBAUTBDQ1MDExEzARBgNVBAMTCm15YmFuay5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAT-CjDx9xLcPH3PqPntTmry26edEF2uAtT0DsJlNgKepW3XyRq2gVS-Wj49_ExuLR8MaVNlSsBtVwadMEHwizhUo10wWzAJBgNVHRMEAjAAMA4GA1UdDwEB_wQEAwID-DAdBgNVHQ4EFgQU0wnrn9RVBfR77HP_t09EZK6brIkwHwYDVR0jBBgwFoAUE0a3d3rVWSNWEHUBQut53Ak0N4kwDAYIKoZIzj0EAwQFAAOBjAAwgYgCQgCoyPGjg0hdwpHkY2FYWjVpZROVjXYQTcFvrnQpKdpiTblPka1y9I_F05zB66VYqijj0t281N92JPIuyHNvdVr3XgJCAVyXYUI16OruC-TtEG0mfxUGvLOxsy4z0XhfsD2q3mjzXKV_f8CJ1mjxnyd1Suv4JnS17h1eSUTqSbA7LKcQoGDQ",
      "MIIDtTCCAZ2gAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAwMQswCQYDVQQGEwJVUzEhMB8GA1UEAxMYUGF5bWVudCBOZXR3b3JrIFJvb3QgQ0ExMB4XDTE2MDcxMDEwMDAwMFoXDTI1MDcxMDA5NTk1OVowLzELMAkGA1UEBhMCRVUxIDAeBgNVBAMTF1BheW1lbnQgTmV0d29yayBTdWIgQ0EzMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAXt9fTiM4nZ9KPkzqOXrE1Ng7CthaAQ-m7DU1ULIfpK-n-vEsE1KqUhG5t_uqNpuBc3DhxsJ4V46EsE_6Q0IlFcAAS-p3J-1RBaKEo8eTqF8eC72GTiMuheictaAS9NT_IcsgEbXoNHwFbUxs0El2A-Boyh9BF_rja-XuQ-A1qgZ5_F-jYzBhMA8GA1UdEwEB_wQFMAMBAf8wDgYDVR0PAQH_BAQDAgEGMB0GA1UdDgQWBBQTRrd3etVZI1YQdQFC63ncCTQ3iTAfBgNVHSMEGDAWgBQE9W2T-nrW1SZqkrC0lUkcShmpvzANBgkqhkiG9w0BAQ0FAAOCAgEAbghYHRipnsMlY_unWECPIdDpqWlB4FvFtCKvPOdCTyu0HAVkN5foFEoecEuqhtLpSrHmMkNIJh33IqbZx00NYqDJ4DHoyv8lia3-pApec43p6_2CrC3fYV9Z8RmTO9cP3TIbeHLDdxNNXoI7kKlLdGsk63m6Tyl7kafTEsV8L8Loso_set0LwQPJJxBZJDnUGCauIEfLSGsLmDcW9oMPkUcSp2n5YwjTxFXOawZ5Rl04rS5KNgDaPyPT0FV-bI0ewRwzhn-_LDFLyhvlSltxEkwLEZFRlezPwQRo_rp8jea6APPVBQSC-B8MNPl8V3Whs_fmmWD1rcIl7VOaKaIR9-lwi2na-lctIEFg2tf8o9PYPf7MVyQ2OgOYPmB1qOJ8UCIOYJB6UxfZ-DTx4i3H4k3P-GcvGFWT5fg1DwapjrWkgEqS_ZXOQe3_r81-MSom2E-HcLjYQQhyoKy-GUzGvE21AQm9jBw3549HOCaT3FFTiE--aluX42HvuzAMIBAywnyQFK2g6o7F8-Ykne7aog3Q3oEMS6DzWVfs7TXZPW3sRz_UP54d3gyFezOjWlk-BhTPsFQ43340OuKFUH-D7n6Vr6sqpAUov4GjRMcjeTzIfw_qWPUamLgTFBNZ4bDpDH9FALvq9MTGFxvERcAxhit94491sV8SHz-IgMHmDdE"
    ],
    "value": "-g6ljSUV30G4XaX0NV5zYr5dwe5yXHE3aJphyCFEFNr4xRfmj_IDwkw3HLFUQ_Zbskn2xgJyLWuKJHTPWIDxXg"
  }
}
EC key for verifying the subsequent object:
{
  "kid": "20170101:mybank:p384",
  "kty": "EC",
  "crv": "P-384",
  "x": "SxtEVg93j4L2bK7Q8qJDYo6xRvP3p3ptyqmQaYnZRH5Ube2T2RogGMl-HHZRTYMO",
  "y": "Zu8b16lT-c5VstC4H9WA28LvcLleE6auP-A9Dr76uu8MI5YjOGH64MJZFswOX8Vz",
  "d": "PWoaRCsLI8sGkKy9O6yTPx8f0lN6CAYu9jfmlI5YmW6XW9qc6Qd2hz6FsrsZ2cxd"
}
The following signature object can be verified by the public part of the key above:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "ES512",
    "publicKey": {
      "kty": "EC",
      "crv": "P-384",
      "x": "SxtEVg93j4L2bK7Q8qJDYo6xRvP3p3ptyqmQaYnZRH5Ube2T2RogGMl-HHZRTYMO",
      "y": "Zu8b16lT-c5VstC4H9WA28LvcLleE6auP-A9Dr76uu8MI5YjOGH64MJZFswOX8Vz"
    },
    "value": "mO0Ph8oBTl37waf8SOShct3X8jVmVLx-XjjdZuLd87upJzo0Ya2XFspgwS65MLM0xtjcmrOW4juXUJV79zHfndKSqnT6VX5GyzW-EMZJylclQqyUkvNHV3Zf-iQnoJ4T"
  }
}
The following signature object uses the same key as in the previous example but featured in a certificate path:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "ES512",
    "signerCertificate": {
      "issuer": "CN=Payment Network Sub CA3,C=EU",
      "serialNumber": "1494492397640",
      "subject": "CN=mybank.com,2.5.4.5=#130434353031,C=FR"
    },
    "certificatePath": [
      "MIICFzCCAXagAwIBAgIGAVv2sEBIMAwGCCqGSM49BAMEBQAwLzELMAkGA1UEBhMCRVUxIDAeBgNVBAMTF1BheW1lbnQgTmV0d29yayBTdWIgQ0EzMB4XDTE3MDEwMTAwMDAwMFoXDTIyMDcxMDA5NTk1OVowMTELMAkGA1UEBhMCRlIxDTALBgNVBAUTBDQ1MDExEzARBgNVBAMTCm15YmFuay5jb20wdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARLG0RWD3ePgvZsrtDyokNijrFG8_enem3KqZBpidlEflRt7ZPZGiAYyX4cdlFNgw5m7xvXqVP5zlWy0Lgf1YDbwu9wuV4Tpq4_4D0Ovvq67wwjliM4YfrgwlkWzA5fxXOjXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH_BAQDAgP4MB0GA1UdDgQWBBTQO94DFLOKPXTXYE765IxdtV9LNTAfBgNVHSMEGDAWgBQTRrd3etVZI1YQdQFC63ncCTQ3iTAMBggqhkjOPQQDBAUAA4GMADCBiAJCAdhQcR9-ejA0ZgCTd9_b94F3DtGoz9fM0G1L7D2F_mmpk7I2uBqat2tET8ESvL1A6JyGKcovXvd-1BCMqRwawKK6AkIB8sAGpJCoh1wTrTXETa4l4aZGoxnMK6-e1BWeCRZ1o08RxoZYVg0COyX2etAOGYoHDRkjUGHv9PMylFmt5ZyWg0E",
      "MIIDtTCCAZ2gAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAwMQswCQYDVQQGEwJVUzEhMB8GA1UEAxMYUGF5bWVudCBOZXR3b3JrIFJvb3QgQ0ExMB4XDTE2MDcxMDEwMDAwMFoXDTI1MDcxMDA5NTk1OVowLzELMAkGA1UEBhMCRVUxIDAeBgNVBAMTF1BheW1lbnQgTmV0d29yayBTdWIgQ0EzMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAXt9fTiM4nZ9KPkzqOXrE1Ng7CthaAQ-m7DU1ULIfpK-n-vEsE1KqUhG5t_uqNpuBc3DhxsJ4V46EsE_6Q0IlFcAAS-p3J-1RBaKEo8eTqF8eC72GTiMuheictaAS9NT_IcsgEbXoNHwFbUxs0El2A-Boyh9BF_rja-XuQ-A1qgZ5_F-jYzBhMA8GA1UdEwEB_wQFMAMBAf8wDgYDVR0PAQH_BAQDAgEGMB0GA1UdDgQWBBQTRrd3etVZI1YQdQFC63ncCTQ3iTAfBgNVHSMEGDAWgBQE9W2T-nrW1SZqkrC0lUkcShmpvzANBgkqhkiG9w0BAQ0FAAOCAgEAbghYHRipnsMlY_unWECPIdDpqWlB4FvFtCKvPOdCTyu0HAVkN5foFEoecEuqhtLpSrHmMkNIJh33IqbZx00NYqDJ4DHoyv8lia3-pApec43p6_2CrC3fYV9Z8RmTO9cP3TIbeHLDdxNNXoI7kKlLdGsk63m6Tyl7kafTEsV8L8Loso_set0LwQPJJxBZJDnUGCauIEfLSGsLmDcW9oMPkUcSp2n5YwjTxFXOawZ5Rl04rS5KNgDaPyPT0FV-bI0ewRwzhn-_LDFLyhvlSltxEkwLEZFRlezPwQRo_rp8jea6APPVBQSC-B8MNPl8V3Whs_fmmWD1rcIl7VOaKaIR9-lwi2na-lctIEFg2tf8o9PYPf7MVyQ2OgOYPmB1qOJ8UCIOYJB6UxfZ-DTx4i3H4k3P-GcvGFWT5fg1DwapjrWkgEqS_ZXOQe3_r81-MSom2E-HcLjYQQhyoKy-GUzGvE21AQm9jBw3549HOCaT3FFTiE--aluX42HvuzAMIBAywnyQFK2g6o7F8-Ykne7aog3Q3oEMS6DzWVfs7TXZPW3sRz_UP54d3gyFezOjWlk-BhTPsFQ43340OuKFUH-D7n6Vr6sqpAUov4GjRMcjeTzIfw_qWPUamLgTFBNZ4bDpDH9FALvq9MTGFxvERcAxhit94491sV8SHz-IgMHmDdE"
    ],
    "value": "lGyVwh8CJN3cOz3C_meMQlVe62_uFCpLCh8PnOzki5r2QMI8JXc-eQhNMirrcV8VW09dQI93UsI5wJ4Avx_IUbCUsmnQGUuvcJWA-EueHqqoG-cHarjkAnPKCtmlsygT"
  }
}
EC key for verifying the subsequent object:
{
  "kid": "20170101:mybank:p521",
  "kty": "EC",
  "crv": "P-521",
  "x": "AKwELPGw-uyxNNMpqynB-71e-5GNMcLmFM0j0mbyVToRflwlWnXS-iAXxR_nOoWK426QoXlyNieyaWBQdwXrnKfj",
  "y": "AIgLgTCaxgKc461uMwFZ04qdBaVa9Wgy8VLNiHrZkKYL3Q_qmLTa9TKQgRThuCpcqlZFnhMPrPLgb3ev6rqCt0GS",
  "d": "AXfJ2R7ao8c2_gL9porCC1yR90w-R8MZ0HNjXcftOlkBD7njIFj7QAYlljJCkx7M3LJSeo5ha4Dg7mD0V1a_vhqr"
}
The following signature object can be verified by the public part of the key above:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "ES512",
    "publicKey": {
      "kty": "EC",
      "crv": "P-521",
      "x": "AKwELPGw-uyxNNMpqynB-71e-5GNMcLmFM0j0mbyVToRflwlWnXS-iAXxR_nOoWK426QoXlyNieyaWBQdwXrnKfj",
      "y": "AIgLgTCaxgKc461uMwFZ04qdBaVa9Wgy8VLNiHrZkKYL3Q_qmLTa9TKQgRThuCpcqlZFnhMPrPLgb3ev6rqCt0GS"
    },
    "value": "ACv1qHEjvXXDiz5DCm0eEKntHN71k73f7R8H3bTPHQJAimQfGWW_nwnQoQz28qEpzg8ULdNDKjzy4Z7CF7HAjkQeAB2-KA4KTgWxaUO1_sWde8QNNUaqqa4yGUufncpaMquBSV2Lae48Tejelt0oBqcXCfBJUS3Z0kNz5CYgOxpMf1Ri"
  }
}
The following signature object uses the same key as in the previous example but builds on that the key to use is implicitly known since the object neither contains a keyId, nor a publicKey property:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "ES512",
    "value": "AI80F7vVAmQi0noyKhOfmWf9aYYuOA4xlu4fOgQ9EcuE66J2hubfWTEpLHBbSgvvUXZUK4vSqE0cpDpYFjn3A31HADeaE7Q53wXi5SBR9dq6Z6PjbmjWLjTvp7gW53CLGPtroqSuwzisV2A2E1KBgYpaoVFOCR6umjA4-IpYEKFuClEo"
  }
}
The following signature object uses the same key as in the previous example but featured in a certificate path:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "ES512",
    "signerCertificate": {
      "issuer": "CN=Payment Network Sub CA3,C=EU",
      "serialNumber": "1494492398843",
      "subject": "CN=mybank.com,2.5.4.5=#130434353031,C=FR"
    },
    "certificatePath": [
      "MIICPTCCAZygAwIBAgIGAVv2sET7MAwGCCqGSM49BAMEBQAwLzELMAkGA1UEBhMCRVUxIDAeBgNVBAMTF1BheW1lbnQgTmV0d29yayBTdWIgQ0EzMB4XDTE3MDEwMTAwMDAwMFoXDTIyMDcxMDA5NTk1OVowMTELMAkGA1UEBhMCRlIxDTALBgNVBAUTBDQ1MDExEzARBgNVBAMTCm15YmFuay5jb20wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABACsBCzxsPrssTTTKaspwfu9XvuRjTHC5hTNI9Jm8lU6EX5cJVp10vogF8Uf5zqFiuNukKF5cjYnsmlgUHcF65yn4wCIC4EwmsYCnOOtbjMBWdOKnQWlWvVoMvFSzYh62ZCmC90P6pi02vUykIEU4bgqXKpWRZ4TD6zy4G93r-q6grdBkqNdMFswCQYDVR0TBAIwADAOBgNVHQ8BAf8EBAMCA_gwHQYDVR0OBBYEFO8GeF_8KWXd_Pwd8Vl-tNegHY7tMB8GA1UdIwQYMBaAFBNGt3d61VkjVhB1AULredwJNDeJMAwGCCqGSM49BAMEBQADgYwAMIGIAkIAuIYm8VQ0FHJm8ObcJ1qBc_O3wS8aJyFMT-ZcrdbJu05RcT70qgOEMLuYdV7AoFelO0rC5VChV21nyTdkm_aefkECQgCL2hjiweKR8YSZvfWgmkQD3WYxLms7YvejhBUZD88MEIfcd__rsoB1GJiFMr9ML478Jvd-58D6-GHvKIgQvcyo0w",
      "MIIDtTCCAZ2gAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAwMQswCQYDVQQGEwJVUzEhMB8GA1UEAxMYUGF5bWVudCBOZXR3b3JrIFJvb3QgQ0ExMB4XDTE2MDcxMDEwMDAwMFoXDTI1MDcxMDA5NTk1OVowLzELMAkGA1UEBhMCRVUxIDAeBgNVBAMTF1BheW1lbnQgTmV0d29yayBTdWIgQ0EzMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAXt9fTiM4nZ9KPkzqOXrE1Ng7CthaAQ-m7DU1ULIfpK-n-vEsE1KqUhG5t_uqNpuBc3DhxsJ4V46EsE_6Q0IlFcAAS-p3J-1RBaKEo8eTqF8eC72GTiMuheictaAS9NT_IcsgEbXoNHwFbUxs0El2A-Boyh9BF_rja-XuQ-A1qgZ5_F-jYzBhMA8GA1UdEwEB_wQFMAMBAf8wDgYDVR0PAQH_BAQDAgEGMB0GA1UdDgQWBBQTRrd3etVZI1YQdQFC63ncCTQ3iTAfBgNVHSMEGDAWgBQE9W2T-nrW1SZqkrC0lUkcShmpvzANBgkqhkiG9w0BAQ0FAAOCAgEAbghYHRipnsMlY_unWECPIdDpqWlB4FvFtCKvPOdCTyu0HAVkN5foFEoecEuqhtLpSrHmMkNIJh33IqbZx00NYqDJ4DHoyv8lia3-pApec43p6_2CrC3fYV9Z8RmTO9cP3TIbeHLDdxNNXoI7kKlLdGsk63m6Tyl7kafTEsV8L8Loso_set0LwQPJJxBZJDnUGCauIEfLSGsLmDcW9oMPkUcSp2n5YwjTxFXOawZ5Rl04rS5KNgDaPyPT0FV-bI0ewRwzhn-_LDFLyhvlSltxEkwLEZFRlezPwQRo_rp8jea6APPVBQSC-B8MNPl8V3Whs_fmmWD1rcIl7VOaKaIR9-lwi2na-lctIEFg2tf8o9PYPf7MVyQ2OgOYPmB1qOJ8UCIOYJB6UxfZ-DTx4i3H4k3P-GcvGFWT5fg1DwapjrWkgEqS_ZXOQe3_r81-MSom2E-HcLjYQQhyoKy-GUzGvE21AQm9jBw3549HOCaT3FFTiE--aluX42HvuzAMIBAywnyQFK2g6o7F8-Ykne7aog3Q3oEMS6DzWVfs7TXZPW3sRz_UP54d3gyFezOjWlk-BhTPsFQ43340OuKFUH-D7n6Vr6sqpAUov4GjRMcjeTzIfw_qWPUamLgTFBNZ4bDpDH9FALvq9MTGFxvERcAxhit94491sV8SHz-IgMHmDdE"
    ],
    "value": "AQph0r2mvuffE3lxfJUt2XL6ZctNb1Z8TvM1qdweAUefLo7PIHJ77dv8xAhd3J-qF5_uwqfrjHTNxX5dUEiDyvzJAK7oPv3PQwcGgd7N-9K403BrVnyYtCg0UIISAl6cANoeXMWe8l-ipRF36GUhJmVGN58mWF9xlV5S6_78HUo8HwnO"
  }
}
RSA key for verifying the subsequent object:
{
  "kid": "20170101:mybank:r2048",
  "kty": "RSA",
  "n": "oBq8_RJIJF9h2dm4r1kjBwv_W-G_YM-clG7GYwGWih3Y22HZnBmMn2Iqf4uXiwty9lICxrdBNcU6b79DY_GmNbA5j16dsuBIqZSq8yMtXfDpC8OS7Dy6OxjFyMZrA4IEqqjvDEmJC5aXoaBD3exECDvsRgB18jNoKyq2CDWgg22wuLz7I0B_T2tM26hPLRw8KfM8pQ1bPUcFn_nUKCrW7Wc2KIWGPwsPmL24VVctzhUWkr-nHuR_RKs2KAff0SYTpWElyEau7AqHiHAOhnPnGOxfb7r6V1AbDx-F95gSDFtoFPRWhNJDng1qHI23UD_7ONTGIK_I4I6y1rf7r26TDQ",
  "e": "AQAB",
  "d": "RbPeW38-ETfFbgavtQdljIfYoLPjkc5RKP4hOLFUTMU5yCkNiDxHUIx4XBb13v8ZCcwikUjvBu3axxPJzxVBe1ZBeP2EQoAKommrEzdZZPChRRHcQSUfHuNmGEbqCBju1y29BOhu1bC2SxNu-IsIA12zO7avosZmr4Rkw6Y1P4Ip67l-9D5KjCcQPfNpSwZzsvXd9AAocpjFZXGOlrjOOnyIblx1IRlyo32_A4PWYniRl_sp26eNr5zGpib_QdU1SrXzuDQcqAmjgiibPeLls7rCvCT1BIBU0MBUzU34dI5lLlMuYWNSNIC6Oa1UYsNoQ1pQHp9H3sy5e0reekN7gQ",
  "p": "99e3Ckt9gVVEpjY4u6Tp9wjC0XPhYqntmq-4JVBIMaMDs87gUC8r7GGFpFfJaImTUxMB0Z442A8gCW7yqS_Xaq6-ddhSalAvb-LaNXpyPEfETNoOoKfa3TMQMe_J9nzv6OcD6Y43CpMOtZLJdrGxtiCytTGhILsAdees91tdw3k",
  "q": "pV_BHdUqnbMTRF8hoYr_f2_9DXe_XYITU1bWlp2Izj8zySuOI4dusrGQIOY8ZFhc-fA_mBICrFlNrPdDv909FP3bJ9MsGrlxsFvLojiiRs4jPcUDqLynOVPrrQ7HWDoMjawfnTGX7LUe8gf-e4yTsq0WXvMCrulBgPG7Sla0MzU",
  "dp": "uVO27Z3RdZq7QMae2cHRqgYFF_Zc_RgwMlFfk5daxLMvG4-AsLT1VUb_VgrG8sKdRaua2pJD01xMCoHKNrUtkfqlNR3TUugu8K1jmkW7klPf98--zGd4A5whahXyobx-8Vt903GiuueIQkJHH9h0GMqOl2tLH1x2VbQt5LGPhZE",
  "dq": "mJ-a1zGYtxpCOeOiYjiqPK7aWMefcWlO9Kc8PJz_WXmzDYKJF_kyDPEbF4HlUqbKiFFWH77fgLiam3tIp5ZDfVAcJtEZ70Ae0KincvvZqIcutx9QlTYnDx2IcJsnFyHb3BRyyNywXeF6wdzm3JeM6GYeM1sLqunTbnGqbJ1AidE",
  "qi": "73MikBETtdyRa37zKeQc-RtPkWhj4HUyQSSNcYyXnCJmPGLt4LFAo2YMp11w7Y_9cOOo5rI3N4LLuGFfOZ9ecCxCP86NUWKY05DrjGnHUvTcmKDlbxEIMnGES0uoykxMoa5-hYjdcd3AgxOQ-EPV6ZipedP0UZmEfNPoZJbKbQc"
}
The following signature object can be verified by the public part of the key above:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "RS256",
    "publicKey": {
      "kty": "RSA",
      "n": "oBq8_RJIJF9h2dm4r1kjBwv_W-G_YM-clG7GYwGWih3Y22HZnBmMn2Iqf4uXiwty9lICxrdBNcU6b79DY_GmNbA5j16dsuBIqZSq8yMtXfDpC8OS7Dy6OxjFyMZrA4IEqqjvDEmJC5aXoaBD3exECDvsRgB18jNoKyq2CDWgg22wuLz7I0B_T2tM26hPLRw8KfM8pQ1bPUcFn_nUKCrW7Wc2KIWGPwsPmL24VVctzhUWkr-nHuR_RKs2KAff0SYTpWElyEau7AqHiHAOhnPnGOxfb7r6V1AbDx-F95gSDFtoFPRWhNJDng1qHI23UD_7ONTGIK_I4I6y1rf7r26TDQ",
      "e": "AQAB"
    },
    "value": "SKD9TahvJNN0QGYNZQT22Z8ODxnyMFQAPEhG_bvAi_xwEnaIZKK_OAYx3AYFq2dJRK2OUd2OsiLoDTg64ZmgM1WlXuTqZVISim99ySlpSE3aaisHBQxojWwBgJRNgwYcreDxARewZmWg4DlM2BtjuX6kXaoOhI5p1XBYzkSdfzrKtDQnyUrovyhpfLeWp4uyG6IQ0epI8UmCuT-rbOVPOShZYzLCG9Eqf1pxLm6q6eU17PXaenN_vFk98QHeE06WQaS8Iop2rmkyabwVQNDGIpujSSma2qnLQ0xyWdm5g5LZs2nDtv3NlLeuuEyMHZd3L56eJ74m0NX_GC4yoS4C4w"
  }
}
The following signature object uses the same key as in the previous example but featured in a certificate path:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "RS256",
    "signerCertificate": {
      "issuer": "CN=Payment Network Sub CA3,C=EU",
      "serialNumber": "1494492400585",
      "subject": "CN=mybank.com,2.5.4.5=#130434353031,C=FR"
    },
    "certificatePath": [
      "MIICxDCCAiSgAwIBAgIGAVv2sEvJMAwGCCqGSM49BAMEBQAwLzELMAkGA1UEBhMCRVUxIDAeBgNVBAMTF1BheW1lbnQgTmV0d29yayBTdWIgQ0EzMB4XDTE3MDEwMTAwMDAwMFoXDTIyMDcxMDA5NTk1OVowMTELMAkGA1UEBhMCRlIxDTALBgNVBAUTBDQ1MDExEzARBgNVBAMTCm15YmFuay5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgGrz9EkgkX2HZ2bivWSMHC_9b4b9gz5yUbsZjAZaKHdjbYdmcGYyfYip_i5eLC3L2UgLGt0E1xTpvv0Nj8aY1sDmPXp2y4EiplKrzIy1d8OkLw5LsPLo7GMXIxmsDggSqqO8MSYkLlpehoEPd7EQIO-xGAHXyM2grKrYINaCDbbC4vPsjQH9Pa0zbqE8tHDwp8zylDVs9RwWf-dQoKtbtZzYohYY_Cw-YvbhVVy3OFRaSv6ce5H9EqzYoB9_RJhOlYSXIRq7sCoeIcA6Gc-cY7F9vuvpXUBsPH4X3mBIMW2gU9FaE0kOeDWocjbdQP_s41MYgr8jgjrLWt_uvbpMNAgMBAAGjXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH_BAQDAgP4MB0GA1UdDgQWBBQdQK8rMT47vQ3jckD9a7rtWay9VzAfBgNVHSMEGDAWgBQTRrd3etVZI1YQdQFC63ncCTQ3iTAMBggqhkjOPQQDBAUAA4GLADCBhwJBAwwUu_xDa2VZndcos1TZ6OfkHw-6qxQk1rCV6fxy3LzDXRJeWJoOfDMhHBz78mH_DD65JvuPgNZggQ8XNsiKTQgCQgDFaQ4M-jenftprkztNkTbuoGbXuzP6riiStJzH6cmgC4ivGDeQ-u4zTD2Wx9DoEMNlN2qa4jBjn3PQD4e_CmqyFA",
      "MIIDtTCCAZ2gAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAwMQswCQYDVQQGEwJVUzEhMB8GA1UEAxMYUGF5bWVudCBOZXR3b3JrIFJvb3QgQ0ExMB4XDTE2MDcxMDEwMDAwMFoXDTI1MDcxMDA5NTk1OVowLzELMAkGA1UEBhMCRVUxIDAeBgNVBAMTF1BheW1lbnQgTmV0d29yayBTdWIgQ0EzMIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAXt9fTiM4nZ9KPkzqOXrE1Ng7CthaAQ-m7DU1ULIfpK-n-vEsE1KqUhG5t_uqNpuBc3DhxsJ4V46EsE_6Q0IlFcAAS-p3J-1RBaKEo8eTqF8eC72GTiMuheictaAS9NT_IcsgEbXoNHwFbUxs0El2A-Boyh9BF_rja-XuQ-A1qgZ5_F-jYzBhMA8GA1UdEwEB_wQFMAMBAf8wDgYDVR0PAQH_BAQDAgEGMB0GA1UdDgQWBBQTRrd3etVZI1YQdQFC63ncCTQ3iTAfBgNVHSMEGDAWgBQE9W2T-nrW1SZqkrC0lUkcShmpvzANBgkqhkiG9w0BAQ0FAAOCAgEAbghYHRipnsMlY_unWECPIdDpqWlB4FvFtCKvPOdCTyu0HAVkN5foFEoecEuqhtLpSrHmMkNIJh33IqbZx00NYqDJ4DHoyv8lia3-pApec43p6_2CrC3fYV9Z8RmTO9cP3TIbeHLDdxNNXoI7kKlLdGsk63m6Tyl7kafTEsV8L8Loso_set0LwQPJJxBZJDnUGCauIEfLSGsLmDcW9oMPkUcSp2n5YwjTxFXOawZ5Rl04rS5KNgDaPyPT0FV-bI0ewRwzhn-_LDFLyhvlSltxEkwLEZFRlezPwQRo_rp8jea6APPVBQSC-B8MNPl8V3Whs_fmmWD1rcIl7VOaKaIR9-lwi2na-lctIEFg2tf8o9PYPf7MVyQ2OgOYPmB1qOJ8UCIOYJB6UxfZ-DTx4i3H4k3P-GcvGFWT5fg1DwapjrWkgEqS_ZXOQe3_r81-MSom2E-HcLjYQQhyoKy-GUzGvE21AQm9jBw3549HOCaT3FFTiE--aluX42HvuzAMIBAywnyQFK2g6o7F8-Ykne7aog3Q3oEMS6DzWVfs7TXZPW3sRz_UP54d3gyFezOjWlk-BhTPsFQ43340OuKFUH-D7n6Vr6sqpAUov4GjRMcjeTzIfw_qWPUamLgTFBNZ4bDpDH9FALvq9MTGFxvERcAxhit94491sV8SHz-IgMHmDdE"
    ],
    "value": "jeAU4mL-D_oVSE4PvYeZeJWhavC3SOt9qH9In9Q5rveGgRogqyxVv8n8EAKYIvlYuWzn0dcv9bYgnKYRg-ZLEG1loxeNz-NR4D1eE75E7JCUGVXjBT2GQWhO8iJORGFtVWfh8OUnGIpduLh--H7u6hqXIIJD6ajT4-YEtEwxLVAnhH18YIO9qx2LiawQ3888OHIFtr3KUaf41txKxe75L7M8uiFr7T3DXXHmM4PBTYdCAP2jEfiRfe8yLw8uxxlJXNiy2mN1yMF89msXxoZYr_wFBmbwFQ8hdlW2wih7zbLrCl1OXtmIRz069beKCX-a3QJSFUwdfThOybO_VVdxwA"
  }
}
The following signature object is referring to a remoteKey which in turn should be identical to the key used in the previous RSA examples:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "RS256",
    "remoteKey": {
      "uri": "https://cyberphone.github.io/doc/openkeystore/r2048.jwk",
      "format": "JWK-PUB-KEY"
    },
    "value": "EPIURyLoT6bi9JNvHZKgBBxdczLjt9Cw6iafkgNkTD1W6ib74Pxy0LRrUhJctTZLuNB0UGdXJR1zuCMSn6XNd7CxBkpV1jkwy6S-9C0ms-Gpa4p-MlrZdOLwGDHhYjniV_2INRiLXgZk4Vj2uUbmE700d_yTR3vWXhQjvCZuQGQQGsP2lz3wpQxIAvl7zxteQgIwBw-bmh_h5RBYFY12h5pelDseDkVZkeCFydRHSL05hgkZ_BKziMiZ1LclIrxgtg7vDj6YVPYbxqvrhJn9kjs1LC7S498p44sFCZ3BXhsGf6t8LxKLBhpuU1YqVFI4UxXi8pX3PloyQ3nZj53iSg"
  }
}
HMAC key named "s256bitkey" here provided in Base64URL notation:
f92FGjudLa_F8NAAMOIrk0OQDNQu3klIVopKLuZVKRo
Signature object requiring the key above for validation:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "HS256",
    "keyId": "s256bitkey",
    "value": "XjcYdnda0l2eng625fSqbkPe7bRarHksa5m7lRhpkwU"
  }
}
HMAC key named "s384bitkey" here provided in Base64URL notation:
N7fa7tw0A-uGWlBsGVl6N1gq1QWeCEOK2ov1RO5EuzAkoV-PoZG756UzpWyfwdsd
Signature object requiring the key above for validation:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "HS384",
    "keyId": "s384bitkey",
    "value": "lmYpsMW5GnvV1wtE7fJdenxyO-cV_fPyFbNotC35CrvEBkI4_w3pUDWB1Qt2V_VP"
  }
}
HMAC key named "s512bitkey" here provided in Base64URL notation:
g9JulrcaXddnwhXyAe9YhPsD3-Wo7pYS1OPJQuhNRd_cWAHLg3mVjzr2ANaOuhoU6UXJDxZVZx8ELOp7NNUyNg
Signature object requiring the key above for validation:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "algorithm": "HS512",
    "keyId": "s512bitkey",
    "value": "Ar0obOHcCi9ry3PqEla4ltBF9Jd1y2qu_IjnznBHylG9-1WuarhUoVlDqTuwiYDtuFvjqAW_2ns55rAzG_l68Q"
  }
}
The following is a multiple signature (see Multiple Signatures) using the "20170101:mybank:p256" and "20170101:mybank:r2048" keys:
{
  "now": "2017-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signatures": [
    {
      "algorithm": "ES256",
      "publicKey": {
        "kty": "EC",
        "crv": "P-256",
        "x": "_gow8fcS3Dx9z6j57U5q8tunnRBdrgLU9A7CZTYCnqU",
        "y": "bdfJGraBVL5aPj38TG4tHwxpU2VKwG1XBp0wQfCLOFQ"
      },
      "value": "9Y-zE1B88sBMtHNYgtTp2YwmPIj42guyp-8KR2e2Cwz_1PnT6Nwh7e2A49fhrwfRJCCnUhSM6J3wbGQ34UGNeQ"
    },
    {
      "algorithm": "RS256",
      "publicKey": {
        "kty": "RSA",
        "n": "oBq8_RJIJF9h2dm4r1kjBwv_W-G_YM-clG7GYwGWih3Y22HZnBmMn2Iqf4uXiwty9lICxrdBNcU6b79DY_GmNbA5j16dsuBIqZSq8yMtXfDpC8OS7Dy6OxjFyMZrA4IEqqjvDEmJC5aXoaBD3exECDvsRgB18jNoKyq2CDWgg22wuLz7I0B_T2tM26hPLRw8KfM8pQ1bPUcFn_nUKCrW7Wc2KIWGPwsPmL24VVctzhUWkr-nHuR_RKs2KAff0SYTpWElyEau7AqHiHAOhnPnGOxfb7r6V1AbDx-F95gSDFtoFPRWhNJDng1qHI23UD_7ONTGIK_I4I6y1rf7r26TDQ",
        "e": "AQAB"
      },
      "value": "b4TKIx1VHJ_d-AWBC2eGbcmsZ04HoHkmiD8H_4Dckgut7dXVCKGOOwGHmn8fh-4pyufj4Ub6pj6vXnYSngiCVOyqUWDPusLFk5hC6b8Bi9mUvTsd6a99H0F_WdSe3OkL_K3H7VQLFH-yjTgGku9LvchLYEx_31Y21vP3UO3YKkKWJYYai537OzAiJv9Y8_5ZzwmYx8WtNFfX4q2Y1xolwQmT1bbxaMZ1rKgmub8baBc26ES9GCiGQeE37IzL-pNXGPNFBDWbSWn596AfCUi45U8nhOeRmiXGk0m3PpNFIU9ZAdMOM5pDjs_HdV4pMG-_7dvVoKnv6hvGSrarb_FIBQ"
    }
  ]
}
The certificate based signatures share a common root (here supplied in PEM [RFC7468] format), which can be used for path validation:
-----BEGIN CERTIFICATE-----
MIIFPjCCAyagAwIBAgIBATANBgkqhkiG9w0BAQ0FADAwMQswCQYDVQQGEwJVUzEhMB8GA1UEAxMY
UGF5bWVudCBOZXR3b3JrIFJvb3QgQ0ExMB4XDTE1MDcxMDEwMDAwMFoXDTMwMDcxMDA5NTk1OVow
MDELMAkGA1UEBhMCVVMxITAfBgNVBAMTGFBheW1lbnQgTmV0d29yayBSb290IENBMTCCAiIwDQYJ
KoZIhvcNAQEBBQADggIPADCCAgoCggIBALeOSacU7QdPttNbR6CqRfZrwiRNT5P9dxpJJGc/Gv4k
3Vigz+eK8DaguAJS0jDdhK7uzi5aOsf066U8ygbYdWvgigNTuuiX8T/rUBe+Xiy0pPKC9ivVem1o
zTtjed19cBWeoihcJQRyRdgek8oMeB4ShyoFZpV6ptraY0SGN4XkwjqHVakkoiX0nkQdlpW9D2Zm
HxDinZWOxBTxHchH66BHX6dDeg6QcPGA7qp6hHsJpUVe/n0F1eRHyuUh8opy+qNjpBuPAJ3DJMwL
ahlRY/7iNU0OJXgngUmsRz+yeUNq5ijzh3wdhJDvpj0J4ircaPsLhLlDvfLQ5rEajaABX/QpXkON
ox8yfIZYFhSgKOEP8anfCoCz3afnpd2CQCZ/zmzOOCIum20F4lcOrTndDVRIIRrz/4tXRKeA3k/A
QWUSHPSsatpITjtKgbDv5o+YfKYesxzL/yoeYPBOiwN1wE3+VfWRK809RVoHmW9do+GKCub3Xc7P
Ae35nLJSu+oP8cnU4pi/rcRx+9Hfua2HhOwzOQ4oDrRReJMBrpaPrQVR/KNC+NDOSOilAEdUmRtJ
BflijQyathXbiAk0l+QTAsshysb/cjPQPTP1qS3OlpjOvWY2ztB7oDFaltfaaVQvj2u7UfvMZ85u
HNQ/tbYYURGBWCTCm2Pf81S98NhslctrAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P
AQH/BAQDAgEGMB0GA1UdDgQWBBQE9W2T+nrW1SZqkrC0lUkcShmpvzAfBgNVHSMEGDAWgBQE9W2T
+nrW1SZqkrC0lUkcShmpvzANBgkqhkiG9w0BAQ0FAAOCAgEArV8eDz06juudum+sQhMZHhB0sci9
w1DB7dRVJ7PsSssSMHwOn0cz3CzTIprb7g5xLro3coOQO3KfJg6t/SrTXTiBdv3nNeFOAmHBCeya
2tzCjSQCXlHj00RWYwzw53RhKCcUEK/XgsBoP5osi9l5jBD9v+CRogZJNr4LJ+Dkc3c8w4p6FezQ
Adc07xyxoji3xatq2vRaUW6RD5LDftnuuz7XeOWu0K8uFxd/lYU1y3c3F+0QLTxpSK+33YIZswhg
Q4OP4GC6qNOPFUdYj8mOb5EiIinnx1GV/QKJvYHA5LF8U5uEeV1BzxUACBOLSxMoigZYq3s0f7Ae
GNu6ZbzQMGdXaN4vzcUNU45waN9G45p0hlgMMxFxOSDhUHDyMpfJx8um1hC9PeIWD1yCx+drJx7G
GHzAZi4aEfntwbFEffjySIa6JZddlVCoAT+ScGzUxpVSwWCozSNsY8+ohqc0Dh8pdiqpuZA3ndsu
2NOwYlnhzXV9mCiSJvkqGIvZ8JyiLVixzjQvztWunFbyMujNnb+5vF/uLgp4WYsOYhicwh83a3on
a0YirxX/fYrnFAwriAsop0wuubm9VwPkjFhgSg/WSRev4TBReFT3UGgWt4qzUYhgJTpjATzuXTgo
oWnLQxEU/YmcVaY2YyhOhnJpa5jrg3H7nPKC8qphGHE70Wc=
-----END CERTIFICATE-----
Appendix B: ECMAScript Mode
ECMAScript mode in this context refers to the ability to sign JavaScript objects as well as using the standard JSON support for parsing and creating signed data.
The code snippet below shows a signed JavaScript object:
var signedObject = {
  // The data
  statement: "Hello signed world!",
  otherProperties: [2000, true],
  // The signature
  signature: {
    algorithm: "ES256",
    publicKey: {
      kty: "EC",
      crv: "P-256",
      x: "vlYxD4dtFJOp1_8_QUcieWCW-4KrLMmFL2rpkY1bQDs",
      y: "fxEF70yJenP3SPHM9hv-EnvhG6nXr3_S-fDqoj-F6yM"
    },
    value: "bEkQ2Owed_oe8MbZjSTXffHOINm2fV5y7GzmGwdH9JrP6fV57tjuxLHQD-wf9eOp-zpu2U_v3RZgaobBkt9rNA"
  }
};
This signature could be verified by the following code:
function convertToUTF8(string) {
  var buffer = [];
  for (var i = 0; i < string.length; i++) {
    var c = string.charCodeAt(i);
    if (c < 128) {
      buffer.push(c);
    } else if ((c > 127) && (c < 2048)) {
      buffer.push((c >> 6) | 0xC0);
      buffer.push((c & 0x3F) | 0x80);
    } else {
      buffer.push((c >> 12) | 0xE0);
      buffer.push(((c >> 6) & 0x3F) | 0x80);
      buffer.push((c & 0x3F) | 0x80);
    }
  }
  return new Uint8Array(buffer);
}

function decodeBase64URL(encoded) {
  var string = atob(encoded.replace(/-/g,'+').replace(/_/g,'/'));
  var buffer = [];
  for (var i = 0; i < string.length; i++) {
    buffer.push(string.charCodeAt(i));
  }
  return new Uint8Array(buffer);
}

function verifySignature(jcs) {
  // Perform JCS normalization
  var clone = Object.assign({}, jcs.signature);     // Clone "signature" child object
  var signature = decodeBase64URL(clone.value);     // Get signature value
  delete jcs.signature.value;                       // Remove signature "value" property from signed object
  var data = convertToUTF8(JSON.stringify(jcs));    // Get normalized JSON string (signed data)
  jcs.signature = clone;                            // Restore signed object
  // Perform the actual crypto, here using W3C WebCrypto
[WCRYPT]
  crypto.subtle.importKey('jwk', clone.publicKey,   // JCS public key is a JWK
                          { name: 'ECDSA', namedCurve: clone.publicKey.crv },
                          true, ['verify']).then(function(publicKey) {
    crypto.subtle.verify({ name: 'ECDSA', hash: { name: 'SHA-256' } }, 
                         publicKey, signature, data).then(function(result) {
      console.debug('Success=' + result);
    });
  });
}

verifySignature(signedObject);
Constraint when using JCS with ECMAScript
If numeric property names are used, they must be provided in ascending numeric order and inserted before possible non-numeric properties.
Appendix C: Counter Signatures
For counter signatures there are two entirely different solutions. One way dealing with counter signatures is using an application level counter signing solution like the following:
{
  "id": "lADU_sO067Wlgoo52-9L",
  "object": {"type": "house", "price": "$635,000"},
  "role": "buyer",
  "timeStamp": "2016-12-08T13:56:08Z",
  "signature": {
    
Original signature...
  }
}
Counter signed JSON object:
{
  "attesting": {
    "id": "lADU_sO067Wlgoo52-9L",
    "object": {"type": "house", "price": "$635,000"},
    "role": "buyer",
    "timeStamp": "2016-12-08T13:56:08Z",
    "signature": {
      
Original signature...
    }
  },
  "role": "notary",
  "timeStamp": "2016-12-08T13:58:42Z",
  "signature": {
    
Counter signature...
  }
}
For sophisticated peer based counter signature schemes another possibility is using Multiple Signatures, optionally including JCS extensions holding application specific (per signature) metadata.
Appendix D: Usage in Applications
JCS as well as the freestanding sub-objects publicKey and certificatePath, have been utilized in a proof-of-concept application [PKIDROID] running on Android.
The sample code below is based on the Java reference implementation [OPENKEY] which features an integrated JSON encoder, decoder and signature solution:
public void signAndVerifyJCS(PrivateKey privateKey, PublicKey publicKey) throws IOException {

  // Create an empty JSON document
  JSONObjectWriter writer = new JSONObjectWriter();

  // Fill it with some data
  writer.setString("myProperty", "Some data");

  // Sign document
  writer.setSignature(new JSONAsymKeySigner(privateKey, publicKey, null));

  // Serialize document
  String json = writer.toString();

  // Print document on the console
  System.out.println("Signed doc: " + json);

  // Parse document
  JSONObjectReader reader = JSONParser.parse(json);

  // Get and verify signature
  JSONSignatureDecoder signature = reader.getSignature(new JSONSignatureDecoder.Options());
  signature.verify(new JSONAsymKeyVerifier(publicKey));

  // Print document payload on the console
  System.out.println("Returned data: " + reader.getString("myProperty"));
}
Appendix E: Interoperability
Since serialization of floating point numbers as specified by JCS is (at the time of writing) not available for all platforms, you may for highest possible interoperability need to put such data in quotes. Albeit a limitation, financial data is not natively supported by JSON either due to the fact that JavaScript lacks support for big decimals. Note the handling of certificate serial numbers in JCS.
JCS compatible reference implementations are available both for server Java and Android [OPENKEY]. These implementations use ECMAScript number serialization when creating JSON data, making them compliant with browsers and Node.js as well.
Pyhton users can get the required parser behavior (modulo floating point data...) by using the following constructs:
jsonObject = json.loads(jcsSignedData,object_pairs_hook=collections.OrderedDict)       # Parse JSON while keeping original property order
signatureObject = jsonObject['signature']                                              # As described in this document
clonedSignatureObject = collections.OrderedDict(signatureObject)                       # For non-destructive signature validation
signatureValue = signatureObject.pop('value')                                          # In Base64URL notation
normalizedSignedData = json.dumps(jsonObject,separators=(',',':'),ensure_ascii=False)  # In Unicode
jsonObject['signature'] = clonedSignatureObject                                        # Restore JSON object
... Signature Validation Code ...
Appendix F: Acknowledgements
During the initial phases of the design process, highly appreciated feedback were provided by Manu Sporny, Jim Klo, Jeffrey Walton, David Chadwick, Jim Schaad, Mike Jones, David Waite, Douglas Crockford, Arne Riiber, Brian Campbell, Sergey Beryozkin, and others.
Special thanks go to James Manger who pointed out the ECMAScript [ES6] number serialization scheme as well as reviewing a related Internet draft.
An early prototype was funded by PrimeKey Solutions AB and the Swedish Innovation Board (VINNOVA).
Appendix G: References
ReferenceDescription
[ES6]A. Wirfs-Brock, "ECMAScript 2015 Language Specification", ECMA-262, June 2015.
https://www.ecma-international.org/ecma-262/6.0/ECMA-262.pdf
[JEF]A. Rundgren, "JEF - JSON Encryption Format", Work in progress, V0.51, May 2017. https://cyberphone.github.io/doc/security/jef.html
[OPENKEY]"OpenKeyStore Project", https://github.com/cyberphone/openkeystore
[PKIDROID]"WebPKI Suite", https://play.google.com/store/apps/details?id=org.webpki.mobile.android
[RFC3986]T. Berners-Lee, R. Fielding, L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", RFC 3986, January 2005. https://tools.ietf.org/html/rfc3986
[RFC4514]K. Zeilenga, "Lightweight Directory Access Protocol (LDAP): String Representation of Distinguished Names", RFC 4514, June 2006. https://tools.ietf.org/html/rfc4514
[RFC4648]S. Josefsson, "The Base16, Base32, and Base64 Data Encodings", RFC 4648, October 2006. https://tools.ietf.org/html/rfc4648
[RFC5280]D. Cooper, S. Santesson, S. Farrell, S. Boeyen, R. Housley, W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, May 2008. https://tools.ietf.org/html/rfc5280
[RFC7159]T. Bray, "The JavaScript Object Notation (JSON) Data Interchange Format", RFC 7159, March 2014. https://tools.ietf.org/html/rfc7159
[RFC7468]S. Josefsson, S. Leonard, "Textual Encodings of PKIX, PKCS, and CMS Structures", RFC 7468, April 2015. https://tools.ietf.org/html/rfc7468
[RFC7515]M. Jones, J. Bradley, N. Sakimura, "JSON Web Signature (JWS)", RFC 7515, May 2015. https://tools.ietf.org/html/rfc7515
[RFC7517]M. Jones, "JSON Web Key (JWK)", RFC 7517, May 2015. https://tools.ietf.org/html/rfc7517
[RFC7518]M. Jones, "JSON Web Algorithms (JWA)", RFC 7518, May 2015. https://tools.ietf.org/html/rfc7518
[V8]"Chrome V8", Google Chrome JavaScript Engine, https://developers.google.com/v8/
[WCRYPT]"Web Cryptography API", R. Sleevi, M. Watson, W3C Candidate Recommendation, December 2014. https://www.w3.org/TR/WebCryptoAPI/
[XMLDSIG]D. Eastlake, J. Reagle, D. Solo, F. Hirsch, M. Nystrom, T. Roessler, K. Yiu, "XML Signature Syntax and Processing Version 1.1.", W3C Recommendation, April 2013.
https://www.w3.org/TR/2013/REC-xmldsig-core1-20130411/
[YASMIN]A. Rundgren, "YASMIN - Yet Another jSon Message notatIoN", Work in progress, V0.6, April 2017. https://cyberphone.github.io/doc/web/yasmin.html
Appendix H: Document History
DateVerComment
2013-12-170.3Initial publication in HTML5
2013-12-200.4Changed from Base64 to Base64URL everywhere
2013-12-290.5Added the extensions facility
2014-01-210.51Added clarification to public key parameter representation
2014-01-260.52Added note regarding the signerCertificate option
2014-04-150.53Embedded bigint in JS string making syntax fully JSON compatible
2014-09-170.54Changed canonicalization to normalization
2014-09-230.55Aligned EC parameter representation with JWS [RFC7515]
2014-12-080.56Removed [XMLDSIG] bloat and added support for JWA [RFC7515] algorithm identifiers
2014-12-190.57Added an interoperability section
2015-01-120.58Added clarification to signature value representation
2016-01-110.59Added ECMAScript compatibility mode
2017-04-190.60Changed public keys to use JWK [RFC7517] format
2017-05-180.70Added multiple signatures and test vectors
Appendix I: Author
JCS was developed by Anders Rundgren (anders.rundgren.net@gmail.com) as a part of the OpenKeyStore project [OPENKEY].