JOSE-JCS
 
JSON Cleartext Signature
Table of Contents
1. Introduction
2. Sample Object
3. Signature Scope
4. Normalization and Signature Validation
5. Notation
6. Data Types
7. JCS Objects
Top Level Property
signature
jwk
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 canonicalization method for JSON data. However, version 6 of ECMAScript [ES6] introduced a simple to support predictable serialization scheme enabling 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 uses the same properties as well as cryptographic algorithms [RFC7518].
Due to the ECMAScript heritage, 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 Object
The following cryptographically verifiable sample signature is used to visualize the JCS specification:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "ES256",
    "jwk": {
      "kty": "EC",
      "crv": "P-256",
      "x": "censDzcMEkgiePz6DXB7cDuwFemshAFR90UNVQFCg8Q",
      "y": "xq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeY"
    },
    "val": "P9CAfhPi4Jx9ZLOcUtZsFbTIyhWHc8D8RJKmOozT_Frz-CBIvyKe1ax7mSjbfruhjYz5Rxu4FL7eSi1ExiDCog"
  }
}
The sample signature's payload consists of the properties above the "signature" property. 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 "val" property (shaded area in the sample).
4. Normalization and Signature Validation
Prerequisite: A JSON object in accordance with [RFC7159] supplied as a textual string containing a top level "signature" property.
Additional input data constraints:The normalization steps are as follows:Note: A practical consequence of this arrangement is that the original property order is preserved. This is also compliant with ECMAScript JSON serialization as described in [ES6] section 9.1.12, albeit with the minor limitation outlined in ECMAScript Constraint.
Also see Interoperability.
Applied on the sample signature, a conforming JCS normalization process should return the following JSON string:
{"now":"2018-04-16T11:23:06Z","escapeMe":"$\u000f\nA'B\"\\\\\"/","numbers":[1e+30,4.5,6],"signature"
:{"alg":"ES256","jwk":{"kty":"EC","crv":"P-256","x":"censDzcMEkgiePz6DXB7cDuwFemshAFR90UNVQFCg8Q","y"
:"xq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeY"}}}
The text in red highlights the string normalization process. Note that the output string was folded for improving readability.
The signature supplied in the val property can now be validated by applying the algorithm specified in the alg property (together with the appropriate signature verification key), on the UTF-8 representation of the normalized textual 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 specifics of 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
stringstringArbitrary string
uristringURI [RFC3986]
byte[]stringBase64URL-encoded [RFC4648] binary data
byte2[]stringBase64-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.
"signature": [signature] 1-nobjectMandatory top level property for Multiple Signatures.
signature
PropertyTypeReqComment
"alg": "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.
"kid": "Identifier"stringOOptional. Application specific string identifying the signature key.
"jwk": jwkobjectOOptional. Public key object.
"jku": "URL"uriOptional. URI [RFC3986] which must be dereferencable by an HTTPS GET operation and pointing to a JWK [RFC7517] key set holding a single jwk object.
Also see test vector.
"x5c": ["Certificate Path"] 1-nbyte2[]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.
"x5u": "URL"uriOptional. URI [RFC3986] which must be dereferencable by an HTTPS GET operation and pointing to a PEM [RFC7468] file containing a 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.
Also see test vector.
"crit": ["Property List"] 1-nstringOOptional. Array holding the names of one or more application specific extension properties also featured within the "signature" sub object.
Extension names must not be duplicated or use any of the JCS reserved words "alg", "crit", "excl", "kid", "jwk", "jku", "x5c", "x5t", "x5t#s256", "x5u" or "val".
Extensions intended for public consumption are preferably expressed as URIs (unless registered with IANA), while private schemes are free using any valid property name.
A conforming JCS implementation must reject signatures listing properties that are not found as well as empty "crit" objects. Verifiers are recommended introducing additional constraints like only accepting predefined extensions.
Also see test vector.
"excl": ["Property List"] 1-nstringOOptional. Array holding the names of one or more properties featured on the same level as the "signature" property, that must be excluded from the signature process.
Note that the "excl" property itself, must also be excluded from the signature process.
Property names that are to be excluded from the signature process must not be duplicated or override the signature object label.
A conforming JCS implementation must reject signatures containing listed properties that are not found as well as empty "excl" objects. Verifiers are recommended introducing additional constraints like only accepting predefined properties.
Also see test vector.
"val": "Signature"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 "jwk", "jku", "x5c" or "x5u" property since the key may be given by the context or through the "kid" property.
jwk
PropertyTypeReqComment
"kty": "Key Type"stringMKey type indicator. Currently the following types are recognized:
Additional EC Properties
"crv": "Curve Name"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": "Coordinate"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": "Coordinate"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": "Modulus"cryptoMRSA modulus. Also see the crypto data type.
"e": "Exponent"cryptoMRSA exponent. Also see the crypto data type.
This object represents a subset of JWK [RFC7517].
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 Object was signed by the following EC private key in JWK [RFC7517] format:
{
  "kid": "example.com:p256",
  "kty": "EC",
  "crv": "P-256",
  "x": "censDzcMEkgiePz6DXB7cDuwFemshAFR90UNVQFCg8Q",
  "y": "xq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeY",
  "d": "nEsftLbi5u9pI8B0-drEjIuJzQgZie3yeqUR3BwWDl4"
}
The following signature object which uses a kid for identifying the public key can be verified with the key above:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "ES256",
    "kid": "example.com:p256",
    "val": "c0MUPa6lhU85uknJf7Nv9MQPaeyY2_3IcoRTMc8xFE_aJhwj538p3oi9cyw1LBuWbNnR1QSAGIhCTvZzkuo3MQ"
  }
}
The following signature object uses the same key as in the previous example but also includes crit extensions:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "ES256",
    "jwk": {
      "kty": "EC",
      "crv": "P-256",
      "x": "censDzcMEkgiePz6DXB7cDuwFemshAFR90UNVQFCg8Q",
      "y": "xq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeY"
    },
    "crit": ["otherExt","https://example.com/extension"],
    "otherExt": "Cool Stuff",
    "https://example.com/extension": {
      "life-is-great": true
    },
    "val": "ufDLMh3ql579gmChxdjrsDcB72Nbgr5X4msjmxrFtP7_ZXHbOj0lDYGU-dYS8gLZWGP6_-PufyT_S3xapNLVuA"
  }
}
The following signature object uses the same key as in the previous example but also specifies excl properties:
{
  "mySignedData": "something",
  "myUnsignedData": "something else",
  "signature": {
    "alg": "ES256",
    "jwk": {
      "kty": "EC",
      "crv": "P-256",
      "x": "censDzcMEkgiePz6DXB7cDuwFemshAFR90UNVQFCg8Q",
      "y": "xq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeY"
    },
    "excl": ["myUnsignedData"],
    "val": "HQ_LCXoY3SUxd0sTY8pjlUU28-wbT1MME_AXndKsyeyy5uAG1jZpL9f_eNG2FrqLpFiQKJgruVPl5az8LGIbLw"
  }
}
The following signature object uses the same key as in the previous example but featured in a certificate path:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "ES256",
    "x5c": [
      "MIIB+TCCAVigAwIBAgIGAWFcc4YkMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNVBAMTFVRydXN0IE5ldHdvcmsgU3
ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTlaMDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGF
tcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABHHp7A83DBJIInj8+g1we3A7sBXprIQBUfdFDVUBQoPExq8rze6ewG0+eVcSF72J
77gKiD0IHnzpwHaU7t6nVeajXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQDAgP4MB0GA1UdDgQWBBQQyJ9rXSIskoUuA946von62LoxqzAfB
gNVHSMEGDAWgBTUWrS54qC2NgG3UK6rVAr0gbQ0MTAMBggqhkjOPQQDBAUAA4GMADCBiAJCAaWoVQ0r6jFjhO5e0WJTgyMmA8BhpO1t7gXQ6x
oKGso9jCOYf9OG9BFfZoVmdIyfYiwkhy1ld27tiOJ5X4m6WasRAkIBpEkUDf8irbSZ1V7zXALaR2mJTjKQV/5jRHsiBQWA+5DxEa+x/zJVRz8
tpp+jjT2tSCU82bwUOBLu6te1YIDpWCA=",
      "MIIDsTCCAZmgAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMWVHJ1c3QgTmV0d29yayBSb290IE
NBMTAeFw0xNjA3MTAxMDAwMDBaFw0yNTA3MTAwOTU5NTlaMC0xCzAJBgNVBAYTAkVVMR4wHAYDVQQDExVUcnVzdCBOZXR3b3JrIFN1YiBDQTM
wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAGJzPZsjniwyZeXrgrlQM3Y13r3znR8FSQpKbC2bplrOWySQJPGm+GFObe5Dk4t3Jrtk/Pbs8+3
VW/4q5drL0YqYwBYNJPhqjbSM6SGHrc6wNdPZRw/WnJVa0ELXKICC73lkjskWPfE+cLpZ3sTq1ovEmoNjgaySVRUH1wFDdkqyReJaKNjMGEwD
wYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNRatLnioLY2AbdQrqtUCvSBtDQxMB8GA1UdIwQYMBaAFEkmC1HDAh
0fXehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQAs2KADYyGQCVy8tJZWakNtGdww4OumZpBuR66p/2xK7veRubQEhG+nJn7oVkJ4w5p
Eec3sYQEqtPbHyZcEKEYbOJ2cVf1nMH+DvFZ6ypQocGRp3WSWsTzL3SgqiWrQdPX1Y5dO6Hvx7p9ST9H2WgkxB+Q75Jov1gVF3bScAbxb7Mw7
tf5z3Cvqmfo0Gatkgzz6+jDPrtUK7AAAOw3C0kHMbE3EnNarsfhBkUerE8QVmHIvz373mWt0SnguaHq0A9ZuSia/pF7bgfVRZi2ZzIzpu2O27
6sB2Yji9tcSn5l21jq63rXtvY/DLAi4kaLyf9sHT/tkH+gkTdkdkfQq8sA5ysRW21wPQbmjTIVwsfY4JjajVIUitjPbkUJqURpf2VD0JXdYQH
S6KVPWqHWTlKPlsKbhw4ghuLqCMYda88L9rxWnSC5L8s0DJSuBBm+nq23NtHl5FbCzeXWcKRayIgimT+An1WIOeJP4F7+BctYLIooKoQzJZR1
tOWvprUs22/xAivVBz7J/LmJyVlKesB2ic8qYdt7YVoCsWrnEUgoNoJPwLHeva8KPvd0gLXrwaMyTCCjeoemXFj6nCbbMHJeVffh6jYBAzlbc
AEvTiZcdzrVVr54kOtWskyaeDnAcMXW4Of1vWdUJ2as5nyfletfTp4E6A9P2dZ5g7nMoL90yIw=="
    ],
    "val": "hdTK8EtyprGjZEEobL8lBsboVya8qXytZeRLRgxS17a5AJ8F7bCkU18YeWYafRrsxzCES5rpZTYEJ6JJ2O_W3Q"
  }
}
EC private key associated with the subsequent object:
{
  "kid": "example.com:p384",
  "kty": "EC",
  "crv": "P-384",
  "x": "GLfdsvEwphRzS_twup7UFPVOk7_CKgHZ7dt_fJ2QHPBdJa1c5pfJcRIWTfT0lpg9",
  "y": "ovA5_QXmFbj9U4pjZ1AX_ZdVyIRZUBWW9cuZda_tupKfWQfmcQHzDmHGHbxl9Xxl",
  "d": "Qsgq80kMs40sAn1gB7gLxAk1se37Kmh9AG18wWZ3SqgcPPRq1wwidNTi866Gt4_0"
}
The following object was signed by the key above:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "ES384",
    "jwk": {
      "kty": "EC",
      "crv": "P-384",
      "x": "GLfdsvEwphRzS_twup7UFPVOk7_CKgHZ7dt_fJ2QHPBdJa1c5pfJcRIWTfT0lpg9",
      "y": "ovA5_QXmFbj9U4pjZ1AX_ZdVyIRZUBWW9cuZda_tupKfWQfmcQHzDmHGHbxl9Xxl"
    },
    "val": "IFFLQOIijWyVnCAPgp4LSYuABW-34DKYLOQYDhdFAiPc02oN5JeH1KxhRSv9bDjPmXiEUe7T1xla0cqSENjW0zDRYErz4aztC
