質問編集履歴

7

質問を減らした

2018/02/08 12:06

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
  上記の記事を見てHMACを使用したAPI認証というものを知りました。
12
12
 
13
- これに関して3つの質問があります。
13
+ これに関して2つの質問があります。
14
14
 
15
15
 
16
16
 
@@ -84,46 +84,10 @@
84
84
 
85
85
 
86
86
 
87
-
88
-
89
87
  ## 質問2
90
88
 
91
89
 
92
90
 
93
- この認証方法の(セキュリティ的な)メリットについて知りたいです。
94
-
95
-
96
-
97
- メリットとしては以下のようなものがあると思います
98
-
99
-
100
-
101
- - `https://example.com/api/?token=XXXXX` このような形式のAPIと異なり、秘密鍵を通信しなくてもよい
102
-
103
- - 途中経路での改竄をHMACによる署名によって防ぐことができる
104
-
105
-
106
-
107
- ## 質問3
108
-
109
-
110
-
111
- [
112
-
113
- Secure ASP.NET Web API using API Key Authentication – HMAC Authentication](http://bitoftech.net/2014/12/15/secure-asp-net-web-api-using-api-key-authentication-hmac-authentication/)
114
-
115
-
116
-
117
- 元記事の実装では何かセキュリティ的な問題はあるのでしょうか。
118
-
119
- 私が理解できた範囲では特に問題はないのかなと思っています。
120
-
121
-
122
-
123
- ## 質問4
124
-
125
-
126
-
127
91
  自分でコードを書いてみましたので、セキュリティの観点からレビューをいただきたいです。
128
92
 
129
93
  Ruby on Railsで使用することを想定しています。

6

タグを追加

2018/02/08 12:06

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
File without changes

5

タグの追加

2018/01/30 09:56

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -126,6 +126,8 @@
126
126
 
127
127
  自分でコードを書いてみましたので、セキュリティの観点からレビューをいただきたいです。
128
128
 
129
+ Ruby on Railsで使用することを想定しています。
130
+
129
131
 
130
132
 
131
133
 

4

レビュー観点の追加

2018/01/30 08:45

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -124,7 +124,9 @@
124
124
 
125
125
 
126
126
 
127
- 自分でコードを書いてみましたので、レビューをいただきたいです。
127
+ 自分でコードを書いてみましたので、セキュリティの観点からレビューをいただきたいです。
128
+
129
+
128
130
 
129
131
 
130
132
 

3

不要コード削除

2018/01/30 08:44

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -156,14 +156,6 @@
156
156
 
157
157
 
158
158
 
159
- # 秘密鍵(仮に定数としている、実際はハードコードしない)
160
-
161
- # SecureRandom.hex(32)で作成
162
-
163
- SECRET_TOKEN = 'a838b46b97a04ef5e6bf5127fd610f94ab60db8300cf149d70be8ffb9e3890a9'
164
-
165
-
166
-
167
159
  # タイムスタンプの期限切れ時間(秒)
168
160
 
169
161
  TIMESTAMP_EXPIRATION = 10.0

2

自分で実装したコードを追加

2018/01/30 08:42

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -117,3 +117,221 @@
117
117
  元記事の実装では何かセキュリティ的な問題はあるのでしょうか。
118
118
 
119
119
  私が理解できた範囲では特に問題はないのかなと思っています。
120
+
121
+
122
+
123
+ ## 質問4
124
+
125
+
126
+
127
+ 自分でコードを書いてみましたので、レビューをいただきたいです。
128
+
129
+
130
+
131
+ ```ruby
132
+
133
+ class HmacAuthentificator
134
+
135
+ # アクセスIDヘッダ ユーザの識別を行う
136
+
137
+ X_ACCESS_ID_HEADER = 'X-Access-Id'
138
+
139
+
140
+
141
+ # 署名ヘッダ リクエストの正当性検証を担う
142
+
143
+ X_SIGNATURE_HEADER = 'X-Signature'
144
+
145
+
146
+
147
+ # タイムスタンプヘッダ replay attacks攻撃防止用
148
+
149
+ X_TIMESTAMP_HEADER = 'X-Timestamp'
150
+
151
+
152
+
153
+ # 署名作成のハッシュ関数
154
+
155
+ DIGEST_METHOD = 'sha256'
156
+
157
+
158
+
159
+ # 秘密鍵(仮に定数としている、実際はハードコードしない)
160
+
161
+ # SecureRandom.hex(32)で作成
162
+
163
+ SECRET_TOKEN = 'a838b46b97a04ef5e6bf5127fd610f94ab60db8300cf149d70be8ffb9e3890a9'
164
+
165
+
166
+
167
+ # タイムスタンプの期限切れ時間(秒)
168
+
169
+ TIMESTAMP_EXPIRATION = 10.0
170
+
171
+
172
+
173
+ # @param [ActionDispatch::Request] request
174
+
175
+ def initialize(request)
176
+
177
+ @request = request
178
+
179
+ end
180
+
181
+
182
+
183
+ # リクエストの正当性検証
184
+
185
+ # @return [Boolean]
186
+
187
+ def valid?
188
+
189
+ #
190
+
191
+ # タイムスタンプ
192
+
193
+ #
194
+
195
+ timestamp = @request.headers[X_TIMESTAMP_HEADER]
196
+
197
+ return false unless timestamp
198
+
199
+ parsed_timestamp = ::Time.zone.parse(timestamp)
200
+
201
+ return false unless parsed_timestamp
202
+
203
+ # タイムスタンプの有効期限検証,制限時間を超えているものと未来のものは拒否する
204
+
205
+ now = ::Time.zone.now
206
+
207
+ return false if now - parsed_timestamp > TIMESTAMP_EXPIRATION || parsed_timestamp > now
208
+
209
+
210
+
211
+ #
212
+
213
+ # アクセスID
214
+
215
+ #
216
+
217
+ access_id = @request.headers[X_ACCESS_ID_HEADER]
218
+
219
+ return false unless access_id
220
+
221
+
222
+
223
+ #
224
+
225
+ # 秘密鍵
226
+
227
+ #
228
+
229
+ secret_token = find_secret_token(access_id)
230
+
231
+ return false unless secret_token
232
+
233
+
234
+
235
+ #
236
+
237
+ # 署名
238
+
239
+ #
240
+
241
+ requested_signature = @request.headers[X_SIGNATURE_HEADER]
242
+
243
+ return false unless requested_signature
244
+
245
+
246
+
247
+ #
248
+
249
+ # 署名の再作成と検証
250
+
251
+ #
252
+
253
+ regenerated_signature = create_signature(secret_token, @request.original_url, @request.raw_post, timestamp)
254
+
255
+ # MITIGATE TIMING ATTACK
256
+
257
+ return false unless ::ActiveSupport::SecurityUtils.variable_size_secure_compare(regenerated_signature, requested_signature)
258
+
259
+ return false unless ::ActiveSupport::SecurityUtils.secure_compare(regenerated_signature, requested_signature)
260
+
261
+
262
+
263
+ return true
264
+
265
+ end
266
+
267
+
268
+
269
+ # @return [String|nil]
270
+
271
+ def find_secret_token(access_id)
272
+
273
+ # secret_tokenはDBに保存しておく
274
+
275
+ end
276
+
277
+
278
+
279
+ # リクエストから署名を作成
280
+
281
+ #
282
+
283
+ # @param [String] token 鍵文字列
284
+
285
+ # @param [String] url リクエストURL
286
+
287
+ # @param [String|nil] body リクエストボディ
288
+
289
+ # @param [String] timestamp - タイムスタンプ(ISO 8601)
290
+
291
+ # @return [String]
292
+
293
+ def create_signature(token, url, body, timestamp)
294
+
295
+ body = '' if body.nil?
296
+
297
+ content = [url, body, timestamp].map(&:strip).join
298
+
299
+ ::Base64.strict_encode64(::OpenSSL::HMAC.digest(DIGEST_METHOD, token, content))
300
+
301
+ end
302
+
303
+ end
304
+
305
+
306
+
307
+ # Railsコントローラ
308
+
309
+ class ExampleController < ApiBaseController
310
+
311
+ before_action :authentificate_api!
312
+
313
+
314
+
315
+ def index
316
+
317
+ render plain: 'ok'
318
+
319
+ end
320
+
321
+
322
+
323
+ def authentificate_api!
324
+
325
+ authentificator = HmacAuthentificator.new(request)
326
+
327
+ return true if @authentificator.valid?
328
+
329
+
330
+
331
+ fail(AuthentificationError, msg)
332
+
333
+ end
334
+
335
+ end
336
+
337
+ ```

1

サンプルの省略箇所を追記

2018/01/30 08:41

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -21,6 +21,8 @@
21
21
  まずはこの認証方法についてそもそもの理解ができているかの確認したく、
22
22
 
23
23
  記事のサンプルとは異なりますが自分の理解を兼ねて仕組みを以下に記載します。
24
+
25
+ ※元記事に記載があるナンスやタイムスタンプは省いています
24
26
 
25
27
 
26
28