PKCEについて気になった仕様いくつか

PKCEなんなの?

https://tools.ietf.org/html/rfc7636

スマホアプリがカスタムURLスキームで認可レスポンスを受信する場合、悪意のあるアプリがクライアントのアプリと同じカスタムURLスキームを利用していると、リダイレクト先が意図しないアプリになる可能性があって、その場合認可コードが盗まれる。 スマホアプリの場合、Clientのシークレットは安全ではないので、シークレットと認可コードを盗まれると、悪意のあるアプリがアクセストークンを取得できてしまう。

特に、Clientのシークレットがアプリに対して固定されてる場合、悪意のあるアプリ開発者はClientのアプリを自分で解析したりしてよしなにできちゃう。 という文脈で、Dynamic Client Registrationのが安全なんだな、という風に理解している。(が、そもそもアプリ側が脆弱だったりするとやっぱりシークレットは漏れる)

で、これをなんとかするための仕様がPKCE。

どうやるか?

  1. クライアントはcode_verifierという暗号学的に安全な乱数を生成し、そこからcode_challengeを生成して、認可リクエストに含める
    • このときcode_challenge_method、というパラメータを含めても良い
    • code_challenge_methodが指定もしくはPLAINの場合、code_challengeはcode_verifier
    • code_challenge_methodがSHA256の場合、code_challengeはBASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
  2. サーバーは認可コードをレスポンスする
    • このとき発行した認可コードと、クライアントが送信したcode_challenge、code_challenge_methodの値を紐づけて保持しておく
  3. クライアントはトークンリクエストの際に、認可リクエストの時に生成したcode_verifierをパラメーターを含める
  4. サーバーはトークンリクエストに含まれるcode_verifierから生成したcode_challengeが、認可リクエストで送信されてきたcode_challengeと同じかどうかを検証する
    • 異なっていた場合、エラーにする

これでなんでトークンが盗まれるのを防げるのか

  • 悪意のあるアプリは、認可コードは盗めるが、認可リクエストの内容は盗めない(盗めるケースについては後述)
  • ので、悪意のあるアプリはトークンリクエストで送信すべきcode_challengeの値がわからない
  • ので、悪意のあるアプリはトークンを発行できない

気になった仕様

サーバーが認可コードとクライアントが送信したcode_challenge、code_challenge_methodの値をどう保持するか

具体的に仕様では規定されてないんだけど、

Typically, the "code_challenge" and "code_challenge_method" values are stored in encrypted form in the "code" itself but could alternatively be stored on the server associated with the code. The server MUST NOT include the "code_challenge" value in client requests in a form that other entities can extract.

とあって、認可コードに暗号化して埋め込んじゃう話がある 認可コードをJWEにしちゃう、とかでいいはず ここの実装時にここの永続化がだるそうだなと思っていて、なるほど感があった

code_challenge_methodがSHA256だと何を守れるのか

 4b. A more sophisticated attack scenario allows the attacker to
      observe requests (in addition to responses) to the
      authorization endpoint.  The attacker is, however, not able to
      act as a man in the middle.  This was caused by leaking http
      log information in the OS.  To mitigate this,
      "code_challenge_method" value must be set either to "S256" or
      a value defined by a cryptographically secure
      "code_challenge_method" extension.

攻撃者が認可リクエストも見れちゃった場合、code_challenge=code_verifierだと認可リクエストに含まれるcode_challengeをそのままトークンリクエストに含めればトークンが取得できてしまう。 が、code_challengeがSHA256でハッシュ化してあると攻撃者はcode_verifierがわからないので、トークンを取得できない。

クライアントが認可リクエストにcode_challengeを指定しなかった場合は?後からPKCE対応したらどうなる?

If the server requires Proof Key for Code Exchange (PKCE) by OAuth public clients and the client does not send the "code_challenge" in the request, the authorization endpoint MUST return the authorization error response with the "error" value set to "invalid_request".