YiMl1K0fcaNEBXXmK8Fzv0H9eYfZkq8"
  }
}
The following signature object uses the same key as in the previous example but featured in a certificate path:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "ES384",
    "x5c": [
      "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"
    ],
    "val": "29NpsOak1af46HFQDGQ6NiPNvlx9xO8ujBfzlbFz2VdzkT_jCXOTAIjyWyr5oI0smM-lqbmfWK6dkwQXbquKCOt7aWUXKVbNO
XMLpd9YeZRka_m-04L904TSB1NxXGWk"
  }
}
EC private key associated with the subsequent object:
{
  "kid": "example.com:p521",
  "kty": "EC",
  "crv": "P-521",
  "x": "AT9Hw32aVQCGd5csltC1dqhSB4fFt-mEWO-QxZqrr9Yrwn69_q7n1YOYrHSWjk_qMkCGk6qQ4f9ZRYIJPGqjfxC9",
  "y": "AeVHV1elHFzR_P5Lzb22hMyhAzcGSTT1sdwVmFkJGBYt55RKXGNO1H9De2v_p5S-kkK8BZVh3JGzixMyT0Eo_ckS",
  "d": "AYSlWWbGUougMnE2r7pRkiHZfXBgUzaVTuWfE0X7PDYodsVXVzRiz4KMgfs5Xowwk2roUsbJV7wdyZ83qMrQM1Fv"
}
The following object was signed by the key above:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "ES512",
    "jwk": {
      "kty": "EC",
      "crv": "P-521",
      "x": "AT9Hw32aVQCGd5csltC1dqhSB4fFt-mEWO-QxZqrr9Yrwn69_q7n1YOYrHSWjk_qMkCGk6qQ4f9ZRYIJPGqjfxC9",
      "y": "AeVHV1elHFzR_P5Lzb22hMyhAzcGSTT1sdwVmFkJGBYt55RKXGNO1H9De2v_p5S-kkK8BZVh3JGzixMyT0Eo_ckS"
    },
    "val": "AM_nHbivA12Ps5NUQoduvF3PlyODTtRMVlg6DqcEtHaF0NsBtR8wrNfbPBUKEQp1S_WqjZ7RpZ5wxqzOtflMDxyCAJ-4wxZCa
