[21] [DFN[[CODE(HTTP)@en[[[oauth_body_hash]]]]]] [[引数]]は、
[[payload body]] の[[ハッシュ値]]を指定するものです。

[23] [[OAuth 1.0]] 本体仕様では [CODE(MIME)@en[[[application/x-www-form-urlencoded]]]]
以外の [[payload body]] は[[署名]]の計算に反映されないため、[[replay攻撃]]が可能となってしまいます。
これを避けたい時に本[[引数]]により [[payload body]] の[[ハッシュ値]]を指定することができます。

[24] 本機能は [[OAuth 1.0]] 本体に含まれない拡張であり、また [[HTTPS]]
を採用した [[OAuth 2.0]] が現在普及していることもあり、それほど広く使われてはいません。
しかし[[クライアント]]の[[ライブラリー]]で本機能を使っているものがあり、
無視できない程度には使われているため [[OAuth 1.0]] の[[鯖]]は本機能を実装する必要があります。

* 仕様書

[REFS[
- [2] [CITE@en[Final: OAuth Request Body Hash]] ([TIME[2009-04-12 08:08:27 +09:00]] 版) <http://oauth.googlecode.com/svn&l=52/spec/ext/body_hash/1.0/oauth-bodyhash.html>
]REFS]

* ハッシュ関数の選択

[3] [CODE(HTTP)@en[[[oauth_signature_method]]]] が [CODE(HTTP)@en[[[HMAC-SHA1]]]] か
[CODE(HTTP)@en[[[RSA-SHA1]]]] なら、 [[SHA1]] を使わなければ[['''なりません''']] [SRC[>>2]]。

[4] [CODE(HTTP)@en[[[PLAINTEXT]]]] なら、 [CODE(HTTP)@en[[[oauth_body_hash]]]]
を使う[['''べきではありません''']] [SRC[>>2]]。

[5] それ以外の[[署名]]方式を規定する際には、 [CODE(URI)@en[[[oauth_body_hash]]]]
の[[ハッシュアルゴリズム]]を規定する[['''べきです''']] [SRC[>>2]]。

* 値の計算

[6] [CODE(HTTP)@en[[[oauth_body_hash]]]] の値は、 [[payload body]]
(なければ[[空文字列]]) に[[ハッシュ関数]]を適用した結果を
[[RFC 4648]] [[Base64]] [[符号化]]したものとしなければ[['''なりません''']] [SRC[>>2]]。

* 文脈

[7] [[一時credentials要求]]や[[トークン要求]]には、 [CODE(HTTP)@en[[[oauth_body_hash]]]]
[[引数]]を含める[['''べきではありません''']] [SRC[>>2]]。

;; [11] 実装によっては未知の[[引数]]をエラーとするため、また [[OAuth]]
の[[引数]]は既に [CODE(HTTP)@en[[[oauth_signature]]]] に含まれているため[[セキュリティー]]上の問題とならないためとされています [SRC[>>2]]。

[8] [CODE(HTTP)@en[[[Content-Type:]] [[application/x-www-form-urlencoded]]]]
の[[要求]]には [CODE(HTTP)@en[[[oauth_body_hash]]]] [[引数]]を含めては[['''なりません''']]
[SRC[>>2]]。

;; [19] 攻撃に使われる可能性があるため [SRC[>>2]] とされています。

[9] それ以外の[[要求]]には [CODE(HTTP)@en[[[oauth_body_hash]]]] [[引数]]を含める[['''べきです''']] [SRC[>>2]]。

;; [10] とされていますが、[[相互運用性]]のため、 [CODE(HTTP)@en[[[oauth_body_hash]]]]
[[引数]]を含めるべきではありません。仕様は [[OAuth 1.0]] 本体に[[引数]]を追加するだけなので[[後方互換性]]がある [SRC[>>2]]
と述べていますが、実際には [CODE(HTTP)@en[[[oauth_signature]]]] [[引数]]の[[署名]]の計算方法が変わってしまっているため、
[[クライアント]]が [CODE(HTTP)@en[[[oauth_body_hash]]]] を送ってきているなら、
[[鯖]]も [CODE(HTTP)@en[[[oauth_body_hash]]]] に対応していないと[[署名]]不一致のエラーになってしまいます。

[12] [[認証された要求]]も参照。

* 検証

[13] [CODE(HTTP)@en[[[Content-Type:]] [[application/x-www-form-urlencoded]]]]
の[[要求]]に [CODE(HTTP)@en[[[oauth_body_hash]]]] [[引数]]が指定されていれば、
攻撃の可能性があるため、拒絶しなければ[['''なりません''']] [SRC[>>2]]。

[14] [CODE(HTTP)@en[[[oauth_body_hash]]]] [[引数]]を指定するべき場合で含まれていなければ、
[[相互運用性]]のためその[[要求]]を受け入れても構いませんし、
[[セキュリティー]]のため拒絶しても構いません。 [SRC[>>2]]

;; [15] 実際には [CODE(HTTP)@en[[[oauth_body_hash]]]] を送らない[[クライアント]]が多いので、
[[相互運用性]]のため拒絶するべきではなさそうです。

[16] [[鯖]]は、指定された値と計算した値が一致しなければ、
拒絶しなければ[['''なりません''']] [SRC[>>2]]。

[17] [[鯖]]は、最終的な値を比較するかわりに、 [[Base64]] [[復号]]したものを比較しても構いません
[SRC[>>2]]。

;; [18] これは[[パーセント符号化]]や [[Base64]] [[符号化]]の実装の違いを吸収するため
[SRC[>>2]] とされています。しかし本規定によってますます[[相互運用性]]の問題が深刻化する可能性があると思いますが・・・。

;; [20] 実装によっては検証を省略し、[[認証された要求]]としての署名の計算にだけ使うものもあるようです。
実質的に [CODE(HTTP)@en[[[oauth_body_hash]]]] [[引数]]を実装していない場合と同じですが、
[CODE(HTTP)@en[[[oauth_body_hash]]]] を送ってくる[[クライアント]]からの[[要求]]も処理できるという利点があります。

;; [22] [CODE(HTTP)@en[[[oauth_body_hash]]]] [[引数]]を指定する[[クライアント]]ライブラリーが存在していて使われているため、
[[鯖]]は最低でも >>20 のような形で [CODE(HTTP)@en[[[oauth_body_hash]]]]
[[引数]]に対応せざるを得ません。

* 歴史

[1] [CITE@en[Implementers' Draft: OAuth Request Body Hash 1.0 Draft 1]]
([TIME[2008-12-08 08:47:55 +09:00]] 版)
<http://oauth.googlecode.com/svn/spec/ext/body_hash/1.0/drafts/1/spec.html>

[25] [CITE@en[draft-eaton-oauth-bodyhash-00 - OAuth Request Body Hash]]
([TIME[2015-01-26 13:44:16 +09:00]] 版)
<https://tools.ietf.org/html/draft-eaton-oauth-bodyhash-00>

[FIG(quote)[
[FIGCAPTION[
[26] [CITE@en[Authentication — Marketplace API 2.0 documentation]]
([TIME[2015-06-24 10:24:58 +09:00]] 版)
<http://firefox-marketplace-api.readthedocs.org/en/latest/topics/authentication.html#shared-secret>
]FIGCAPTION]

> Example headers (new lines added for clarity):
> Content-type: application/json
> Authorization: OAuth realm="",
>                oauth_body_hash="2jm...",

]FIG]