なので、エラーにしないといけない、が、5. Compatibilityに

Server implementations of this specification MAY accept OAuth2.0 clients that do not implement this extension. If the "code_verifier" is not received from the client in the Authorization Request, servers supporting backwards compatibility revert to the OAuth 2.0 [RFC6749] protocol without this extension.

とある。

認可リクエストで送信するのが"code_verifier"となっている意味がよくわからない(認可リクエストで送るのは"code_challenge"じゃないのか?)が、認可リクエストに"code_challenge"が含まれてなければPKCEしない、で良いのかな。 トークンリクエストに"code_verifier"がなかったら検証なし、だとそもそも成立しない(悪意のあるアプリがトークンを取得できてしまう)ので、それは違うと思うんだけども・・・。

qiita.com

この記事で紹介されているコードだと、認可リクエストに"code_challenge"が指定されてなかったらトークンリクエストの"code_verifier"をスキップしてるっぽいので、多分そういうことなんだろうな、と思う。(多分・・・)

2019年12月にやったこと

2019年12月にやったこと

冬休み入ってすぐパソコンが壊れたので修理に出したりしてかなり最悪だった。バンドメンバーを集めたりしていた。 あとQiitadonの忘年会に行ったりした。 http://karoten512.hatenablog.com/entry/2019/12/22/225640

同僚にCTFについて話を聞いて興味を持ったが手が回らんかった

体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践

読み終わった。PHPのコード読むのだるかったりとか知ってる話とかあんまり興味ない話が続いたりしてちょっとだれたけどまあ読んで良かったような気はする。

プログラミングコンテスト攻略のためのアルゴリズムとデータ構造

300ページくらいまでやった。 今年中に終わらせる気持ちでいたんだけどパソコン壊れた問題と後半に行くにつれて難易度が上がる問題で終わらなかったので、目標を誕生日までに終わらす、に変えた。

WebAuthn仕様

5章くらいまで流し読みした。 基本的な認証フローがわかってると割とサクサク読める気がする。 あと割と仕様だけじゃなくて例の話とかがあるのが良い。とりあえず全部読む。

https://www.w3.org/TR/webauthn/

マイクロサービスアーキテクチャ

Qiitadon忘年会の主催者の方の家にあったのを見せてもらったら面白そうだったので読み始めた。

これからやること

  • プログラミングコンテスト攻略のためのアルゴリズムとデータ構造
    • 読んでる
  • マイクロサービスアーキテクチャ
  • Linuxの仕組み
  • Goならわかるシステムプログラミング
  • 英語
  • 中国語
    • Toeic900超えるまで止める予定
  • ここ最近ほとんど業務でプログラミングをしなくなって、調整とかレビューとかばっかしてるがかなり雰囲気でやってるので、マネジメント系の本を読もうとしている
    • なにがいいのかよくわからん
  • Effective Go - The Go Programming Language
  • パタヘネ
  • OAuth2.0のクライアント書く
  • OAuth 2.0/OIDC関連仕様全部読む
  • WebAuthnのドキュメント読む

2019年11月にやったこと

2019年11月にやったこと

OAuth 2.0/OIDC関連の仕様読んでた。

体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践

半分くらい読んだ。知識として知ってることでも、開発中になんとなくセキュリティのために追加してた機能に対して、俺はこれで何を守りたいんだ?みたいな視点で見直したりできてよかった。読む。

現代暗号入門 いかにして秘密は守られるのか

JWT、JWSの仕様を読んだ後JWAの仕様を読もうとしたんだけど、その前に暗号の基礎知識欲しいなと思って読み始めた。 50ページくらい読んだところで差分解読法が全く理解できなくて停滞している。

プログラミングコンテスト攻略のためのアルゴリズムとデータ構造

200ページくらいまでやった。

OAuth 2.0/OIDC関連仕様