bwqrlrVcGN-2DAdnDHNpxPDTw677JwX5slYM4iyrY4qqQlEe-siPLgByUV5zMc4C3eFsncEdNUGuybL"
  }
}
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 kid, nor a jwk property:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "ES512",
    "val": "AIo2Y4ILzSJ1Y9DI-h-FrRYF8g5NSyGdmMaJ7k7ClDuaD5OKkkVOGvGVYkWaxm3rUI3bUDZ9leZjI-A2UMCA_MuWAP3IO9ig4
Hax9cF1HC4W9ejOSgvQd2PMNC-3fHdKHMGbfy8ruflazzTxRqlvoptdTKK1YxH_sAFPY8cXIDxe1xfS"
  }
}
The following signature object uses the same key as in the previous example but featured in a certificate path:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "ES512",
    "x5c": [
      "MIICOzCCAZugAwIBAgIGAWFcc5MjMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNVBAMTFVRydXN0IE5ldHdvcmsgU3
ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTlaMDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGF
tcGxlLmNvbTCBmzAQBgcqhkjOPQIBBgUrgQQAIwOBhgAEAT9Hw32aVQCGd5csltC1dqhSB4fFt+mEWO+QxZqrr9Yrwn69/q7n1YOYrHSWjk/q
MkCGk6qQ4f9ZRYIJPGqjfxC9AeVHV1elHFzR/P5Lzb22hMyhAzcGSTT1sdwVmFkJGBYt55RKXGNO1H9De2v/p5S+kkK8BZVh3JGzixMyT0Eo/
ckSo10wWzAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwID+DAdBgNVHQ4EFgQUa+tPMR1eN/0bbadpgzj+C5t+fMswHwYDVR0jBBgwFoAU1Fq0ue
KgtjYBt1Cuq1QK9IG0NDEwDAYIKoZIzj0EAwQFAAOBiwAwgYcCQgFNJcVPfnQh7VeKnsXp1ay6oX9WSDN6RtTDAQ+4LZlIj8quUsKN7JH78fc
qJgB3no8s6+N6vkyNTdAUQuhnuqeS0AJBEIF9NuLOuIaQW7ZPR1x95OworMGyXq0vKonMnijD5utltRmhZLdwI+GVX5k0V2+cGoTBKp3K2uFH
PsTFVGSFRlU=",
      "MIIDsTCCAZmgAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMWVHJ1c3QgTmV0d29yayBSb290IE
NBMTAeFw0xNjA3MTAxMDAwMDBaFw0yNTA3MTAwOTU5NTlaMC0xCzAJBgNVBAYTAkVVMR4wHAYDVQQDExVUcnVzdCBOZXR3b3JrIFN1YiBDQTM
wgZswEAYHKoZIzj0CAQYFK4EEACMDgYYABAGJzPZsjniwyZeXrgrlQM3Y13r3znR8FSQpKbC2bplrOWySQJPGm+GFObe5Dk4t3Jrtk/Pbs8+3
VW/4q5drL0YqYwBYNJPhqjbSM6SGHrc6wNdPZRw/WnJVa0ELXKICC73lkjskWPfE+cLpZ3sTq1ovEmoNjgaySVRUH1wFDdkqyReJaKNjMGEwD
wYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNRatLnioLY2AbdQrqtUCvSBtDQxMB8GA1UdIwQYMBaAFEkmC1HDAh
0fXehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQAs2KADYyGQCVy8tJZWakNtGdww4OumZpBuR66p/2xK7veRubQEhG+nJn7oVkJ4w5p
Eec3sYQEqtPbHyZcEKEYbOJ2cVf1nMH+DvFZ6ypQocGRp3WSWsTzL3SgqiWrQdPX1Y5dO6Hvx7p9ST9H2WgkxB+Q75Jov1gVF3bScAbxb7Mw7
tf5z3Cvqmfo0Gatkgzz6+jDPrtUK7AAAOw3C0kHMbE3EnNarsfhBkUerE8QVmHIvz373mWt0SnguaHq0A9ZuSia/pF7bgfVRZi2ZzIzpu2O27
6sB2Yji9tcSn5l21jq63rXtvY/DLAi4kaLyf9sHT/tkH+gkTdkdkfQq8sA5ysRW21wPQbmjTIVwsfY4JjajVIUitjPbkUJqURpf2VD0JXdYQH
S6KVPWqHWTlKPlsKbhw4ghuLqCMYda88L9rxWnSC5L8s0DJSuBBm+nq23NtHl5FbCzeXWcKRayIgimT+An1WIOeJP4F7+BctYLIooKoQzJZR1
tOWvprUs22/xAivVBz7J/LmJyVlKesB2ic8qYdt7YVoCsWrnEUgoNoJPwLHeva8KPvd0gLXrwaMyTCCjeoemXFj6nCbbMHJeVffh6jYBAzlbc
AEvTiZcdzrVVr54kOtWskyaeDnAcMXW4Of1vWdUJ2as5nyfletfTp4E6A9P2dZ5g7nMoL90yIw=="
    ],
    "val": "AHB20-U8smIl0psfvvYxRptN7gZihQo9dlVAr6u3OI7x_QdBEzikHc_XdJjtxcWupaJFbCFvojC3kODrIpBdMiUhASKK0_OlN
