JWSの概要まとめ

実務でJWSによって保護されたJWTを扱う機会があったのですが、あれから時間が経過して忘れてしまっていることが多いため、JWSについてまとめることにしました。

記事の内容は [RFC7515 JSON Web Signature (JWS)](https://datatracker.ietf.org/doc/html/rfc7515) を元にJWSの概要をまとめました。
この記事では以下の点についてまとめています。
1. JWSは何か
2. JWSの構成要素
3. JWSの3つの形式
4. JWSの作成/検証
5. JWSとJWTの関係

## JWSの概要

JWS(JSON Web Signature)は、デジタル署名やメッセージ認証コード(MAC)によってデータを保護し、改ざん検知を可能にする仕組みです。保護対象のデータはJSONオブジェクトである必要はなく、任意のデータとすることができます。JWSは文字列またはJSONオブジェクトとして表現されます。このうち、JWT(JSON Web Token)で使われる表現は文字列です。

### 用語説明

本記事を読む上で参考にしてください。 
これらは[RFC7515の 2.  Terminology](https://datatracker.ietf.org/doc/html/rfc7515#section-2)で定義されています。

#### JWS Protected Header
デジタル署名やMACによって保護されるJSONオブジェクト。
データ保護に使用された暗号操作などに関する情報を含む。
JWSでは name/value のペアを Header Parameter という。
含むことのできる Header Parameter の詳細は[RFC7515 4.  JOSE Header](https://datatracker.ietf.org/doc/html/rfc7515#section-4)を参照。

#### JWS Unprotected Header
デジタル署名やMACによって保護されないJSONオブジェクト。
含むことのできる Header Parameter は JWS Protected Headerとほとんど変わらないが、
"alg" などセキュリティ上重要な Header Parameter を含めることは推奨されない。
JWS JSON Serialization形式のJWSでのみ使われる。

#### JWS Payload
データをエンコードして得られるオクテットシーケンス（8ビットのバイト列）。
デジタル署名やMACによって保護される。
データはJSONである必要はなく、任意のデータとすることが可能

#### JWS Signing Input
デジタル署名やMACを求めるために必要な値で、
以下を処理して得られるオクテットシーケンス。
```
ASCII(BASE64URL(UTF8(JWS Protected Header)) || '.' || BASE64URL(JWS Payload))
```

#### JWS Signature
JWS Protected HeaderとJWS Payloadに対するデジタル署名またはMACのこと。

### JWSの構成要素

JWSは以下の要素の組み合わせで構成されます。
- JWS Protected Header
- JWS Unprotected Header
- JWS Payload
- JWS Signature

どれをどう組み合わせるかはJWSの形式によって異なります。

### JWSの形式

形式は3つあります。

#### 1. JWS Compact Serialization
JWSをASCII文字列として表現する方法。
コンパクトでURLに含めても安全なのが特徴
```
BASE64URL(UTF8(JWS Protected Header)) || '.' ||
BASE64URL(JWS Payload) || '.' ||
BASE64URL(JWS Signature)
```
#### 2. JWS JSON Serialization
JWSをJSONオブジェクトとして表現する方法。
複数のデジタル署名やMACでデータを保護できるが、コンパクトさやURL安全性が最適化されていない。JSONを構成する “protected” と “header” は必ずどちらか一つは存在しなければならない。
2つの構文がある
    
##### 2.1. General JWS JSON Serialization Syntax
複数のデジタル署名やMACでデータを保護できる。より一般的な構文。
```json
{
  "payload":"<BASE64URL(JWS Payload)>",
  "signatures":[
    {"protected":"<BASE64URL(UTF8(JWS Protected Header))>",
      "header":<JWS Unprotected Header>,
      "signature":"<BASE64URL(JWS Signature)>"},
     ...
    {"protected":"<BASE64URL(UTF8(JWS Protected Header))>",
      "header":<JWS Unprotected Header>,
      "signature":"<BASE64URL(JWS Signature)>"}]
}
```
    
##### 2.2  Flattened JWS JSON Serialization Syntax
1つのデジタル署名またはMACでデータを保護する構文。
よりコンパクトな表現が可能
```json
{
  "payload":"<BASE64URL(JWS Payload)>",
  "protected":"<BASE64URL(UTF8(JWS Protected Header))>",
  "header":<JWS Unprotected Header>,
  "signature":"<BASE64URL(JWS Signature)>"
}
```
    

次のセクションでそれぞれのJWSを作成します。

## JWSの作成
:::note info
ここではデータ保護方法として、署名スキーム RSASSA-PKCS1-v1_5 とハッシュ関数 SHA-256 を使った方法を取り上げますが、他の方法においても JWS Signature の作成/検証を除いて処理が共通しています。他の方法でJWSを作成するフローを確認したい方は [Appendix A.  JWS Examples](https://datatracker.ietf.org/doc/html/rfc7515#appendix-A) を参照ください。
:::

データは以下のJSONオブジェクトとし、署名スキーム RSASSA-PKCS1-v1_5 とハッシュ関数SHA-256を使ってデータを保護します。

```json
{"iss":"joe",
 "exp":1300819380,
 "http://example.com/is_root":true}
```

### 必要なデータを準備する

3つの形式に共通で必要なデータは次の3つです。(JWS JSON Serialization 形式のJWSでは、 “kid” をJWS Unprotected Header に含めることが可能ですが、説明を簡単にするために JWS Protected Header に含めることにし、 JWS Unprotected Header は省略します)

- BASE64URL(UTF8(JWS Protected Header))
- BASE64URL(JWS Payload)
- BASE64URL(JWS Signature)

**BASE64URL(UTF8(JWS Protected Header)) を作成する**
JWT Protected Header は以下のJSONオブジェクトです。
”alg” は必須要素で、どのような方法で保護するかを表します。
”kid” はデジタル署名の検証に必要な公開鍵を特定するための値です。
```json
{"alg":"RS256",
 "kid":"1dbe06b5d7c2a7c044563061ff0fea37740b86bc"}
```
このJSONの文字列表現をUTF-8エンコードしてオクテットシーケンスに変換します。
(見やすさのために途中で改行を入れています)
```
[123, 34, 116, 121, 112, 34, 58, 34, 74, 87, 84, 34, 44, 13, 10, 32, 
34, 97, 108, 103, 34, 58, 34, 82, 83, 50, 53, 54, 34, 44, 13, 10, 32, 
34, 107, 105, 100, 34, 58, 34, 49, 100, 98, 101, 48, 54, 98, 53, 100, 
55, 99, 50, 97, 55, 99, 48, 52, 52, 53, 54, 51, 48, 54, 49, 102, 102, 
48, 102, 101, 97, 51, 55, 55, 52, 48, 98, 56, 54, 98, 99, 34, 125]
```
このオクテットシーケンスを base64url エンコードして文字列に変換します。
以降、これを header として参照します。
```
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJSUzI1NiIsDQogImtpZCI6IjFkYmUwNmI1ZDdjMmE3YzA0NDU2MzA2MWZmMGZlYTM3NzQwYjg2YmMifQ
```

**BASE64URL(JWS Payload) を作成する**
JWS Payload はデータをエンコードして得られるオクテットシーケンスです。今回はデータがJSONなのでUTF-8でエンコードします。(途中で改行を入れています)
```
[123, 34, 105, 115, 115, 34, 58, 34, 106, 111, 101, 34, 44, 13, 10, 32, 
34, 101, 120, 112, 34, 58, 49, 51, 48, 48, 56, 49, 57, 51, 56, 48, 44, 
13, 10, 32, 34, 104, 116, 116, 112, 58, 47, 47, 101, 120, 97, 109, 112, 
108, 101, 46, 99, 111, 109, 47, 105, 115, 95, 114, 111, 111, 116, 34, 58, 
116, 114, 117, 101, 125]
```
このJWS Payloadを base64url エンコードします。
以降、これを payload として参照します。
```
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
```

**BASE64URL(JWS Signature) を作成する**
JWS Signature を作成するために、まず JWS Signing Input を求めます。
JWS Signing Input は header と payload をドット(”.”)で結合した文字列をASCIIエンコードして得られるオクテットシーケンスです。(途中で改行を入れています)
```
[101, 121, 74, 48, 101, 88, 65, 105, 79, 105, 74, 75, 86, 49, 81, 105, 76, 
65, 48, 75, 73, 67, 74, 104, 98, 71, 99, 105, 79, 105, 74, 83, 85, 122, 73, 
49, 78, 105, 73, 115, 68, 81, 111, 103, 73, 109, 116, 112, 90, 67, 73, 54, 
73, 106, 70, 107, 89, 109, 85, 119, 78, 109, 73, 49, 90, 68, 100, 106, 77, 
109, 69, 51, 89, 122, 65, 48, 78, 68, 85, 50, 77, 122, 65, 50, 77, 87, 90, 
109, 77, 71, 90, 108, 89, 84, 77, 51, 78, 122, 81, 119, 89, 106, 103, 50, 
89, 109, 77, 105, 102, 81, 46, 101, 121, 74, 112, 99, 51, 77, 105, 79, 105, 
74, 113, 98, 50, 85, 105, 76, 65, 48, 75, 73, 67, 74, 108, 101, 72, 65, 105, 
79, 106, 69, 122, 77, 68, 65, 52, 77, 84, 107, 122, 79, 68, 65, 115, 68, 81, 
111, 103, 73, 109, 104, 48, 100, 72, 65, 54, 76, 121, 57, 108, 101, 71, 70, 
116, 99, 71, 120, 108, 76, 109, 78, 118, 98, 83, 57, 112, 99, 49, 57, 121, 
98, 50, 57, 48, 73, 106, 112, 48, 99, 110, 86, 108, 102, 81]
```
署名で使う秘密鍵は、[RFC7515 A.2.  Example JWS Using RSASSA-PKCS1-v1_5 SHA-256](https://datatracker.ietf.org/doc/html/rfc7515#appendix-A.2) のJWK(JSON Web Key)形式で表現されたRSA鍵を使用します。
<details><summary>鍵の内容(長いので折りたたみます)</summary>
    
```json
 {"kty":"RSA",
  "n":"ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddx
       HmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMs
       D1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSH
       SXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdV
       MTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8
       NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ",
  "e":"AQAB",
  "d":"Eq5xpGnNCivDflJsRQBXHx1hdR1k6Ulwe2JZD50LpXyWPEAeP88vLNO97I
       jlA7_GQ5sLKMgvfTeXZx9SE-7YwVol2NXOoAJe46sui395IW_GO-pWJ1O0
       BkTGoVEn2bKVRUCgu-GjBVaYLU6f3l9kJfFNS3E0QbVdxzubSu3Mkqzjkn
       439X0M_V51gfpRLI9JYanrC4D4qAdGcopV_0ZHHzQlBjudU2QvXt4ehNYT
       CBr6XCLQUShb1juUO1ZdiYoFaFQT5Tw8bGUl_x_jTj3ccPDVZFD9pIuhLh
       BOneufuBiB4cS98l2SR_RQyGWSeWjnczT0QU91p1DhOVRuOopznQ",
  "p":"4BzEEOtIpmVdVEZNCqS7baC4crd0pqnRH_5IB3jw3bcxGn6QLvnEtfdUdi
       YrqBdss1l58BQ3KhooKeQTa9AB0Hw_Py5PJdTJNPY8cQn7ouZ2KKDcmnPG
       BY5t7yLc1QlQ5xHdwW1VhvKn-nXqhJTBgIPgtldC-KDV5z-y2XDwGUc",
  "q":"uQPEfgmVtjL0Uyyx88GZFF1fOunH3-7cepKmtH4pxhtCoHqpWmT8YAmZxa
       ewHgHAjLYsp1ZSe7zFYHj7C6ul7TjeLQeZD_YwD66t62wDmpe_HlB-TnBA
       -njbglfIsRLtXlnDzQkv5dTltRJ11BKBBypeeF6689rjcJIDEz9RWdc",
  "dp":"BwKfV3Akq5_MFZDFZCnW-wzl-CCo83WoZvnLQwCTeDv8uzluRSnm71I3Q
       CLdhrqE2e9YkxvuxdBfpT_PI7Yz-FOKnu1R6HsJeDCjn12Sk3vmAktV2zb
       34MCdy7cpdTh_YVr7tss2u6vneTwrA86rZtu5Mbr1C1XsmvkxHQAdYo0",
  "dq":"h_96-mK1R_7glhsum81dZxjTnYynPbZpHziZjeeHcXYsXaaMwkOlODsWa
       7I9xXDoRwbKgB719rrmI2oKr6N3Do9U0ajaHF-NKJnwgjMd2w9cjz3_-ky
       NlxAr2v4IKhGNpmM5iIgOS1VZnOZ68m6_pbLBSp3nssTdlqvd0tIiTHU",
  "qi":"IYd7DHOhrWvxkwPQsRM2tOgrjbcrfvtQJipd-DlcxyVuuM9sQLdgjVk2o
       y26F0EmpScGLq2MowX7fhd_QJQ3ydy5cY7YIBi87w93IKLEdfnbJtoOPLU
       W0ITrJReOgo1cq9SbsxYawBgfp_gh6A5603k2-ZQwVK0JKSHuLFkuQ3U"
 }

```
</details>

このJWKから秘密鍵を作成し、RSA署名関数に秘密鍵、SHA-256、JWS Signing Inputを与えると、以下の JWS Signature が得られます。(途中で改行を入れています)
```
[119, 64, 125, 226, 172, 102, 132, 43, 208, 154, 241, 32, 52, 150, 161, 85, 
14, 183, 119, 57, 18, 101, 9, 68, 227, 163, 109, 166, 186, 224, 105, 164, 
191, 170, 251, 192, 123, 155, 238, 185, 215, 177, 120, 118, 23, 41, 224, 
100, 145, 49, 238, 60, 53, 73, 109, 174, 73, 119, 0, 148, 176, 164, 55, 33, 
181, 187, 0, 52, 194, 213, 102, 220, 132, 186, 99, 72, 231, 103, 62, 80, 
191, 77, 64, 100, 91, 242, 229, 205, 111, 8, 62, 3, 92, 1, 175, 67, 122, 
126, 150, 247, 35, 138, 211, 37, 216, 144, 71, 24, 225, 245, 7, 38, 249, 
138, 199, 63, 40, 246, 137, 196, 1, 181, 129, 126, 41, 179, 234, 76, 102, 
217, 14, 28, 118, 241, 218, 193, 29, 49, 156, 234, 242, 167, 17, 8, 176, 
166, 173, 55, 211, 250, 212, 168, 9, 202, 145, 52, 245, 60, 118, 9, 184, 
246, 55, 40, 74, 149, 76, 138, 36, 196, 144, 249, 21, 54, 18, 64, 221, 195, 
246, 140, 239, 42, 235, 105, 255, 196, 7, 189, 146, 194, 183, 75, 91, 50, 4, 
241, 100, 206, 239, 221, 19, 64, 240, 153, 143, 153, 13, 109, 159, 85, 30, 
230, 61, 67, 127, 45, 180, 58, 182, 34, 178, 109, 179, 129, 105, 173, 106, 
203, 69, 215, 108, 215, 8, 90, 135, 197, 12, 111, 70, 175, 57, 27, 187, 206, 
4, 185, 162, 235, 193, 84, 177, 243, 25, 42, 184, 86]
```
このJWS Signatureを base64url エンコードします。
以降、これを signature として参照します。
```
d0B94qxmhCvQmvEgNJahVQ63dzkSZQlE46NtprrgaaS_qvvAe5vuudexeHYXKeBkkTHuPDVJba5JdwCUsKQ3IbW7ADTC1WbchLpjSOdnPlC_TUBkW_LlzW8IPgNcAa9Den6W9yOK0yXYkEcY4fUHJvmKxz8o9onEAbWBfimz6kxm2Q4cdvHawR0xnOrypxEIsKatN9P61KgJypE09Tx2Cbj2NyhKlUyKJMSQ-RU2EkDdw_aM7yrraf_EB72SwrdLWzIE8WTO790TQPCZj5kNbZ9VHuY9Q38ttDq2IrJts4FprWrLRdds1whah8UMb0avORu7zgS5ouvBVLHzGSq4Vg
```

準備した header, payload, signature から、3つの形式のJWSを作成します。

### JWS Compact Serialization
準備した header, payload, signature を先頭から順番にドット(’.’)で結合すると
JWS Compact Serialization 形式のJWSの完成です。(途中で改行を入れています)

```
eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJSUzI1NiIsDQogImtpZCI6IjFkYmUwNmI1ZDdjMmE3YzA0NDU2MzA2MWZmMGZlYTM3NzQwYjg2YmMifQ
.
eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ
.
d0B94qxmhCvQmvEgNJahVQ63dzkSZQlE46NtprrgaaS_qvvAe5vuudexeHYXKeBkkTHuPDVJba5JdwCUsKQ3IbW7ADTC1WbchLpjSOdnPlC_TUBkW_LlzW8IPgNcAa9Den6W9yOK0yXYkEcY4fUHJvmKxz8o9onEAbWBfimz6kxm2Q4cdvHawR0xnOrypxEIsKatN9P61KgJypE09Tx2Cbj2NyhKlUyKJMSQ-RU2EkDdw_aM7yrraf_EB72SwrdLWzIE8WTO790TQPCZj5kNbZ9VHuY9Q38ttDq2IrJts4FprWrLRdds1whah8UMb0avORu7zgS5ouvBVLHzGSq4Vg
```

### Flattened JWS JSON Serialization Syntax
JSONオブジェクトの protected, payload, signature 要素の値として、それぞれ header, payload, signature を使うことで完成です。
```json
{
  "payload":"eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ",
  "protected":"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJSUzI1NiIsDQogImtpZCI6IjFkYmUwNmI1ZDdjMmE3YzA0NDU2MzA2MWZmMGZlYTM3NzQwYjg2YmMifQ",
  "signature":"d0B94qxmhCvQmvEgNJahVQ63dzkSZQlE46NtprrgaaS_qvvAe5vuudexeHYXKeBkkTHuPDVJba5JdwCUsKQ3IbW7ADTC1WbchLpjSOdnPlC_TUBkW_LlzW8IPgNcAa9Den6W9yOK0yXYkEcY4fUHJvmKxz8o9onEAbWBfimz6kxm2Q4cdvHawR0xnOrypxEIsKatN9P61KgJypE09Tx2Cbj2NyhKlUyKJMSQ-RU2EkDdw_aM7yrraf_EB72SwrdLWzIE8WTO790TQPCZj5kNbZ9VHuY9Q38ttDq2IrJts4FprWrLRdds1whah8UMb0avORu7zgS5ouvBVLHzGSq4Vg"
}
```

### General JWS JSON Serialization Syntax
今回は一つのデジタル署名でデータを保護しているので以下のようにして完成です。デジタル署名やMACが複数存在する場合は、それぞれに対応するJSONオブジェクトを signatures 要素に追加します。
```json
{
  "payload":"eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ",
  "signatures":[
    {
      "protected":"eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJSUzI1NiIsDQogImtpZCI6IjFkYmUwNmI1ZDdjMmE3YzA0NDU2MzA2MWZmMGZlYTM3NzQwYjg2YmMifQ",
      "signature":"d0B94qxmhCvQmvEgNJahVQ63dzkSZQlE46NtprrgaaS_qvvAe5vuudexeHYXKeBkkTHuPDVJba5JdwCUsKQ3IbW7ADTC1WbchLpjSOdnPlC_TUBkW_LlzW8IPgNcAa9Den6W9yOK0yXYkEcY4fUHJvmKxz8o9onEAbWBfimz6kxm2Q4cdvHawR0xnOrypxEIsKatN9P61KgJypE09Tx2Cbj2NyhKlUyKJMSQ-RU2EkDdw_aM7yrraf_EB72SwrdLWzIE8WTO790TQPCZj5kNbZ9VHuY9Q38ttDq2IrJts4FprWrLRdds1whah8UMb0avORu7zgS5ouvBVLHzGSq4Vg"
    }
  ]
}
```

## JWSの検証
### signature の検証
RS256で保護された場合、デジタル署名の検証は、SHA-256ハッシュ関数を使用するように設定された署名検証機`RSASSA-PKCS1-V1_5-VERIFY ((n, e), M, S)`に以下のデータを渡して行います。
- M：JWS Signing Input (前の例と同じため省略)
- S：JWS Signature(前の例と同じため省略)
- (n, e)：公開鍵

公開鍵はweb上のエンドポイントから取得できます。公開鍵は証明書やJWKの形式で提供されることがあります。例として、[firebase は証明書](https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com)、[facebookはJWK](https://limited.facebook.com/.well-known/oauth/openid/jwks/)を提供します。

先ほどのJWKの n と e から公開鍵を作成すると以下の値が得られます。
(途中で改行を入れています)

```json
"-----BEGIN PUBLIC KEY-----\n
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAofgWCuLjybRlzo0tZWJj\n
NiuSfb4p4fAkd/wWJcyQoTbji9k0l8W26mPddxHmfHQp+Vaw+4qPCJrcS2mJPMEz\n
P1Pt0Bm4d4QlL+yRT+SFd2lZS+pCgNMsD1W/YpRPEwOWvG6b32690r2jZ47soMZo\n
9wGzjb/7OMg0LOL+bSf63kpaSHSXndS5z5rexMdbBYUsLA9e+KXBdQOS+UTo7WTB\n
EMa2R2CapHg665xsmtdVMTBQY4uDZlxvb3qCo5ZwKh9kG4LT6/I5IhlJH7aGhyxX\n
FvUK+DWNmoudF8NAco9/h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXp\n
oQIDAQAB\n-----END PUBLIC KEY-----\n"
```

署名の検証にはライブラリを使うことが多いと思います。署名・検証に利用できるライブラリは[JWT公式ページ](https://jwt.io/libraries)にまとまっています。

具体的な署名検証フローが知りたい人は [RFC3447 8.2.2 Signature verification operation](https://datatracker.ietf.org/doc/html/rfc3447#section-8.2.2) を確認ください。(時間がある時にまとめるかも)

**signature が複数ある場合について**
[RFC7515 5.2.  Message Signature or MAC Validation](https://datatracker.ietf.org/doc/html/rfc7515#section-5.2)によれば、すべての signature の検証に失敗した場合はJWSを無効として扱うが、その全ての検証に成功するべきなのか、そのうちのどの検証に成功するべきなのかの判断はアプリケーションに委ねるとしています。

**他の検証項目について**
[RFC7515 5.2. Message Signature or MAC Validation](https://datatracker.ietf.org/doc/html/rfc7515#section-5.2) では signature の検証以外にも検証項目が列挙されていますが、ライブラリを使う場合は気にしなくて良さそうなため割愛します。

## JWT と JWS の関係

[RFC7519 1. Introduction](https://datatracker.ietf.org/doc/html/rfc7519#section-1) では、JWTは以下のように説明されています。

```
JWTs encode claims to be transmitted as a JSON [RFC7159] object that is used
as the payload of a JSON Web Signature (JWS) [JWS] structure or 
as the plaintext of a JSON Web Encryption (JWE) [JWE] structure, 
enabling the claims to be digitally signed or integrity protected with a 
Message Authentication Code (MAC) and/or encrypted. JWTs are always represented 
using the JWS Compact Serialization or the JWE Compact Serialization.
```

このことから、以下の条件をすべて満たすJWSはJWTであると言えます。

- JWSの形式が JWS Compact Serialization
- payload に含まれるデータがJSONオブジェクト(このJSONオブジェクトをJWTではJWT Claims Set といいます)