今月はこの辺りまで読んでた。 FAPI抜きでもまだ半分以上ある・・・。

  • RFC 7009: OAuth 2.0 Token Revocation
  • RFC 7515: JSON Web Signature (JWS)
  • RFC 7519: JSON Web Token (JWT)
  • RFC 7662: OAuth 2.0 Token Introspection
  • OAuth 2.0 Multiple Response Type Encoding Practices
  • OpenID Connect Session Management 1.0
  • OpenID Connect Front-Channel Logout 1.0 (Draft)
  • OpenID Connect Back-Channel Logout 1.0 (Draft)

OAuth 2.0 Multiple Response Type Encoding Practicesはやたら読み直してたので雑に訳?した。

inabajunmr.hatenablog.com

その他

FIDOアライアンス東京セミナーに行った。 台湾の政府系の対応状況の話とか印象的だった。 あとはWebAuthnのドキュメント読む前に紹介されてた CodelabsのWebAuthnのやつやろうかなとか。

FIDO認定とGoogleの対応状況のセッションはまとめてブログにアップした。

dev.classmethod.jp

dev.classmethod.jp

あとはOpenID Connect Session Management 1.0のブログ書いたりとか。

dev.classmethod.jp

いつ書くかなーと思いながら雑に認証認可アドベントカレンダーに登録したので書いてしまった。

これからやること

  • プログラミングコンテスト攻略のためのアルゴリズムとデータ構造
    • 読んでる
  • ElectronかWebアプリ(サーバなし)でNature RemoのPC用クライアントを作る
    • なぜか俺は音声やスマホよりもPCで操作したい時がたまにある
    • あとはSPAとJSの学習用に
  • Goならわかるシステムプログラミング
  • Kotlinがらみなんか
    • Kotlinインアクションとか
  • 英語
  • 中国語
    • Toeic900超えるまで止める予定
  • ここ最近ほとんど業務でプログラミングをしなくなって、調整とかレビューとかばっかしてるがかなり雰囲気でやってるので、マネジメント系の本を読もうとしている
    • なにがいいのかよくわからん
  • Effective Go - The Go Programming Language
  • パタヘネ
  • OAuth2.0のクライアント書く
  • OAuth 2.0/OIDC関連仕様全部読む
  • WebAuthnのドキュメント読む

OAuth 2.0 Multiple Response Type Encoding Practicesの和訳風怪文書

以下は、OAuth 2.0 Multiple Response Type Encoding Practicesの和訳風怪文書です。 読んでいて意味がよくわからなかった部分については、🍙がついています。 具体的には、none の用途と、response_mode を混在すべき理由が理解できていません。

Abstract

本仕様はOAuth 2.0のスペース文字を含むResponse Typeの値を利用する認可リクエストに対するレスポンスの適切なエンコードのガイダンスを提供します。 さらに仕様では、いくつかの新しいレスポンスタイプの値を、OAuth Authorization Endpoint Response Types registryに登録します。

この仕様では、認可リクエストのパラメーター、'レスポンスモード'も定義します。これらの値は、認可エンドポイントから認可レスポンスのパラメーターを返却するためのメカニズムを認可サーバーに伝えるために利用されます。

1. Introduction

1.1. Requirements Notation and Conventions

1.2. Terminology

2. Response Types and Response Modes

レスポンスタイプリクエストパラメーター 'response_type' は、認可サーバーにエンドポイントからどのパラメーターが返却されるのかを含んだ、期待する認可処理フローを伝えます。 レスポンスモードリクエストパラメーター 'response_mode' は、認可エンドポイントから返却される認可レスポンスを返却するために使われるメカニズムを、認可サーバーに伝えます。 各レスポンスタイプの値は、レスポンスモードが指定されなかった場合に利用されるデフォルトのレスポンスモードも定義します。

2.1. Response Mode