J6YVxX32Q_7OH6jmX3HMISoTk-0A5SxxZoTtxSLlSVhILqrH9apB4B_LfYmEKCK1RAXtysD5mYW6aAG"
  }
}
RSA private key associated with the subsequent object:
{
  "kid": "example.com:r2048",
  "kty": "RSA",
  "n": "hFWEXArvaZEpSP5qNX7x4C4Hl28GJQTNvnDwkfqiWs63kXbdyPeS06bz6GnY3tfQ_093nGauWsimqKBmGAGMPtsV83Qxw1OIeO4uj
bIIb9pema0qtVqs0MWlHxklZGFkYfAmbuEUFxYDeLDHe0bkkXbSlB7_t8pCSvc8HLgHjEQjYOlFRwjR0D-uLo-xgsCbpmCtYkB5lcT_zFgpRg
Y4zJNLSv7GZiz2S4Fc5ArGjd34lL47-L8bozuYjqNOv9sqX0Zgll5XaJ1ndvr7UqZu1xQFgm38reoM3IarBP_SkEFbt_v9iak602VO3k28fQh
MaocP7JWR2YLT3kZM0-WTFw",
  "e": "AQAB",
  "d": "Q6iBYpnIrB2mkQZagP1lZuvBv9_osVaSZpLRvKD7DxhvbDTs0coaTJIoVCSB1_VZip8zlUg-TnYWF1Liv9VSwfQ7ddxrcOUtej60m
Id0ntNz2HhbxJsWjiru8EZoArl0nEovLDNxlRgRMEyZwOKPC_xHT6nFrk7_s9pR5pEEcubGLAVBKnLCoPdLr-CBjCvWfJo73W5AZxoSb8MdWQ
Oi5viXHURpr1Y_uBRsMuclovM56Vt05etMsB1AbcTLUDwAuYrZWa1c08ql60ft7b3v6Q_rCL7EHtFU3PHAuP0mV7tM5BfAPf4T0g9pbr4GOw7
eqQCiYgPFE7gmCR_PDxv5YQ",
  "p": "6DIM343hAtj1hQprJaVQ3T8YeIytIQ7Ma544C0A8BX-irjJfARy4fAlTSyBFeauZ0WdbMGtKpAIgNVmfCfuP7W1bXw7UaxpqsQlbw
54K1VtBs8xG-lee_2YQ3lUlIiC1at6L0jxWYNkvp-LIfU2F5ZQir5ZWVXwgdMcgoNBABMc",
  "q": "keacq0goV7pAtG2h33OAk-XOSclIF1agvEMMOKuud5V-vGQ6OaYldlYqZmSGgF7RVlX0GZO70nPqatjd2G-tI8wEq5K_xmLQurUPF
W8g___z0CTgJ62KbjFxCtGny5rsObX9im6cCc_EOtWZRaApzO8ykxfo1QcEjT4k1na7DzE",
  "dp": "nPmJPnFal2Q5x_GdMlwq6QhI8OaZ_OlWRcM3PFP2v_jj8ERZehUCm8hqKTXuAi2C1dC8E2XVlj9hqu-l10fcq7Tsurz52laHnpwn
D35-8HK7XmRR79jgwuUrrkN90S6vt0ow2La15s-tqiBlTmDkjqqxMGfAghZiktA0PMPNI-0",
  "dq": "D3c1lkZw2FPK9hVE-m3A7GyIwHOQq8CoCyzER-GS_eQf6hJpxaCiCfg6SF5Rj5v9brxvwqJRX46gA7F3WrED1m6S9Cj7ISlqXNBC
iBAenGRiUOcHx8zyhpnBFNeChOeoMLnk5V6yNawLbf0kYSgIJkwYvVTkfmhfCCXVO9KcI5E",
  "qi": "wV0NzfCakfog1NFjtPzcga1MtkpizgPkxcP9LjNdvXW2YQZhM6GIEGjsu3ivTrHrrM-4_bTQHOoTtfIY7wdqBKlwQTJOI0dH9FbN
J4ecGojRwgv83TN8aNKh17Tt44jI5oibs2P-31B_VW9R1wwhnnOuCYpABfoSbtHIoCRme5I"
}
The following object was signed by the key above:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "RS256",
    "jwk": {
      "kty": "RSA",
      "n": "hFWEXArvaZEpSP5qNX7x4C4Hl28GJQTNvnDwkfqiWs63kXbdyPeS06bz6GnY3tfQ_093nGauWsimqKBmGAGMPtsV83Qxw1OIe
O4ujbIIb9pema0qtVqs0MWlHxklZGFkYfAmbuEUFxYDeLDHe0bkkXbSlB7_t8pCSvc8HLgHjEQjYOlFRwjR0D-uLo-xgsCbpmCtYkB5lcT_zF
gpRgY4zJNLSv7GZiz2S4Fc5ArGjd34lL47-L8bozuYjqNOv9sqX0Zgll5XaJ1ndvr7UqZu1xQFgm38reoM3IarBP_SkEFbt_v9iak602VO3k2
8fQhMaocP7JWR2YLT3kZM0-WTFw",
      "e": "AQAB"
    },
    "val": "FFDKoa9u-Q0WmjulgP53O17YAPQeXxBY3khlulSYaXk12QUiPKU7TPx-6rqyPR_u1JNG56Pp2UK1eKbB_uAQOEJjECewE6Bpg
