Upgrade to Pro — share decks privately, control downloads, hide ads and more …

米国のサイバーセキュリティタイムラインと見る Goの暗号パッケージの進化

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

米国のサイバーセキュリティタイムラインと見る Goの暗号パッケージの進化

Avatar for tom twinkle

tom twinkle

February 25, 2026
Tweet

More Decks by tom twinkle

Other Decks in Programming

Transcript

  1. © 2026 ANDPAD All Rights Reserved. ANDPADとは 社内 現場 営業

    / 監督 / 設計 事務 / 管理職 職人 / 業者 メーカー / 流通 現場の効率化から経営改善まで一元管理できる クラウド型建設プロジェクト管理サービス 案件管理 資料 工程表 写真 報告 チャット 黒板 図面 受発注 • • • 
 

  2. © 2026 ANDPAD All Rights Reserved. Go を間接的に使っているプロダクト のプロダクト Go

    がメインのプロダクト 施工管理 図面 引合粗利管理 検査 黒板 受発注 ボード 資料承認 おうちノート … 歩掛管理 請求管理 入退場管理 遠隔臨場 ANDPAD と Go
  3. © 2026 ANDPAD All Rights Reserved. • Adam Langley (agl)

    https://github.com/agl • David Crawshaw https://github.com/crawshaw • Russ Cox (rsc) https://github.com/rsc • Filippo Valsorda (FiloSottile) https://github.com/FiloSottile • Roland Shoemaker https://github.com/rolandshoemaker Goのcryptoパッケージの主要メンテナー
  4. © 2026 ANDPAD All Rights Reserved. • Goの初期のcryptoパッケージの設計と実装 • OpenSSLをforkしたBoringSSLのコアメンテナー

    • IETFにおいてTLS1.3の策定に深く関与 (RFC 7918, RFC7685 etc) • Certificate Transparencyの開発 • FIDO/WebAuthnやPassKeyの標準化と実装 • Google Chromeのsandboxの設計と実装 • Google内部通信インフラのポスト量子暗号導入第一人者 Adam Langley (agl)
  5. © 2026 ANDPAD All Rights Reserved. • 車輪の再発明を避ける • パフォーマンスの最適化

    • セキュリティパッチへの追従 複雑な暗号処理を専門家に委譲する、これはこれで合理的 プログラミング言語のOpenSSL依存
  6. © 2026 ANDPAD All Rights Reserved. Goのcryptoは ”最初から” 標準で入っている https://www.reddit.com/r/golang/comments/ityww8/comment/g5itrh1

    Adam LangleyはGoプロジェクト初期から参加し非常に高品 質な暗号ライブラリ群を開発しました。 Goは最初から優れた暗号機能を備えていました。 後付けの追加機能ではないのです。
  7. © 2026 ANDPAD All Rights Reserved. • GoogleのセキュリティチームNeel Mehtaにより発見 •

    修正パッチを作成したのはAdam Langley ◦ その後OpenSSLをforkしBoringSSL「Boring(退屈)なほ ど安全で予測可能な暗号ライブラリ」を立ち上げ ◦ BoringSSLはGoogleインフラやAndroid等で広く利用 • Goのcrypto/tlsはこの脆弱性の影響を受けなかった (正確にはAdamがこの機能自体を不要と削っていた) 2014年 CVE-2014-0160(Heartbleed) https://heartbleed.com/
  8. © 2026 ANDPAD All Rights Reserved. 閑話休題 Fifty Years of

    Open Source Software Supply-Chain Security - Russ Cox Ken Thompson 先生、曰く 「教訓は明らかだ:自分等が完全に自作し たコード以外は信用できない」
  9. © 2026 ANDPAD All Rights Reserved. FIPS 140は米国NIST暗号モジュールセキュリティ認証標準 医療、国防などセキュリティが重要な分野での使用が可能 CやC++に依存せず

    標準ライブラリだけで FIPS 140 認証を取得出来ているのは (Go1.24以降の)「Go言語」だけ Javaはpure JavaのBC-FJAがあるがサードパーティー製 C# はOSのCモジュールに依存 Python / Node / Rust などの多くの言語はC/C++ライブラリをWrap FIPS 140 認証とGo
  10. © 2026 ANDPAD All Rights Reserved. 2019年6月7日 - proposal: adopt

    golang.org/design/cryptography-principles #32466 https://go.dev/issues/32466 Safe 目標は、ライブラリを単に利用可能にするだけでなく、安全に利用しやすいものにすることです。なぜなら、ライ ブラリの誤用は脆弱性と同様にアプリケーションにとって危険だからです。 「デフォルトの動作は可能な限り安全であるべき」 「安全でない機能は簡単に使えないようにする」
  11. © 2026 ANDPAD All Rights Reserved. 2021年9月15日 - Automatic cipher

    suite ordering in crypto/tls https://go.dev/blog/tls-cipher-suites
  12. © 2026 ANDPAD All Rights Reserved. 2020年12月13日 - SolarWinds事件 米SolarWinds社のIT管理ソフト

    「Orion」の正規アップデートプログ ラムに、攻撃者が悪意あるコード を混入 米国財務省、国土安全保障省、 Microsoft、FireEye(発見元)など 約18,000組織が汚染されたアッ プデートをダウンロード ロシア対外情報庁(SVR)に関連 するグループ(Nobelium)による 国家主導のサイバースパイ活動 と断定 https://piyolog.hatenadiary.jp/entry/2020/12/20/045153
  13. © 2026 ANDPAD All Rights Reserved. 2020年12月13日 - SolarWinds事件 Russ

    Cox Goの開発者コミュニティには、これに関する格言があります。 「少しの依存関係より、少しのコピーのほうがマシ( A little copying is better than a little dependency)」 Surviving Software Dependencies (2019) https://research.google/pubs/surviving-software-dependencies/ Russ Cox 「SolarWindsのようなトロイの木馬型の攻撃に対しては、単にコードを安全に書 くだけでは不十分であり、ビルドの透明性と認証の確立が不可欠 」 Securing the AI Software Supply Chain(2024) https://research.google/pubs/securing-the-ai-software-supply-chain/
  14. © 2026 ANDPAD All Rights Reserved. 2021年5月7日 - Colonial Pipeline事件

    米国東海岸の燃料供給の約 45% を担う最大級の石油パイプライン で従業員のパスワード漏洩( VPN アカウント)を起点としたランサム ウェア攻撃 東海岸でのガソリン不足、パニッ ク買い、航空便の欠航、燃料価格 の高騰 復旧を急ぐため、約440万ドル(当 時のレートで約5億円)相当のビッ トコインを支払い ロシア拠点のサイバー犯罪集団 「DarkSide」が実行犯 https://piyolog.hatenadiary.jp/entry/2021/05/12/051650
  15. © 2026 ANDPAD All Rights Reserved. 2021年5月12日 - 大統領令第14028号 “Executive

    Order on Improving the Nation’s Cybersecurity” https://bidenwhitehouse.archives.gov/briefing-room/presidential-actions/2021/05/12/executive-order-on-improving-the-nations-cybersecurity/ サイバー攻撃がやべえで、国と民間が もっと情報共有せなあかん! 「ゼロトラスト」や「SBOM」でソフトの守 りをガチガチに固めて、官民一丸となっ て速攻で対策できるようにルールを作 り直すんだわ しっかりやってよ!
  16. © 2026 ANDPAD All Rights Reserved. 2021年8月5日 - JCDC(共同サイバー防御コラボレーティブ)の設立 サイバー攻撃は一人の手に負えるもんやないから

    官民で一致団結して守ろうや! https://bidenwhitehouse.archives.gov/briefing-room/presidential-actions/2021/05/12/executive-order-on-improving-the-nations-cybersecurity/
  17. © 2026 ANDPAD All Rights Reserved. 2021年11月3日 - BOD 22-01:

    Reducing the Significant Risk of Known Exploited Vulnerabilities ええか、世の中に脆弱性は 山ほどあるけど、まずは実 際に悪用されてるヤバいや つ(KEV)から速攻で片付け や! 2021年より後に出たやつは 2週間以 内に直さなあかんから、のんびりして られへんで スコアが高い低いも大事やけど、現 実に泥棒が使ってる鍵穴から塞ぐん が一番効率ええやろ? ちゃんとリスト見て、サボらんと更新し ときや! https://www.cisa.gov/news-events/directives/bod-22-01-reducing-significant-risk-known-exploited-vulnerabilities
  18. © 2026 ANDPAD All Rights Reserved. 2022年2月24日 - ロシアがウクライナに侵攻開始 CISA「Shields

    Up」キャンペーン https://www.cisa.gov/shields-up 今はロシアの情勢もあってサイ バー攻撃のリスクがむっちゃ上 がってるから、組織のトップも現 場も全員『シールド全開 (Shields Up)』でガチガチに警 戒してや! もし『これ、攻撃されてへんか?』って少 しでも怪しいことあったら、迷わずすぐに 報告や 一人の油断がみんなの命取りになるか ら、気ぃ引き締めていこか!
  19. © 2026 ANDPAD All Rights Reserved. 2023年3月2日 - ホワイトハウス「National Cybersecurity

    Strategy」の発表 https://www.cisa.gov/topics/cyber-threats-and-advisories/information-sharing/cyber-incident-reporting-critical-infrastructure-act-2022-circia ネットの安全を、個人やちっこい会社に 丸投げしとっちゃいかんわ 力のある大きいとこが、責任持って準 備せなあかん 今さえ良ければええんじゃなくて、先の こと考えてしっかり投資してかな、えら いことになるがね
  20. © 2026 ANDPAD All Rights Reserved. 2023年4月13日 - CISA「Secure by

    Design」ガイドラインの発表 https://www.cisa.gov/securebydesign
  21. © 2026 ANDPAD All Rights Reserved. ソフトウェア製造者に向けたガイドライン • メモリ安全なプログラミング言語を利用せよ •

    セキュリティに関する機能を後付けするな • デフォルト設定を安全に設計せよ(Secure by Default) • 安全でないレガシー機能を積極的に廃止せよ • 脆弱性を管理し統計と傾向を公表せよ Secure by Design?
  22. © 2026 ANDPAD All Rights Reserved. Goの設計段階から考慮されていた内容 • メモリ安全なプログラミング言語を利用せよ •

    セキュリティに関する機能を後付けするな ◦ crypto#SignMessage 実装 etc • 安全でないレガシー機能を積極的に廃止せよ ◦ crypto/dsa廃止、math/randのSeed廃止、crypto/rsa 1024bit key廃止 etc Go 1.20以降徐々に適用 • デフォルト設定を安全に設計せよ(Secure by Default) ◦ math/randのデフォルト暗号生成器をChaCha8に差し替え etc • 脆弱性を管理し統計と傾向を公表せよ ◦ Go vulnerability database https://go.dev/blog/vuln Secure by Design?
  23. © 2026 ANDPAD All Rights Reserved. 2023年4月13日 - CISA「Secure by

    Design」ガイドラインの発表 https://zenn.dev/tomtwinkle/articles/33bf277ea526c4
  24. © 2026 ANDPAD All Rights Reserved. 米国のサイバーセキュリティタイムラインと振り返る Go 2020年2月25日 -

    Go 1.14 is released crypto系更新2件 2020年8月11日 - Go 1.15 is released crypto系更新6件 2020年12月13日 - SolarWinds事件 2021年2月16日 - Go 1.16 is released crypto系更新4件 2021年5月12日 - 大統領令第14028号 “Executive Order on Improving the Nation’s Cybersecurity” 2021年8月5日 - JCDC(共同サイバー防御コラボレーティブ)の設立 2021年8月16日 - Go 1.17 is released crypto系更新5件 2021年9月15日 - Automatic cipher suite ordering in crypto/tls 2022年2月24日 - ロシアがウクライナに侵攻開始、 CISA「Shields Up」キャンペーン 2022年3月15日 - Go 1.18 is released crypto系更新3件 2022年3月31日 - How Go Mitigates Supply Chain Attacks 2022年8月2日 - Go 1.19 is released crypto系更新5件 2022年9月6日 - Vulnerability Management for Go 2023年2月1日 - Go 1.20 is released crypto系更新 7件 2023年4月13日 - CISA「Secure by Design」ガイドラインの発表 2023年7月13日 - Govulncheck v1.0.0 is released! 2023年8月8日 - Go 1.21 is released crypto系更新 7件 2024年2月6日 - Go 1.22 is released crypto系更新 4件 2024年8月13日 - Go 1.23 is released crypto系更新 2件 2025年2月11日 - Go 1.24 is released crypto系更新 17件 2025年8月12日 - Go 1.25 is released crypto系更新 9件 2026年2月11日 - Go 1.26 is released crypto系更新 17件 https://go.dev/blog/go1.26
  25. © 2026 ANDPAD All Rights Reserved. • 共通鍵暗号 ◦ 送信者と受信者が同じ暗号鍵

    (共通鍵)でメッセージを暗号化・復号する。 ◦ 処理は早いが、鍵を相手に渡すのが難しい。 • 公開鍵暗号 ◦ 受信者が公開鍵と秘密鍵を用意し、送信者に公開鍵を提供する。 ◦ 送信者は公開鍵でメッセージを暗号化し 受信者は秘密鍵でメッセージを復号する。 ◦ 鍵の受け渡しは安全だが、計算が重すぎて大きなデータの暗号化には向かない。 • ハイブリッド暗号 ◦ 受信者が公開鍵と秘密鍵を用意し、送信者に公開鍵を提供する。 ◦ 送信者は共通鍵を作成し、メッセージを 共通鍵で暗号化する。 ◦ 受信者の公開鍵を使用して共通鍵を暗号化する。 ◦ 送信者は「暗号化されたメッセージ」と「暗号化された共通鍵」を送信する。 ◦ 受信者は「暗号化された共通鍵」を 秘密鍵で復号し共通鍵を取得する。 ◦ 受信者は共通鍵で「暗号化されたメッセージ」を復号する。 ◦ 送信者と受信者の間で共通鍵が交換された後はそのセッション間は 共通鍵でメッセージをやり取り する。 ハイブリッド暗号の復習
  26. © 2026 ANDPAD All Rights Reserved. ハイブリッド暗号の復習 受信者(Recipient) 送信者(Sender) RSA

    2024bit GenerateKey() rsa.PrivateKey rsa.PublicKey rsa.PublicKey AES-GCM暗号化 (暗号文) パラメータ生成 (crypto/rand) 共通鍵 (crypto/aes) Nonce (12byte) 平文 パッキング 暗号文 平文 ここから開 始 RSA-OAEP暗号化 (AES鍵) 暗号文 アンパッキン グ RSA-OAEP復号 (AES鍵) Nonce (12byte) AES-GCM復号 (暗号文) 共通鍵 (crypto/aes)
  27. © 2026 ANDPAD All Rights Reserved. RSA (crypto/rsa) + ハッシュ関数(crypto/sha256)

    + AES (crypto/aes) + GCM (crypto/cipher) Go 1.26以前のRSAハイブリッド暗号 1: // ====== 受信者(Recipient) ====== 2: // 1-1. 公開鍵暗号方式の公開鍵、秘密鍵を作成 3: receiverPrivKey, err := rsa.GenerateKey(rand.Reader, 2048) 4: receiverPubKey := &receiverPrivKey.PublicKey 5: 6: // ====== 送信者(Sender) ====== 7: // 2-1. ワンタイム共通鍵の生成 8: sessionKey := make([]byte, 32) 9: _, err := io.ReadFull(rand.Reader, sessionKey) 10: 11: // 2-2. AES-GCM(共通鍵)の準備 12: block, err := aes.NewCipher(sessionKey) 13: gcm, err := cipher.NewGCM(block) 14: 15: // 2-3. Nonceの生成 16: nonce := make([]byte, gcm.NonceSize()) 17: _, err := io.ReadFull(rand.Reader, nonce) 18: 19: // 2-4. データ本体の暗号化 20: aad := []byte("Additional Authenticated Data to Tom") 21: cipherText := gcm.Seal(nil, nonce, plaintext, aad) 22: 23: // 2-5. 共通鍵をRSA-OAEPで暗号化 24: info := []byte("Encryption Key Label to Login") 25: encryptedSessionKey, err := rsa.EncryptOAEP(sha256.New(), rand.Reader, pubKey, sessionKey, info) NG例: crypto/randではなくmath/randを利用してしまう Go 1.20でmath/rand#Seedが固定値(1)ではなくなり Go 1.22でmath/randの乱数生成器がChaCha8になり多少マシに とはいえcrypto/rand以外を間違えて利用してしまう可能性はある NG例:鍵の長さが足りない Go 1.24以前は脆弱な1024bit鍵が指定可能だった そもそも実装者が暗号鍵の長さを指定する必要がある NG例: Nonceを固定値、小さな値で運用してしまう 乱数値の生成を忘れたり、Nonceのサイズが小さい状態で実装されてしま う NG例: 暗号鍵のラベル情報 (info)の検証なし infoをnilにすると異なる処理で同じ暗号鍵を使い回せてしまう、クロスコン テキスト攻撃の可能性 NG例: メッセージ毎 Additional Authenticated Data(aad)検証なし addをnilにすると同メッセージを何度も送れるリプレイ攻撃の可能性
  28. © 2026 ANDPAD All Rights Reserved. RSA (crypto/rsa) + ハッシュ関数(crypto/sha256)

    + AES (crypto/aes) + GCM (crypto/cipher) Go 1.26以前のRSAハイブリッド暗号 1: // ====== 受信者(Recipient) ====== 2: // 3-1. RSA暗号化済みワンタイム共通鍵の長さを読み取る 3: var keyLen uint32 4: err := binary.Read(reader, binary.LittleEndian, &keyLen) 5: 6: // 3-2. RSA暗号化済みワンタイム共通鍵を取り出す 7: encryptedSessionKey := make([]byte, keyLen) 8: _, err := io.ReadFull(reader, encryptedSessionKey) 9: 10: // 3-3. ワンタイム共通鍵を復号 11: info := []byte("Encryption Key Label to Login") 12: sessionKey, err := rsa.DecryptOAEP(sha256.New(), rand.Reader, privKey, encryptedSessionKey, info) 13: 14: // 3-4. Nonceを取り出す 15: gcmNonceSize := 12 16: nonce := make([]byte, gcmNonceSize) 17: _, err := io.ReadFull(reader, nonce) 18: 19: // 3-5. 残りのデータをAES暗号文として読み込む 20: cipherText, err := io.ReadAll(reader) 21: 22: // 3-6. AES-GCMで復号 23: aad := []byte("Additional Authenticated Data to Tom") 24: block, err := aes.NewCipher(sessionKey) 25: gcm, err := cipher.NewGCM(block) 26: plaintext, err := gcm.Open(nil, nonce, cipherText, aad) NG例: 共通鍵の復号とメッセージの復号時に異なるエラーで返却 こちらも攻撃者にRSA復号、AES復号どちらで失敗したか判別されてし まい、パディングオラクル攻撃のきっかけになる NG例: 暗号メッセージのサイズ検証不足 DoS攻撃により巨大な暗号メッセージを送りつけることでOOMを引き起 こしサービス停止が可能 NG例: 復号処理途中のエラーで Early Returnしてしまう エラーが返るまでのタイミングが異なると攻撃者にRSA復号のエラーか AES復号のエラーか判別する材料を与え、パディングオラクル攻撃の きっかけになる NG例: io.ReadFullではなくio.Readを利用してしまう io.Readは指定バイト数分を読み切る前に返ってしまう。
  29. © 2026 ANDPAD All Rights Reserved. 共通鍵暗号・ブロック暗号 • crypto/aes •

    crypto/cipher • ChaCha20Poly1305 公開鍵暗号・デジタル署名・鍵交換 • crypto/des : 3DES暗号 脆弱な暗号 使っちゃダメ • crypto/dsa : 昔のデジタル署名アルゴリズム 非推奨なので使わん方が良い • crypto/rsa : 昔から使われている暗号化、デジタル署名 • crypto/ecdsa, crypto/ed25519 : 楕円曲線暗号を利用したデジタル署名 • crypto/ecdh : 楕円曲線暗号を利用した鍵交換プロトコル • crypto/mlkem : ポスト量子暗号鍵カプセル化メカニズム、新しすぎるので単体では使わん方がよい ハッシュ関数 • crypto/md5 : 高速だが脆弱なハッシュ関数 暗号では使っちゃダメ • crypto/sha256, crypto/sha512, crypto/sha3 : ファイルの改ざん検知や署名の為のハッシュ関数 • crypto/hmac : APIリクエストの改ざん防止の為のメッセージ認証コード Go 1.26以前のハイブリッド暗号
  30. © 2026 ANDPAD All Rights Reserved. ECIES (サードパーティ製暗号スキーム ) HPKEの元となったもの。

    公開鍵暗号(ECC)、鍵導出関数(KDF)、共通鍵暗号(AES)、メッセージ認証(HMAC)を組み合わせたハイブリット 暗号。 「公開鍵暗号にECCを使うためRSAより短い鍵で高い強度」 「メッセージ自体は計算量の少ない AESなどを利用するため早い」 ただし、自由度が高く規格が統一されていなかったため実装者毎に方言が一杯あって普及しなかった。 Go 1.26以前のECCハイブリッド暗号
  31. © 2026 ANDPAD All Rights Reserved. Go 1.26 ハイブリッド公開鍵暗号 crypto/hpke

    (RFC 9180) crypto/aes, crypto/mlkem, crypto/rsa, crypto/cipher, crypto/sha512 が シリンダー錠なら crypto/hpke はそれらを組み合わせる玄関ドアユニット 簡単に言えば crypto/hpke は他の暗号鍵 crypto/xxx パッケージの組み合わせを全て内包した概念 暗号業界の苦悩と失敗の歴史 から生まれた 暗号パッケージの集大成 (ここで壮大な BGMが流れる )
  32. © 2026 ANDPAD All Rights Reserved. Go 1.26 ハイブリッド公開鍵暗号 crypto/hpke

    (RFC 9180) hpke.KEM (Key Encapsulation Mechanism) ハイブリッド公開鍵暗号における「鍵カプセル化」インターフェース 暗号文の送信者は受信者の「公開鍵」で暗号化に使用する 「共有シークレット」 と 受信者が共有シークレットを復元するために必要な 「カプセル化鍵」 を生成
  33. © 2026 ANDPAD All Rights Reserved. Go 1.26 ハイブリッド公開鍵暗号 crypto/hpke

    (RFC 9180) hpke.KDF (Key Derivation Function) KEMで生成された「共有シークレット」と、付加情報( info)を入力し AEADで使用するための「暗号鍵」 や「Nonce」を導出する関数 Nonce (number used once) 署名毎にUniqueなNumberを利用する為の実装。 Uniqueにしておかないと計算で暗号が解読出来ちゃう。 以下にNonceの実装バグにまつわる有名なインシデント事例を紹介。 • PS3では、実装ミス により使いまわしてはいけない Nonceを固定値にしていたため、数学的に計算不可能 なはずのECDSA秘密鍵が逆算され、違法な CFWが出回る事態になりました。 https://en.wikipedia.org/wiki/PlayStation_3_homebrew • Wi-FiのWEPで利用されているInitialization Vector(Nonce)は24bitしかない ため、ARPリプレイ攻撃などを 利用し大量の通信を行うことで 偶然同じになった IVを収集し数分で暗号鍵を解読出来てしまう。 https://www.gate02.ne.jp/lab/security-article/wifi-security-introduction-wep-weakness-attack/ • Android Bitcoin Wallet 盗難事件 。Android JavaのSecureRandom classの実装バグにより、乱数生成 器が適切に初期化されず、 複数の異なる取引で 同じNonceが利用されBitcoinの盗難に繋がった事件 https://android-developers.googleblog.com/2013/08/some-securerandom-thoughts.html
  34. © 2026 ANDPAD All Rights Reserved. Go 1.26 ハイブリッド公開鍵暗号 crypto/hpke

    (RFC 9180) hpke.AEAD (Authenticated Encryption with Associated Data) KDFで導出された暗号鍵と Nonceと付加情報(aad)を使用して、メッセージを暗号化 するアルゴリズム 暗号化と同時にメッセージの「改ざん検知」も行うことができる
  35. © 2026 ANDPAD All Rights Reserved. Go 1.26 ハイブリッド公開鍵暗号 crypto/hpke

    (RFC 9180) 受信者(Recipient) 送信者(Sender) hpke.KEM GenerateKey() hpke.PrivateKey hpke.PublicKey hpke.PublicKey hpke.KDF hpke.PublicKey encap() hpke.NewSender カプセル化 鍵 Shared Secret 共通 Info hpke.Sender#Seal Key & Nonce hpke.AEAD カプセル化 鍵 平文 暗号文 hpke.NewRecipient hpke.PrivateKey decap() Shared Secret 共通 Info hpke.KDF Key & Nonce hpke.Recipient#Open hpke.AEAD 暗号文 平文 ここから開 始 共通 aad 共通 aad 事前定義 もしくは秘密情報で ないので送信者から メタデータとして送付 しても良い 事前定義 もしくは秘密情報で ないので送信者から メタデータとして送付 しても良い
  36. © 2026 ANDPAD All Rights Reserved. Go 1.26 ハイブリッド暗号スイート crypto/hpke

    (RFC 9180) hpke.PrivateKey算出の例 - MLKEM768-X25519(X-Wing)をハイブリット暗号として利用する場合 crypto.ecdh とか crypto.mlkem package は使う必要がなく crypto.hpkeだけで完結する 1: import ( 2: "crypto/ecdh" 3: "crypto/hpke" 4: "crypto/mlkem" 5: "crypto/rand" 6: ) 7: 8: // 古典的な楕円曲線暗号 (X25519) の鍵生成 9: // Go 1.26 では、GenerateKey の引数 reader は無視され 10: // 安全な乱数生成器 (FIPS 140 DRBG) が使用されます。 11: ecdhPriv, err := ecdh.X25519().GenerateKey(rand.Reader) 12: 13: // 耐量子暗号 (ML-KEM-768) の鍵生成 14: mlkemPriv, err := mlkem.GenerateKey768() 15: 16: // ハイブリッド秘密鍵の結合 17: privKey, err := hpke.NewHybridPrivateKey(mlkemPriv, ecdhPriv) 18: 19: // ハイブリッド公開鍵の取得 20: // PrivateKey インターフェースには PublicKey() メソッドがある 21: pubKey := privKey.PublicKey() 1. import ( 2. "crypto/hpke" 3. ) 4. 5. // KEMを作成 6. // MLKEM768-X25519 (X-Wing)の実装 7. privKey, err = hpke.MLKEM768X25519().GenerateKey() 8. 9. // ハイブリッド公開鍵の取得 10. // PrivateKey インターフェースには PublicKey() メソッドがある 11. pubKey := privKey.PublicKey() https://go.dev/play/p/sURFwC7zvC_l?v=gotip 次の暗号方式が利用可能 DHKEM MLKEM1024, MLKEM1024P384 MLKEM768P256, MLKEM768X25519
  37. © 2026 ANDPAD All Rights Reserved. Go 1.26 ハイブリッド暗号スイート crypto/hpke

    (RFC 9180) 送信者(Sender) が暗号送信する例 // KDF: Key Derivation Function (鍵導出関数) kdf := hpke.HKDFSHA512() // AEAD: Authenticated Encryption with Associated Data (認証付き暗号) // KDFで作られた共通鍵を使って、実際のメッセージを暗号化するアルゴリズム aead := hpke.AES256GCM() // Info: Application Context Information (アプリケーション固有の情報 ) // 鍵を特定の用途やプロトコルに「紐付ける」ための任意のバイト列です。 // 送信側と受信側で完全に一致していないと、正しい鍵が生成されず復号に失敗します。 // 用途:「これは決済用の鍵」「これはログイン用の鍵」と区別し、使い回し攻撃を防ぐ。 info := []byte("Go 1.26 HPKE!") // Senderの作成 // enc は受信者に送る必要がある「カプセル化鍵」 enc, sender, err := hpke.NewSender(pubKey, kdf, aead, info) // 暗号文の作成 plaintext := []byte("Hello, Quantum-Resistant Future!") aad := []byte("Additional Authenticated Data to Tom") ciphertext, err := sender.Seal(aad, plaintext) https://go.dev/play/p/sURFwC7zvC_l?v=gotip 次の関数が利用可能 HKDFSHA256,HKDFSHA384, HKDFSHA512, SHAKE128, SHAKE256 次の暗号方式が利用可能 AES128GCM, AES256GCM, ChaCha20Poly1305
  38. © 2026 ANDPAD All Rights Reserved. Go 1.26 ハイブリッド暗号スイート crypto/hpke

    (RFC 9180) 受信者(Recipient) が暗号文を復号する例 // Recipient コンテキストの作成 // 送信者(Sender) から受け取った enc (カプセル鍵) と自分の秘密鍵を使って「共通鍵」を導出 // ※ 重要: 送信者(Sender) と同じ kdf, aead, info を指定する必要があります。 kdf := hpke.SHAKE256() aead := hpke.ChaCha20Poly1305() info := []byte("Go 1.26 HPKE!") recipient, err := hpke.NewRecipient(enc, privKey, kdf, aead, info) // メッセージの復号 (Open) aad := []byte("Additional Authenticated Data to Tom") decrypted, err := recipient.Open(aad, ciphertext) https://go.dev/play/p/sURFwC7zvC_l?v=gotip
  39. © 2026 ANDPAD All Rights Reserved. Go 1.26 ハイブリッド暗号スイート crypto/hpke

    (RFC 9180) 複雑さの隠蔽と標準化 KEM (鍵カプセル化メカニズム )、KDF (鍵誘導関数)、AEAD (認証付き暗号) これらを個別に選ぶのではなく暗号スイートとして定義することで、 「Nonceの導出漏れ」 や「弱いアルゴリズム の組み合わせ」を選択してしまうリスクを排除 署名機能のネイティブ統合 従来の暗号化では「誰が送ったか」を保証するために別途署名が必要 HPKEは標準で署名の機能も統合 コンテキストの分離 リプライ攻撃やクロスコンテキスト攻撃を防ぐために鍵の使いまわしを設計で防ぐ必要がある HPKE は info や aad により、同じ鍵ペアを使っていたとしても、アプリケーションやコンテキストが異なれば、生 成される暗号文が論理的に分離される
  40. © 2026 ANDPAD All Rights Reserved. Go 1.26 Cryptographic Randomness

    // crypto/ed25519 publicKey, privateKey, err := ed25519.GenerateKey(rand.Reader) // crypto/rsa privateKey, err := rsa.GenerateKey(rand.Reader, 2048) // crypto/ecdh privateKey, err := ecdh.X25519().GenerateKey(rand.Reader) // crypto/ecdsa privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) // crypto/dsa params := new(dsa.Parameters) err := dsa.GenerateParameters(params, rand.Reader, dsa.L2048N256) dsaKey := new(dsa.PrivateKey) dsaKey.Parameters = *params err := dsa.GenerateKey(dsaKey, rand.Reader) https://go.dev/doc/go1.26#cryptopkgcrypto // crypto/ed25519 publicKey, privateKey, err := ed25519.GenerateKey(nil) // crypto/rsa privateKey, err = rsa.GenerateKey(nil, 2048) // crypto/ecdh privateKey, err := ecdh.X25519().GenerateKey(nil) // crypto/ecdsa privateKey, err := ecdsa.GenerateKey(elliptic.P256(), nil) // crypto/dsa params := new(dsa.Parameters) err := dsa.GenerateParameters(params, rand.Reader, dsa.L2048N256) dsaKey := new(dsa.PrivateKey) dsaKey.Parameters = *params err := dsa.GenerateKey(dsaKey, nil) 全ての暗号パッケージの GenerateKeyのrandom引数が無視され 、強制的に安全なソース (crypto/rand#Reader)を適用するようになりました
  41. © 2026 ANDPAD All Rights Reserved. Go 1.26 Cryptographic Randomness

    // crypto/dsa err := dsa.GenerateKey(dsaKey, rand.Reader) messageHashed := sha256.Sum256([]byte("Hello, DSA!")) r, s, err := dsa.Sign(rand.Reader, dsaKey, messageHashed[:]) https://cs.opensource.google/go/go/+/master:src/crypto/dsa/dsa.go;l=223 全ての暗号パッケージの GenerateKeyのrandom引数が無視され 、強制的に安全なソースを適用するようにな りました。dsa.GenerateKeyではなく dsa.Signでのみrandom引数が無視されます。 恐らくリリースノートの記 載ミスでしょう。 DSA自体がDeprecatedなのでクリティカルではないですけどね。 // crypto/dsa err := dsa.GenerateKey(dsaKey, rand.Reader) messageHashed := sha256.Sum256([]byte("Hello, DSA!")) r, s, err := dsa.Sign(nil, dsaKey, messageHashed[:]) https://cs.opensource.google/go/go/+/master:src/crypto/dsa/dsa.go;l=177
  42. © 2026 ANDPAD All Rights Reserved. Go 1.26 testing/cryptotest https://cs.opensource.google/go/go/+/refs/tags/go1.26.0:src/testing/cryptotest/rand.go;l=45

    暗号パッケージのGenerateKeyのrandom引数が無視されると テストで困る ので テスト利用する Seedを固定するための testing/cryptotest が追加 cryptotest.SetGlobalRandom(t, seed) で seed を指定出来ます。
  43. © 2026 ANDPAD All Rights Reserved. Go 1.26 RSA PKCS#1

    v1.5暗号の非推奨化 と RSA-OAEP移行 初期のSSL/TLSで標準だったRSA PKCS#1 v1.5暗号の問題 RSA暗号そのものは決定論的な定義であり、そのまま利用しては同じ平分では必ず同じ暗号文になるため暗号 文のランダム性を保証出来ません。 これを防ぐために実用的な RSA暗号ではパティングをして平分にランダム性を保証しようとしています。 RSA PKCS#1 v1.5 では このパディングの構造でデータの先頭に 00 02 というバイト列を配置するルールがあり ます。 サーバーは RSA PKCS#1 v1.5 を利用した暗号文の復号時に先頭が 00 02 で始まらない場合は「不正」として 拒絶されます。この拒絶の挙動がパディングオラクル攻撃に利用されました。 Go 1.26 での RSA-OAEPへの移行 Go 1.26以降では RSA-OAEP (RFC 8017 PKCS#1 v2.2) の利用が強く推奨されています。 https://go.dev/doc/go1.26#cryptorsapkgcryptorsa OAEP(Optimal Asymmetric Encryption Padding)は、ハッシュ関数とマスク生成関数を用いた Feistelネットワー ク構造を取り入れ、パディング検証に失敗した場合でも復号プロセス全体がランダムな出力となるように設計さ れており、部分的な情報漏洩を防ぐ構造を持っています。 https://ja.wikipedia.org/wiki/Optimal_Asymmetric_Encryption_Padding
  44. © 2026 ANDPAD All Rights Reserved. まとめ • Goはマッチョな専門家により世界最強レベルのセキュ リティが担保されている

    • Goの哲学は米国CISAのSecure by Designにも活か されている • HPKEはGoの哲学の延長線上にある • 先人達が用意した安全なレールの上でセキュアなシス テムを作っていきましょう
  45. © 2026 ANDPAD All Rights Reserved. Go 1.20,1.24 rand.Seedをユーザーに設定させない設計 Go

    1.20 未満では math/rand のSeedのDefault値は "1" で固定されており、安全な疑似乱数を生成するために は rand.Seed() を利用者が明示的に指定する必要がありました // NG: time.Now().UnixNano() を利用する例 // Seedが予測可能、かつ重複の可能性がある rand.Seed(time.Now().UnixNano()) // NG: UNIXの /dev/urandom を利用する例 // 読み取りタイミングによってデバイスやコンテナ内のエントロピー不足により同値になる可能性がある // Mining Your Ps and Qs: https://www.usenix.org/system/files/conference/usenixsecurity12/sec12-final228.pdf f, err := os.Open("/dev/urandom") var seed int64 err = binary.Read(f, binary.LittleEndian, &seed) rand.Seed(seed) // OK: crypto/rand#Reader を利用する例 これなら安全だが math/rand を誤って利用するケースがよく発生していた import “crypto/rand” var seed int64 err = binary.Read(rand.Reader, binary.LittleEndian, &seed) rand.Seed(seed) https://cs.opensource.google/go/go/+/refs/tags/go1.20:src/math/rand/rand.go;l=318-324;bpv=0
  46. © 2026 ANDPAD All Rights Reserved. Go 1.20,1.24 rand.Seedをユーザーに設定させない設計 Go

    1.20 では math/rand の Seed function が deprecated になり Seedはfastrand64(runtime.rand)により安全に決まるように変更 Go 1.24 で廃止されました (利用したい場合はGODEBUG=randseednop=0の指定が必須化) https://cs.opensource.google/go/go/+/refs/tags/go1.20:src/math/rand/rand.go;l=318-324;bpv=0 https://cs.opensource.google/go/go/+/refs/tags/go1.24.0:src/math/rand/rand.go;l=398-402;bpv=0 https://cs.opensource.google/go/go/+/refs/tags/go1.20:src/math/rand/rand.go;l=413-426
  47. © 2026 ANDPAD All Rights Reserved. Go 1.22 math.rand のデフォルト乱数生成器がChaCha8に変更

    math/randのデフォルト乱数生成器が 数学的に次の値が予測可能な Lagged Fibonacci の一種を利用した乱数生成から、ストリーム暗号 の ChaCha8 に変更 開発者が誤ってcrypto/rand ではなく math/rand を 使ってしまっても、十分安全な乱数を利用するよう になった とはいえ、安全な乱数生成を利用したい場合は今 まで通りcrypto/rand を利用するべき https://cs.opensource.google/go/go/+/refs/tags/go1.22.0:src/math/rand/rand.go;l=349-369 https://cs.opensource.google/go/go/+/refs/tags/go1.22.0:src/runtime/rand.go;l=127
  48. © 2026 ANDPAD All Rights Reserved. Go 1.20,1.21 crypto/ecdhの追加 と

    crypto/elliptic の実質廃止 crypto/elliptic パッケージは、楕円曲線上の座標( x, y)を直接扱う低レイヤーなインターフェースです。 専門知識のないエンジニアが利用すると脆弱性を埋め込みやすいインターフェースになっていました。 そこで、高レイヤーで抽象化したインターフェースとして crypto/ecdh が実装されました。 crypto/ecdh の内部実装は暗号専門家である Goセキュリティチームにより最適化され、サイドチャネル攻撃へ の耐性がデフォルトで備わっています。 https://go.dev/doc/go1.20#crypto_ecdh https://go.dev/doc/go1.21#cryptoellipticpkgcryptoelliptic
  49. © 2026 ANDPAD All Rights Reserved. crypto/ellipticの実装ミスにより発生する代表的な脆弱性 Invalid Curve Attack(無効曲線攻撃)

    「受け取った公開鍵が、本当にその楕円曲線の方程式を満たす (楕円曲線上に存在する )か」のチェックを省略 してしまった。 Small Subgroup Attack(小位数部分群攻撃) 「楕円曲線暗号の点が無限遠点になっていないか」の確認を忘れた。 curve := elliptic.P256() // 計算前に点が曲線上にあるか検証を忘れると Invalid Curve Attackの脆弱性あり if !curve.IsOnCurve(pubX, pubY) { return nil, nil, fmt.Errorf("invalid public key: point not on curve") } x, y := curve.ScalarMult(pubX, pubY, privKey) x, y := curve.ScalarMult(pubX, pubY, privKey) // 結果が無限遠点(0,0)になっていないか確認していないと Small Subgroup Attack の脆弱性あり if x.Sign() == 0 && y.Sign() == 0 { return nil, errors.New("shared secret is identity element") }
  50. © 2026 ANDPAD All Rights Reserved. Go 1.24 crypto/rsa 1024bit

    key の廃止 Go 1.24 では crypto/rsa で 1024bit未満の鍵を利用しようとするとエラーを返すようになりました。 1024bitのRSA鍵はAESで80bit相当の強度しかない 2030年まで安全とされる暗号強度の最低ラインは「 AES 112bit相当(RSA 2048bit)」 https://cs.opensource.google/go/go/+/refs/tags/go1.24.0:src/crypto/rsa/rsa.go;l=246-259;bpv=0
  51. © 2026 ANDPAD All Rights Reserved. Go 1.25 crypto#SignMessage の実装

    従来の crypto#Sign で渡すのはハッシュ化済みデータ (digest) のみ ハッシュアルゴリズムの選択は呼び出し側に委ねられています。 例えば、ECDSA署名に対して脆弱なハッシュ関数を組み合わせてしまうといった、組み合わせのミスが発生し得 ます。 https://cs.opensource.google/go/go/+/refs/tags/go1.25.0:src/crypto/crypto.go;l=198;bpv=0 crypto#SignMessage は、生のメッセージを直接受け取ります。 署名者が署名プロセスにおいて「今、何を、どのアルゴリズムでハッシュ化しているか」を完全にコントロールで き、その署名鍵に最適なハッシュ処理と署名処理を選択できます。 https://cs.opensource.google/go/go/+/refs/tags/go1.25.0:src/crypto/crypto.go;l=215;bpv=0
  52. © 2026 ANDPAD All Rights Reserved. Go 1.24 ポスト量子暗号 crypto/mlkem

    ポスト量子暗号とは今後実用的な量子コンピュータが登場しても暗号解読され得ない、次世代の暗号技術の事 を指します。 実用的な量子コンピュータの登場には後 10〜30年かかると言われていますが 2013年にスノーデン氏が告発した NSAによるUpstream収集(PRISM)などにより 「Harvest Now, Decrypt Later(今盗んで、後で解読する)」 という手法が既に行われていることが分かっています。 Go 1.24 では ポスト量子暗号 crypto/mlkem (NIST FIPS 203) が実装されました。 Go 1.25 までは他のcrypto package同様あくまでユーザーが選択可能な暗号方式の 1つというポジション。 ドアがない状態でシリンダー錠だけあるようなものです、これだけあっても使いづらい。 https://cs.opensource.google/go/go/+/refs/tags/go1.24.0:src/crypto/mlkem/mlkem.go;bpv=0