本仕様は以下のOAuth認可リクエストパラメーターを定義します。

  • response_mode 任意の値。認可サーバーに、認可エンドポイントから認可レスポンスパラメーターを返却するのに利用されるメカニズムを伝えます。 レスポンスタイプが利用するデフォルトのレスポンスモードと同じ値を指定する場合、本パラメーターの利用は推奨されません。 本仕様は以下のレスポンスモードの値を定義します。

  • query このモードでは、認可レスポンスパラメーターはクライアントにリダイレクトする際の redirect_uri に付与されるクエリストリングにてエンコードされます。

  • fragment このモードでは、認可レスポンスパラメーターはクライアントにリダイレクトする際の redirect_uri に付与されるフラグメントにてエンコードされます。

OAuth 2.0 code レスポンスタイプのデフォルトのレスポンスモードは、クエリエンコーディングです。 OAuth 2.0 token レスポンスタイプのデフォルトのレスポンスモードは、フラグメントエンコーディングです。

追加のレスポンスモードを定義している仕様の例の為には、OAuth 2.0 Form Post Response Mode[OAuth.Post]を参照してください。 今後、HTML5 postMessage APIやクロスオリジンリソースシェアリング(CORS)を利用することのできるものを含めて、他の仕様で追加のレスポンスモードが定義されることが想定されることを留意してください。

2.2. Multiple-Valued Response Types

複数の値のレスポンスタイプが定義される場合、認可エンドポイントから発行されるレスポンスの為に、以下のエンコーディングルールが適用されることを推奨します。

認可エンドポイントから返却される全てのパラメーターは、同じレスポンスモードを利用すべきです。これは、成功、失敗いずれのレスポンスにも適用されるべきです。

根拠: これはクライアントのパラメーター処理を単純化します。以下で説明しているように、パフォーマンスについての利点もあります。

例えば、レスポンスがフラグメントでエンコードされた部分を含む場合、クライアントのユーザーエージェントコンポーネントはレスポンスの処理を完了する必要があります。🍙 もし新しいクエリパラメーターがクライアントURIに付与された場合、それはユーザーエージェントがクライアントURIを再取得する原因となり、ユーザーエージェントベースのクライアントコンポーネントの継続的ではない操作を引き起こします。🍙 もしフラグメントエンコーディングだけが利用される場合、ユーザーエージェントはフラグメントを処理し、クライアントのホストへ必要に応じてパラメータを(例えばXmlHttpRequestを通じて)送信する、クライアントコンポーネントの再活性化を単純化するでしょう。🍙 したがって、全体をフラグメントエンコーディングすることは、レスポンスの処理において低いレイテンシをもたらします。

3. ID Token Response Type

このセクションでは新しいレスポンスタイプ id_token を OAuth2.0 のセクション8.4の仕様にしたがって登録します。 id_token の用途は、認可サーバーによって解釈されるリソースオーナーのアイデンティティアサーションを提供することです。 そのアサーションは、対象としたオーディエンスを明示しなければいけません。ただし、アサーションの具体的なセマンティクスや、それをどのようにバリデーションするかについては、本ドキュメントでは言及しません。

  • id_token OAuth 2.0 認可リクエストにおいて response_type として提供された場合、成功レスポンスは id_token パラメーターを含む必要があります。 認可サーバーは認可コード、アクセストークン、アクセストークンタイプを、グラントリクエストの成功レスポンスで返却すべきではありません。 もし redirect_uri が提供された場合、ユーザーエージェントは id_token の付与もしくはアクセスの拒否後に、そこにリダイレクトされるべきです。 このリクエストは state パラメーターを含むことができます。その場合、認可サーバーは成功もしくはエラーレスポンスを発行する際に、レスポンスパラメーターとしてその値を返す必要があります。 このレスポンスタイプのデフォルトのレスポンスモードはフラグメントエンコーディングであり、クエリエンコーディングを利用してはいけません。 成功もしくはエラーレスポンスは提供されたレスポンスモードを利用して返却するべきです。 何も指定されなかった場合、デフォルトのレスポンスモードを利用します。