mojuB51CJArRCwrPD9BoLj9F9GBzf0m_VTGLENzgQC5w8q8BaYWeU16WKx73TFtV-Y1vUJA4zoHr7CevBJEaCvTYFDhxxvzb5q4IhVQqZ3_bD
dNxhuyJQUYO0qPKK3DgpnefcOfWtZhDaT9KQuo5rMbS3km8iZmAUjLZc3e0DeXMqj-5OxebiOSnwssJ2WxU21OkXxYGFjPbsJFuGdN-heTLdY
vYhxK7gSZEFlK01NNyUKiMtcM8w"
  }
}
The following signature object uses the same key as in the previous example but featured in a certificate path:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "RS256",
    "x5c": [
      "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"
    ],
    "val": "NpWvRMaP1XBVnFpOhs8fDoMtXt_n5bVyOeh_2ehskL53SEpaXoubFCRGl2sNK3Ysv6Ovck8qIBpzIHM_j48huB_TJj8NTLpaI
iLNvOMaZZFOICcgDt_SXY0JnE5I_fQwf4cw24B76VLU4SRAqPgFAL9vDojrATn5p82vMaM-Y63sW2OevIeb_XVVWjDnb3aSVp8bWuuhoKVjvV
qaoYN-0KD-vITrUB2_fRh0WmZDqPLI15qmw3-zVokMBf8ukw7WVRhoCiGk7kZWOpQScx7gzqbAWUcIQKGF0tpBtZD-co_Gf8QCeL5HCbGV42z
MunLn0XWOWDdkJ2rEACqaRyle4g"
  }
}
JWK [RFC7517] key set for verifying the subsequent object:
{
  "keys": [{
    "kty": "RSA",
    "n": "hFWEXArvaZEpSP5qNX7x4C4Hl28GJQTNvnDwkfqiWs63kXbdyPeS06bz6GnY3tfQ_093nGauWsimqKBmGAGMPtsV83Qxw1OIeO4
ujbIIb9pema0qtVqs0MWlHxklZGFkYfAmbuEUFxYDeLDHe0bkkXbSlB7_t8pCSvc8HLgHjEQjYOlFRwjR0D-uLo-xgsCbpmCtYkB5lcT_zFgp
RgY4zJNLSv7GZiz2S4Fc5ArGjd34lL47-L8bozuYjqNOv9sqX0Zgll5XaJ1ndvr7UqZu1xQFgm38reoM3IarBP_SkEFbt_v9iak602VO3k28f
QhMaocP7JWR2YLT3kZM0-WTFw",
    "e": "AQAB"
  }]
}
The following signature object is referring to a jku property pointing to an object as described above:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "RS256",
    "jku": "https://cyberphone.github.io/doc/openkeystore/r2048.jwks",
    "val": "J4Xqtnjwy00_v9vAMRkqqAsAh3Upkkl8zRppfsn4fvsRHkAEFSKyY7GYKGWPTL1XyLnvA3u4_RhnCcocdus8C_KMdXNboqkLU
