HEADLINE

HEADLINE


Cognito SRP認証を理解する(Secure Remote Passwordとは?)

SRP完全図解

AWS Cognitoには SRP(Secure Remote Password) という認証方式があります。
これはパスワードをサーバーに送信せずにログインを証明する仕組みです。

SRP認証とは

SRP(Secure Remote Password)は、Zero Knowledge Proof(ゼロ知識証明)を利用した認証プロトコルです。

通常のログインでは次のような通信が行われます

Client → Server
username + password

この場合、通信が盗聴されるとパスワードが漏洩するリスクがあります

SRPでは

Client → Server
username + 証明データ

パスワード自体は一切送信されません。

① ユーザー登録

ユーザー登録時、パスワードはそのまま保存されません

x = H(salt | password)

v = g^x mod N

保存パスワードはサーバーに保存されません。

② ログイン開始

クライアントはランダム値を生成

a = random
A = g^a mod N

Cognitoへ送信の場合パスワードは含まれない

③ サーバー応答

サーバーはランダム値を生成

b = random
B = kv + g^b mod N

クライアントへ送信

④ 共通セッションキー生成

クライアント

x = H(salt | password)
u = H(A | B)

S = (B - kg^x)^(a + ux) mod N
K = H(S)

サーバー

u = H(A | B)

S = (A * v^u)^b mod N
K = H(S)

結果として、同じセッションキーKが生成されます。

⑤ 認証証明

クライアントは証明を送信

M1 = H(A | B | K)

サーバーが確認後、問題なければログイン成功

さらにサーバーも証明

M2 = H(A | M1 | K)

SRPが安全な理由

  • パスワード送信不要
  • ゼロ知識証明
  • リプレイ攻撃防止
  • パスワード漏洩リスク低減
  • OAuthとの相性

Cognito SRPのAPIフロー

Cognitoでは以下のAPIでSRP認証が行われます。

InitiateAuth
AuthFlow = USER_SRP_AUTH

レスポンス

ChallengeName = PASSWORD_VERIFIER

その後

RespondToAuthChallenge

で認証が完了します。

無音ガメラ Web版 Jsree スクショ

Next.js + react-pdfを利用 iPhoneでPDF1ページしか表示されない解決方法

react-pdf 実装

iPhone Safari での PDF 全ページ表示問題を解決するため、<iframe> を使った PDF 表示を廃止し、react-pdf を用いた全ページレンダリングに切り替えた。 iframe では、 iOS Safari において PDF が1ページ目しか表示されなかった。

使用パッケージとバージョン

パッケージバージョン備考
react-pdf^10.4.1Document / Page コンポーネント提供
pdfjs-dist^5.4.296react-pdf が内部で使うバージョンに合わせる(重要)

インストール

pnpm install react-pdf pdfjs-dist@5.4.296

pdfjs-dist のバージョンは必ず react-pdf が要求するものに揃えること。 バージョンが異なると後述のバージョン不一致エラーが発生する。

遭遇したエラーと解決

エラー 1: DOMMatrix is not defined(SSRエラー)

エラー内容:
const SCALE_MATRIX = new DOMMatrix();
digest: ‘534975899’

原因: pdfjs-dist のモジュール初期化時に DOMMatrix(ブラウザ専用API)を使用しているため、 Next.js の SSR フェーズ(Node.js 環境)でクラッシュする。
'use client' を付けてもモジュールの初期化はサーバーで走るため回避できない。

解決策: react-pdf を使うコンポーネントを別ファイル(PdfViewer.tsx)に分離し、next/dynamic の ssr: false でクライアントのみ読み込む。

// IntroMediaOverlay.tsx
import dynamic from 'next/dynamic';

const PdfViewer = dynamic(
  () => import('@/components/PdfViewer'),
  { ssr: false }
);

エラー 2: API version does not match Worker version

エラー内容:
UnknownErrorException: The API version "5.4.296" does not match the Worker version "5.5.207".