id_token をフラグメントで返却することは、id_token の送信中の漏洩の可能性を減らし、ユーザー(リソースオーナー)のプライバシーに関連するリスクを軽減します。

4. None Response Type

このセクションではレスポンスタイプ none を OAuth2.0 のセクション8.4の仕様にしたがって登録します。 この用途は、パーティが認可サーバーに保護リソースへのアクセス付与の登録をクライアントに代わってリクエストするが、その時点ではクライアントに返却されるクレデンシャルを必要としない場合のユースケースを可能にすることです。 最終的にクライアントがアクセスのクレデンシャルを得る手段は、ここでは指定されません。

1つのシナリオは、マーケットからユーザーがアプリケーションを購入することを期待していて、さらにアプリケーションのインストールの認可を望み、1つのステップでアプリケーションの保護リソースへのアクセスを付与することです。🍙 けれども、ユーザーはその時点で(まだアクティベートされていない)アプリケーションとのインタラクトがないので、認可ステップで同時にアクセスのクレデンシャルを返すことは適切ではありません。🍙

  • none このレスポンスタイプパラメーターが OAuth 2.0 認可リクエストに提供された時、認可サーバーは OAuth 2.0 認可コード、アクセストークン、アクセストークンタイプ、IDトークンをグラントリクエストに対する成功レスポンスで返すべきではありません。 もし redirect_uri が提供された場合、ユーザーエージェントは id_token の付与もしくはアクセスの拒否後に、そこにリダイレクトされるべきです。 このリクエストは state パラメーターを含むことができます。その場合、認可サーバーは成功もしくはエラーレスポンスを発行する際に、レスポンスパラメーターとしてその値を返す必要があります。 このレスポンスタイプのデフォルトのレスポンスモードはフラグメントエンコーディングであり、クエリエンコーディングを利用してはいけません。 成功もしくはエラーレスポンスは提供されたレスポンスモードを利用して返却するべきです。 このレスポンスタイプのためのデフォルトのレスポンスモードはクエリエンコーディングです。 成功もしくはエラーレスポンスは提供されたレスポンスモードを利用して返却するべきです。 何も指定されなかった場合、デフォルトのレスポンスモードを利用します。

このレスポンスタイプ none は、他のレスポンスタイプと組み合わせるべきではありません。

5. Definitions of Multiple-Valued Response Type Combinations

このセクションはそれぞれ個別に登録されたレスポンスタイプ code、 token id_token の組み合わせを定義します。

  • code token この response_type パラメーターが指定された時、成功レスポンスはアクセストークン、アクセストークンタイプ、そして認可コードを含む必要があります。 このレスポンスタイプのためのデフォルトのレスポンスモードはフラグメントエンコーディングであり、クエリエンコーディングは利用してはいけません。 成功もしくはエラーレスポンスは提供されたレスポンスモードを利用して返却するべきです。 何も指定されなかった場合、デフォルトのレスポンスモードを利用します。

  • code id_token この response_type パラメーターが指定された時、成功レスポンスは認可コードと id_token を含む必要があります。 このレスポンスタイプのためのデフォルトのレスポンスモードはフラグメントエンコーディングであり、クエリエンコーディングは利用してはいけません。 成功もしくはエラーレスポンスは提供されたレスポンスモードを利用して返却するべきです。 何も指定されなかった場合、デフォルトのレスポンスモードを利用します。

  • code id_token token この response_type パラメーターが指定された時、成功レスポンスは認可コードと id_token 、そしてアクセストークンとアクセストークンタイプを含む必要があります。 このレスポンスタイプのためのデフォルトのレスポンスモードはフラグメントエンコーディングであり、クエリエンコーディングは利用してはいけません。 成功もしくはエラーレスポンスは提供されたレスポンスモードを利用して返却するべきです。 何も指定されなかった場合、デフォルトのレスポンスモードを利用します。

全てのレスポンスタイプのリクエストは state パラメーターを含むことができます。その場合、認可サーバーは成功もしくはエラーレスポンスを発行する際に、レスポンスパラメーターとしてその値を返す必要があります。