6fnLYk7VrHoDygggdJ2jbVYPfK_VUTpVuRq_GjdkRpOmR2b_C-I9gKbPkSq2Fw8iJhLhli4wmlYXYEQEuaI8v3Le3NOXcOeGu0b8aoseBC4-j
4J2rkS11ZZVp8EyTt0eRfhIgEHmIKDf56lhluiVmJEhRGe87_ygNkHgekjwuJWCCM7OmZA7W50kAI7xOXHM1ILpyfUUpxxQywV77PC4Za0tpM
tN-mPcVVTudp5jAsDwXvp-3RLvg"
  }
}
PEM [RFC7468] certificate path for verifying the subsequent object:
-----BEGIN CERTIFICATE-----
MIIB+TCCAVigAwIBAgIGAWFcc4YkMAwGCCqGSM49BAMEBQAwLTELMAkGA1UEBhMCRVUxHjAcBgNV
BAMTFVRydXN0IE5ldHdvcmsgU3ViIENBMzAeFw0xODAxMDEwMDAwMDBaFw0yMjEyMzEyMzU5NTla
MDIxCzAJBgNVBAYTAkZSMQ0wCwYDVQQFEwQ0NTAxMRQwEgYDVQQDEwtleGFtcGxlLmNvbTBZMBMG
ByqGSM49AgEGCCqGSM49AwEHA0IABHHp7A83DBJIInj8+g1we3A7sBXprIQBUfdFDVUBQoPExq8r
ze6ewG0+eVcSF72J77gKiD0IHnzpwHaU7t6nVeajXTBbMAkGA1UdEwQCMAAwDgYDVR0PAQH/BAQD
AgP4MB0GA1UdDgQWBBQQyJ9rXSIskoUuA946von62LoxqzAfBgNVHSMEGDAWgBTUWrS54qC2NgG3
UK6rVAr0gbQ0MTAMBggqhkjOPQQDBAUAA4GMADCBiAJCAaWoVQ0r6jFjhO5e0WJTgyMmA8BhpO1t
7gXQ6xoKGso9jCOYf9OG9BFfZoVmdIyfYiwkhy1ld27tiOJ5X4m6WasRAkIBpEkUDf8irbSZ1V7z
XALaR2mJTjKQV/5jRHsiBQWA+5DxEa+x/zJVRz8tpp+jjT2tSCU82bwUOBLu6te1YIDpWCA=
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
MIIDsTCCAZmgAwIBAgIBAzANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMW
VHJ1c3QgTmV0d29yayBSb290IENBMTAeFw0xNjA3MTAxMDAwMDBaFw0yNTA3MTAwOTU5NTlaMC0x
CzAJBgNVBAYTAkVVMR4wHAYDVQQDExVUcnVzdCBOZXR3b3JrIFN1YiBDQTMwgZswEAYHKoZIzj0C
AQYFK4EEACMDgYYABAGJzPZsjniwyZeXrgrlQM3Y13r3znR8FSQpKbC2bplrOWySQJPGm+GFObe5
Dk4t3Jrtk/Pbs8+3VW/4q5drL0YqYwBYNJPhqjbSM6SGHrc6wNdPZRw/WnJVa0ELXKICC73lkjsk
WPfE+cLpZ3sTq1ovEmoNjgaySVRUH1wFDdkqyReJaKNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNRatLnioLY2AbdQrqtUCvSBtDQxMB8GA1UdIwQYMBaAFEkm
C1HDAh0fXehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQAs2KADYyGQCVy8tJZWakNtGdww
4OumZpBuR66p/2xK7veRubQEhG+nJn7oVkJ4w5pEec3sYQEqtPbHyZcEKEYbOJ2cVf1nMH+DvFZ6
ypQocGRp3WSWsTzL3SgqiWrQdPX1Y5dO6Hvx7p9ST9H2WgkxB+Q75Jov1gVF3bScAbxb7Mw7tf5z
3Cvqmfo0Gatkgzz6+jDPrtUK7AAAOw3C0kHMbE3EnNarsfhBkUerE8QVmHIvz373mWt0SnguaHq0
A9ZuSia/pF7bgfVRZi2ZzIzpu2O276sB2Yji9tcSn5l21jq63rXtvY/DLAi4kaLyf9sHT/tkH+gk
TdkdkfQq8sA5ysRW21wPQbmjTIVwsfY4JjajVIUitjPbkUJqURpf2VD0JXdYQHS6KVPWqHWTlKPl
sKbhw4ghuLqCMYda88L9rxWnSC5L8s0DJSuBBm+nq23NtHl5FbCzeXWcKRayIgimT+An1WIOeJP4
F7+BctYLIooKoQzJZR1tOWvprUs22/xAivVBz7J/LmJyVlKesB2ic8qYdt7YVoCsWrnEUgoNoJPw
LHeva8KPvd0gLXrwaMyTCCjeoemXFj6nCbbMHJeVffh6jYBAzlbcAEvTiZcdzrVVr54kOtWskyae
DnAcMXW4Of1vWdUJ2as5nyfletfTp4E6A9P2dZ5g7nMoL90yIw==
-----END CERTIFICATE-----
The following signature object is referring to a x5u property pointing to an object as described above:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "ES256",
    "x5u": "https://cyberphone.github.io/doc/openkeystore/p256certpath.pem",
    "val": "ARVH7-JBPvcLNK9mYmKmiiR5k23yp1MdKRhH9nEAGlyfT1PQ3Smho0sntBeKaNtPEeL18lhskxFpJCpMj0w05Q"
  }
}
HMAC key named "a256bitkey" here provided in hexadecimal notation:
7fdd851a3b9d2dafc5f0d00030e22b9343900cd42ede4948568a4a2ee655291a
Signature object requiring the key above for validation:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "HS256",
    "kid": "a256bitkey",
    "val": "xMRm1aOmKLu3smdx3QL8HGXaslfXE8NnTSAt3rGV_s0"
  }
}
HMAC key named "a384bitkey" here provided in hexadecimal notation:
37b7daeedc3403eb865a506c19597a37582ad5059e08438ada8bf544ee44bb3024a15f8fa191bbe7a533a56c9fc1db1d
Signature object requiring the key above for validation:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "HS384",
    "kid": "a384bitkey",
    "val": "dnBHwrx7C4EtLZh3qLaAzure_Ncm8P5bPsU0ZpQE6bGxNJpPJSukR5KvXDsAZRqW"
  }
}
HMAC key named "a512bitkey" here provided in hexadecimal notation:
83d26e96b71a5dd767c215f201ef5884fb03dfe5a8ee9612d4e3c942e84d45dfdc5801cb8379958f3af600d68eba1a14e945c90f16556
71f042cea7b34d53236
Signature object requiring the key above for validation:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "alg": "HS512",
    "kid": "a512bitkey",
    "val": "JrxIoEa9CerQ7meF4AqIlmFifrPcrheGtp5Dc-HGdbZI-Ea04Q-ca4Nem5ocNd8OUyj-0UWxBoAKNIGpzGt1Zg"
  }
}
The following is a multiple signature (see Multiple Signatures) using the "example.com:p256" and "example.com:r2048" keys:
{
  "now": "2018-04-16T11:23:06Z",
  "escapeMe": "\u20ac$\u000F\u000aA'\u0042\u0022\u005c\\\"\/",
  "numbers": [1e+30,4.5,6],
  "signature": {
    "signers": [{
      "alg": "ES256",
      "jwk": {
        "kty": "EC",
        "crv": "P-256",
        "x": "censDzcMEkgiePz6DXB7cDuwFemshAFR90UNVQFCg8Q",
        "y": "xq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeY"
      },
      "val": "_6abpgZgskI9bj2NhXZ3myFIQX_iTvc-k_MWilQjZssz1ouiSWtdRwg4VhnqXT_5YPznlqgQ8HMDyj3NdUouHQ"
    },{
      "alg": "RS256",
      "jwk": {
        "kty": "RSA",
        "n": "hFWEXArvaZEpSP5qNX7x4C4Hl28GJQTNvnDwkfqiWs63kXbdyPeS06bz6GnY3tfQ_093nGauWsimqKBmGAGMPtsV83Qxw1O
IeO4ujbIIb9pema0qtVqs0MWlHxklZGFkYfAmbuEUFxYDeLDHe0bkkXbSlB7_t8pCSvc8HLgHjEQjYOlFRwjR0D-uLo-xgsCbpmCtYkB5lcT_
zFgpRgY4zJNLSv7GZiz2S4Fc5ArGjd34lL47-L8bozuYjqNOv9sqX0Zgll5XaJ1ndvr7UqZu1xQFgm38reoM3IarBP_SkEFbt_v9iak602VO3
k28fQhMaocP7JWR2YLT3kZM0-WTFw",
        "e": "AQAB"
      },
      "val": "V5we6wZmRXSHwW98fr-noGWdXrbvOwENW-e8kxE-2BNR_7TvyXsJhemfoDpzgw0FbI2gCKVf94TK3pUTNMdgQq0pvMymRd0
wMPGUV1tLYJEixP92IU0DEFmGy_0TFWQctKOce_UI2yku6ZFZP_B8yrt7RSW6dYQ_42C3-pS83ys-gsFmsN_rUzrxOx_RjlaxbPEgp1P1ZCnB
pq627FVW7rmwyiRekf1MyWJPwp2E0RhiYxevZD3y5V4s4NRMH-mvCFwhXhmqVYTQtMScytC47VOTSdrpjOc26lPkDk1CQIxz5nC803ZdfKM_E
ElMaol0l_78MPZJz6mOk_tsV_9XZQ"
    }]
  }
}
The certificate based signatures share a common root (here supplied in PEM [RFC7468] format), which can be used for path validation:
-----BEGIN CERTIFICATE-----
MIIFOjCCAyKgAwIBAgIBATANBgkqhkiG9w0BAQ0FADAuMQswCQYDVQQGEwJVUzEfMB0GA1UEAxMW
VHJ1c3QgTmV0d29yayBSb290IENBMTAeFw0xNTA3MTAxMDAwMDBaFw0zMDA3MTAwOTU5NTlaMC4x
CzAJBgNVBAYTAlVTMR8wHQYDVQQDExZUcnVzdCBOZXR3b3JrIFJvb3QgQ0ExMIICIjANBgkqhkiG
9w0BAQEFAAOCAg8AMIICCgKCAgEAmhJBTeP6sCLA3bkZURJA3z8OmEUmuu18nEDaVVTfnT1UJWXY
A37xF8MQu3UZ6pCBEBiNIl41rjA17KFA1gBtJGTeSAza98acS+/AM3bsTDUrhjBD1vj3B63tnU2H
Ib/XFzqY9CLo3XkTwkrs1k4m6nxH7DX2VrsqddzeHduoDIwuBYfjwJZIPo+UX03xkD2OYBYr9xBW
EDcyEt+jOSb1Ftdstsm8ASMR5L01roHsAdsM75NDd2rKE0xGteHw/aAK0SWvSm23AiXTFX3BcHgm
5/c4OkvPodP+IJTb4EaLTD2rcFwe5AzF9+pkABVZZUwGwysORwuCVRZsgfODFm/Qan4xTtC2kRkz
XZdLplxAWZx/j+GRuYbppIzcS6v9XGnHBs7j58Jp6OF1TX4SLjQ7v2Ff1caPesPGCnO7gVAaiMTl
ctHONY3rCvsQb4KF65qoyQPXWtL5HiqQ96T8bxc4ycdeHfD0Owvielg1aKWDF8Amf4/s6r09rKNR
L47YTmp/3FK6XIfLLrMldbugpekF7pBGs9KxT6afQNGiVeRU0cUv5CrFg2e+044edc0kCqM1rCgD
W3ksHMlBLsp0FbU+yPt1aYni8T+9TgeFLObCBDSt77JCFrQIC/MmC3HlnB5rnOynKxLkYmy73+GI
WXx1JyCep7fW2Au/67RTrXNMF2kCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
BAMCAQYwHQYDVR0OBBYEFEkmC1HDAh0fXehpiUhUGE868Hk2MB8GA1UdIwQYMBaAFEkmC1HDAh0f
XehpiUhUGE868Hk2MA0GCSqGSIb3DQEBDQUAA4ICAQBrV9ON1pjwwABptKwnh3WDK9Q0qVrTJMYW
OfI/7AdrGlut6IR8h+ObKUAsfQqQcM1HYOKXHSJYKJjNkn+lX+BcXrlTpo/+gKqEavRabSFHYn28
jFqoUqMMMnDO2XhccHS9zN9HListfG0c+2Hg8FY2Bz1UnueipzQPN85drUGQUyRKRDgJuc8Ib47r
sQlxNeo3XCL88MgvTRMlRKCV5g5ufVowNbo4VWn936bUZxNQ0ivhYpv5bFTmQSuUzDJSC9+/hln7
FqxpnTaaIJEGXI7iXM+QDW0CHjhse69yE0x+DhuF1heqeQT1BU6Va1lNEIjWY2e/xjSrWAZ05RPd
Cs+DuerNMbBatOlXhcpBFYzEhjrCK1r2vu0WNKNznsVyuJ1EU1aw9Rfn5xQ5+CRO00CF6mxTwuhA
rwE5CpBt4fi2YyDzDa1kjho0MZfAvuF1ZNvovD1k6dQ36UU5U5RBoZO112tQwMqGPFzBZHJMbvqK
oAXtmSef7JK9NOEtiFnCL8GklOJlFn+zfGSqNvwqMwaMnEVTjsJnwqzK7gXGZmVj/2dkk4zzO3W8
EL48x5vpaX9/IXw0HHLGEj9CAIVk2oOes+Vp/49siuwBQm58VV0fIIHewDmwkgZV3RTPFrOrDYTf
pfjf8EV2t0G5ef13s4qXg7p3If75LR7h/gXpNHhw4A==
-----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 = {
  // Data to be signed
  statement: "Hello Signed World!",
  otherProperties: [2000,true],
  // Signature
  signature: {
    alg: "ES256",
    jwk: {
      kty: "EC",
      crv: "P-256",
      x: "censDzcMEkgiePz6DXB7cDuwFemshAFR90UNVQFCg8Q",
      y: "xq8rze6ewG0-eVcSF72J77gKiD0IHnzpwHaU7t6nVeY"
    },
    val: "PXyPZN_MbNnizyPibI5W9xit8cdMQIknO3umhgGX1g_UB8PXlBoHCWbHkcJEnpp9QmMF1QjUa4laOIHqeBk2oQ"
  }
};
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.val);       // Get signature value
  delete jcs.signature.val;                         // 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.jwk,         // JCS public key is a JWK
                          { name: 'ECDSA', namedCurve: clone.jwk.crv },
                          true, ['verify']).then(function(publicKey) {
    crypto.subtle.verify({ name: 'ECDSA', hash: { name: 'SHA-256' } }, 
                         publicKey, signature, data).then(function(result) {
      console.log('Success=' + result);
    });
  });
}