原因: package.json に直接インストールされた pdfjs-dist が 5.5.207 だったのに対し、react-pdf 内部が使う pdfjs-dist は 5.4.296 だった。 Worker ファイルの解決に 5.5.207、API には 5.4.296 が使われバージョン不一致になった。

解決策: pdfjs-dist を react-pdf が要求するバージョンに固定する。

pnpm install pdfjs-dist@5.4.296

確認方法:

cat node_modules/react-pdf/package.json | grep pdfjs-dist
# → "pdfjs-dist": "5.4.296"

実装コード

PdfViewer.tsx(react-pdf 本体)

// src/components/PdfViewer.tsx
'use client';

import { useRef, useState, useCallback } from 'react';
import { Document, Page, pdfjs } from 'react-pdf';
import 'react-pdf/dist/Page/AnnotationLayer.css';
import 'react-pdf/dist/Page/TextLayer.css';

pdfjs.GlobalWorkerOptions.workerSrc = new URL(
  'pdfjs-dist/build/pdf.worker.min.mjs',
  import.meta.url,
).toString();

export default function PdfViewer({ url }: { url: string }) {
  const [numPages, setNumPages] = useState<number>(0);
  const containerRef = useRef<HTMLDivElement>(null);
  const [containerWidth, setContainerWidth] = useState<number>(600);

  const onDocumentLoadSuccess = useCallback(
    ({ numPages }: { numPages: number }) => {
      setNumPages(numPages);
      if (containerRef.current) {
        setContainerWidth(containerRef.current.clientWidth);
      }
    },
    []
  );

  return (
    <div ref={containerRef} className="overflow-y-auto max-h-[60vh] p-2">
      <Document
        file={url}
        onLoadSuccess={onDocumentLoadSuccess}
        loading={<span>PDF読み込み中...</span>}
      >
        {Array.from({ length: numPages }, (_, i) => (
          <Page
            key={i}
            pageNumber={i + 1}
            width={containerWidth - 16}
            className="mb-2"
          />
        ))}
      </Document>
    </div>
  );
}
Win版 Jsree スクショ 無音ガメラ Web版

【digでTXTレコードを確認する方法】DNS設定後に反映確認

digでTXTレコードを確認

DNSにTXTレコード(Google認証やSPFなど)を追加したのに、
「ちゃんと設定できているか分からない…」ということはありませんか?

dig コマンドを使ってTXTレコードを確認する方法まとめ


TXTレコードとは?

TXTレコードは、ドメインに任意のテキスト情報を登録できるDNSレコードです。

主に次の用途で使われます:

  • Google Search Console のサイト所有権確認
  • SPF(送信ドメイン認証)
  • DKIM / DMARC設定
  • AWS / HubSpot / 各種サービス認証

digでTXTレコードを確認する方法

基本コマンド

dig example.com TXT

シンプル表示する場合

dig example.com TXT +short

成功すると、以下のように表示されます。

"google-site-verification=xxxxxxxxxxxx"
"v=spf1 include:_spf.google.com include:amazonses.com ~all"

TXTレコードが複数あっても問題ない?

はい、問題ありません。

1つのドメインに複数のTXTレコードを持つのは通常の構成です。

例:

re-tool.co.jp TXT "google-site-verification=..."
re-tool.co.jp TXT "v=spf1 include:_spf.google.com ..."

ただし注意

⚠ SPF(v=spf1)は1つだけにまとめる必要があります。

複数のSPFレコードがあるとメールが正常に送信できなくなる可能性があります。


TXTレコードが表示されないときのチェックポイント

1. ネームサーバーが正しいか確認

dig example.com NS +short

2. DNS反映待ちの可能性

DNSは反映に数分〜最大48時間かかることがあります。

Google DNSで確認:

dig example.com TXT @8.8.8.8 +short

Windowsで確認する方法

PowerShellを使う場合:

Resolve-DnsName example.com -Type TXT
Resolve-DnsName example.com -Type TXT -Server 8.8.8.8

whisper.cpp を Visual Studio 2022 でビルドする方法