ユーザーエージェントによって発行/受信する参考のリクエスト、レスポンス例(余分な改行は表示用)は、

  GET /authorize?
    response_type=id_token%20token
    &client_id=s6BhdRkqt3
    &redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
    &state=af0ifjsldkj HTTP/1.1
  Host: server.example.com
  HTTP/1.1 302 Found
  Location: https://client.example.org/cb#
  access_token=SlAV32hkKG
  &token_type=bearer
  &id_token=eyJ0 ... NiJ9.eyJ1c ... I6IjIifX0.DeWt4Qu ... ZXso
  &expires_in=3600
  &state=af0ifjsldkj

7. Security Considerations

クエリストリング内のエンコーディングレスポンスはセキュリティに関連があります。 HTTPリファラーヘッダーは、クエリパラメータを含み、クエリパラメーターにエンコードされた値はサードパーティに漏洩し得ます。 コンフィデンシャルクライアントを利用している場合、認可コードをクエリパラメーターでエンコードするのは安全です。(サードパーティが保持していないクライアントシークレットなしに、利用できないため) ただし、アクセストークンやIDトークンのようなさらにセンシティブな情報は、クエリストリングでエンコードしてはいけません。 デフォルトのレスポンスモードがフラグメントエンコーディングの認可レスポンスパラメーターは、常にクエリエンコーディングを利用すべきではありません。

sliceをrangeでループして取得した値のフィールドを更新しても、元のsliceは更新されない(rangeで取得した値はコピー)

AOJやっててハマったので

package main

import (
    "fmt"
)

type Element struct {
    number int
}

func main() {
    Elementのsliceの場合()
    Elementのポインタのsliceの場合()
}

func Elementのsliceの場合() {
    elements := []Element{}
    for i := 0; i < 2; i++ {
        elements = append(elements, Element{i})
    }
    fmt.Println(elements) // 0 1
    elements[0].number = 10
    fmt.Println(elements) // 10 1

    // これは99にならない
    for _, elem := range elements {
        elem.number = 99
    }
    fmt.Println(elements) // 10 1

    // これは99になる
    for i := 0; i < 2; i++ {
        elements[i].number = 99
    }
    fmt.Println(elements) // 99 99
}

func Elementのポインタのsliceの場合() {
    elements := []*Element{}
    for i := 0; i < 2; i++ {
        elements = append(elements, &Element{i})
    }
    fmt.Println(elements) // 0 1

    // これは99になる
    for _, elem := range elements {
        elem.number = 99
    }
    fmt.Printf("%v %v\n", elements[0].number, elements[1].number)
}

rangeで返ってくる値は要素のコピーになる(=参照が別)のかなと思ってポインタを見てみた感じ、そうっぽい

package main

import (
    "fmt"
)

type Element struct {
    number int
}

func main() {
    Elementのsliceの場合のポインタ()
    Elementのポインタのsliceの場合のポインタ()
}

func Elementのsliceの場合のポインタ() {
    elements := []Element{}
    for i := 0; i < 2; i++ {
        elements = append(elements, Element{i})
    }

    fmt.Println("各要素のポインタ:")
    fmt.Printf("element[0] pointer:%p\n", &elements[0])
    fmt.Printf("element[1] pointer:%p\n", &elements[1])

    fmt.Println("rangeの場合のポインタ:")
    for _, elem := range elements {
        // このポインタは&elements[0]とも&elements[1]とも異なる
        // さらに、ループ内で&elemはどの要素に対するポインタも同じ
        fmt.Printf("element[%v]] pointer:%p\n", elem.number, &elem)
    }

}