verifySignature(signedObject);
Constraint when using JCS with ECMAScript
For JavaScript optimization reasons, ECMAScript's JSON.parse() internally rearranges order of properties with names expressed as integers, making a parsed JSON string like '{"2":"First","A":"Next","1":"Last"}' actually serialize as '{"1":"Last","2":"First","A":"Next"}'.
Due to this fact, signature creators must (in the hopefully rather unusual case cross platform applications would mandate numeric property names), in an here unspecified way, "emulate" this scheme since this behavior is not intended to be an additional requirement to support by JSON tools in general in order to use this specification.
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 a JCS crit extension holding application specific (per signature) metadata.
Appendix D: Usage in Applications
JCS is a core element 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 JSONCryptoHelper.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.
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('val')                                            # 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.60, January 2018. https://cyberphone.github.io/doc/security/jose-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
[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 (now obsoleted) extension facility
2014-01-210.51Added clarification to public key parameter representation
2014-01-260.52Added note regarding the (now obsoleted) signerCertificate option
2014-04-150.53Embedded (the now obsoleted) bigint in JS string
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 val 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
2017-11-180.71Added detailed references to ECMAScript [ES6]
2018-01-050.80Rewritten to reuse JWS [RFC7515] property names
Appendix I: Author
JCS was developed by Anders Rundgren (anders.rundgren.net@gmail.com) as a part of the OpenKeyStore project [OPENKEY].