メインコンテンツまでスキップ

利用者証明用電子証明書の有効性確認

このページでは、Verify SDK を使用して取得した利用者証明用電子証明書を使って、有効性確認を行う方法を説明します。

Verify API は、与えられた証明書の失効確認を行う機能のみを提供します。 有効性確認は、さらに、その証明書が有効期限内であることを確認する必要があります。 取得した証明書の有効期限は Verify API から返却されるため、バックエンドで取得した時刻が有効期限内かの確認を行います。 これらの確認で失効しておらず期限内であった場合に、取得した証明書が有効であると判断されます。

あらかじめAPI の利用開始を完了し、API トークンを取得しておいてください。

注意

テナントを作成した段階では、 かざし利用に関係する API は無効化されているため利用できません。

利用するにはお問い合わせください。

利用者の識別

次のステップで行う内部認証では、暗証番号として利用者の生年月日が必要です。 利用者証明用電子証明書の失効確認だけでは利用者の生年月日は取得できないため、内部認証を行うことができません。

利用者証明用電子証明書の失効確認時に利用者の識別を行い、利用者 ID を取得します。 内部認証の実行時に利用者 ID に紐づいた生年月日を取得することで、暗証番号を入力できます。

シーケンス

アプリとバックエンドの連携

Verify SDK を用いて取得した証明書は、何らかの方法でバックエンドサーバーに共有して有効性確認を行ってください。

以下の実装例では、アプリとバックエンドの間での連携については省略しています。 実際のアプリケーションの実装例については、サンプルアプリをご覧ください。

要確認

Verify API の利用は、必ず SP 事業者で管理するサーバを経由して行ってください。 API トークンをアプリケーションに含めて配布することは、Verify API の不正利用ひいては JPKI への不正なアクセスにつながるため、絶対に行わないでください

実装例

クライアントライブラリのセットアップ方法は、クライアントライブラリをご参照ください。

package main

import (
"context"
"crypto/sha256"
"encoding/base64"
"fmt"
"log"
"net/http"

"buf.build/gen/go/pocketsign/apis/connectrpc/go/pocketsign/verify/v2/verifyv2connect"
verifyv2 "buf.build/gen/go/pocketsign/apis/protocolbuffers/go/pocketsign/verify/v2"
"connectrpc.com/connect"
)

var (
// APIエンドポイントを指定します。この値は環境によって異なります。
baseUrl = "https://verify.mock.p8n.app"

// Verify APIのトークンです。ご自身のトークンに置き換えてください。
token = "<YOUR_API_TOKEN>"

// Verify SDKによってJPKI APから読み出された利用者証明用電子証明書です。これらの値は、アプリ上で作成したものを何らかの方法で予め受け取っておいてください。
rawCertificate = "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"
)

func run() error {
// Base64をデコードしてバイト列にします。
certificate, err := base64.StdEncoding.DecodeString(rawCertificate)
if err != nil {
return err
}

// 署名検証リクエストを作成します。
request := connect.NewRequest(&verifyv2.CheckCertificateStatusByContentRequest{
Certificate: certificate,
// 利用者の識別を行うためにtrueにします。
IdentifyUser: proto.Bool(true),
})

// リクエストにAPIトークンを設定します。
request.Header().Set("Authorization", "Bearer "+token)

// APIクライアントを作成します。
client := verifyv2connect.NewCertificateServiceClient(http.DefaultClient, baseUrl)

// 署名検証リクエストを送信します。
response, err := client.CheckCertificateStatusByContent(context.Background(), request)
if err != nil {
return err
}

// 有効な証明書は、以下の条件を両方満たす場合です。
// - 取得した証明書が有効である
isGood := response.Msg.CertificateStatus.Status == verifyv2.CertificateStatus_STATUS_GOOD
// - 取得した証明書が有効期限内である
validity := response.Msg.CertificateContent.Validity
now := time.Now()
isValidPeriod := now.After(validity.NotBefore.AsTime()) && now.Before(validity.NotAfter.AsTime())
// 証明書が有効かどうか
isValidCert := isGood && isValidPeriod

// 結果を表示します。
fmt.Printf("UserID: %s\n", response.Msg.User.Id)
fmt.Printf("Validity: %t\n", isValidCert)
return nil
}

func main() {
if err := run(); err != nil {
log.Fatalln(err)
}
}

リクエストに成功すると、以下のように結果が表示されます。

UserID: 1e5d5d27-d225-4824-bf36-dbc663973051
Validity: true
要確認

SP 事業者は、証明書の生データの保持が禁じられています。 データの保存について十分ご注意いただき、Verify API に送信後は速やかに削除するようにご実装ください。


次のステップ

券面事項確認 AP を使用して、内部認証データの作成を行いましょう。

その他、API の詳しい使い方やエラーの詳細等については、API リファレンスをご覧ください。