func Elementのポインタのsliceの場合のポインタ() {
    elements := []*Element{}
    for i := 0; i < 2; i++ {
        elements = append(elements, &Element{i})
    }
    fmt.Println("各要素のポインタ:")
    fmt.Printf("element[0] pointer:%p\n", &elements[0])
    fmt.Printf("element[1] pointer:%p\n", &elements[1])

    for _, elem := range elements {
        // このポインタは&elements[0]とも&elements[1]と等しい
        fmt.Printf("element[%v]] pointer:%p\n", elem.number, elem)
        // ループ内で&elemはどの要素に対するポインタも同じ(ポインタのポインタになってるはず)
        fmt.Printf("element[%v]] pointer:%p\n", elem.number, &elem)

    }
}

と思ったらtour of goにも書いてあった https://tour.golang.org/moretypes/16

When ranging over a slice, two values are returned for each iteration. The first is the index, and the second is a copy of the element at that index.

channelも同じような感じ

package main

import "fmt"

type Element struct {
    number int
}

func send(c chan Element) {
    for i := 0; i < 3; i++ {
        elem := Element{i}
        fmt.Printf("send: %p\n", &elem)
        c <- elem
    }
    close(c)
}

// send: 0xc000094008
// send: 0xc000094018
// range: 0xc000094000
// range: 0xc000094000
// send: 0xc000018058
// range: 0xc000094000
func main() {
    c := make(chan Element)
    go send(c)

    for val := range c {
        fmt.Printf("range: %p\n", &val)
    }
}

関数に渡した場合にコピーになる奴でもちょっとハマったんだよな

どうするか

  • インデックスでループしてインデックスでアクセス
  • rangeでループしてインデックスでアクセス
  • ポインタの配列にする

あたり?

2019年10月にやったこと

2019年10月にやったこと

アルゴリズムの本読みながら問題解いてたら終わったのであんまり書くことがない。 なぜかFinal: OpenID Authentication 2.0 - 最終版を読んだりしていた。

英語

レアジョブの先生に「ディズニーの映画を見ろ。1週間同じやつをみ続けろ。1ヶ月で4本だ。」と言われ、アラジンを7回みた。

その後TOEICの結果が返ってきて、思ったよりだいぶ良い結果だったので、その勢いで勉強が停滞している。

プログラミングコンテスト攻略のためのアルゴリズムとデータ構造

いい加減アルゴリズムをやるかと思って初めて、178ページまでやった。なんとなくGoでやっている。 Javaのコレクションライブラリって便利なんだな・・・とかジェネリクス欲しいな・・・とかそういう気持ちになりつつも面白いのでちまちま解いている。

体系的に学ぶ 安全なWebアプリケーションの作り方 第2版 脆弱性が生まれる原理と対策の実践

半額だったので勢いで買ってしまった。 3割くらい読んだが今の所別に読まなくてもよかったかなあという気持ちが若干出てきたがさらい直しておくべき分野なのはそうなので、ざらっと読む。

Final: OpenID Connect Core 1.0 incorporating errata set 1

とりあえず一通り読んだ。これとか全然知らなかった。

その他

idance.connpass.com

これにいったりしていた。WebAuthnのドキュメントを読みたいが時間がない。

OpenID Connect Session Management 1.0のブログを書きたいがこれも時間がない。

これからやること

  • プログラミングコンテスト攻略のためのアルゴリズムとデータ構造
    • 読んでる
  • ElectronかWebアプリ(サーバなし)でNature RemoのPC用クライアントを作る
    • なぜか俺は音声やスマホよりもPCで操作したい時がたまにある
    • あとはSPAとJSの学習用に
  • Goならわかるシステムプログラミング
  • Kotlinがらみなんか
    • Kotlinインアクションとか
  • 英語
  • 中国語
    • Toeic900超えるまで止める予定
  • ここ最近ほとんど業務でプログラミングをしなくなって、調整とかレビューとかばっかしてるがかなり雰囲気でやってるので、マネジメント系の本を読もうとしている
    • なにがいいのかよくわからん
  • Effective Go - The Go Programming Language
  • パタヘネ
  • OAuth2.0のクライアント書く