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

マイナンバー画像の検証

このページでは、PocketSign Verify API を使用して券面事項確認 AP から取得した公開鍵・署名値・マイナンバー画像のデータを用いて、 マイナンバー画像のパース・検証を行う方法を説明します。

あらかじめAPI の利用開始を完了し、API トークンを取得しておいてください。 また、利用の前に券面事項系 API の利用についてお問い合わせください。

シーケンス

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

Verify SDK を用いて取得した公開鍵・署名値・マイナンバー画像などの情報は、 何らかの方法でバックエンドサーバーに共有してデータのパース・検証を行ってください。

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

要確認

Verify API の利用は、必ず バックエンドサーバーを経由して行ってください。 API トークンをアプリケーションに含めて配布することは Verify API の不正利用につながるため、絶対に行わないでください

実装例

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

package main

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

"buf.build/gen/go/pocketsign/apis/connectrpc/go/pocketsign/cardinfo/v1/cardinfov1connect"
cardinfov1 "buf.build/gen/go/pocketsign/apis/protocolbuffers/go/pocketsign/cardinfo/v1"
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>"

// チャレンジとして送信したNonceです。
nonce = []byte{0xCA, 0xFE, 0xBA, 0xBE}

// Verify SDKによって券面事項確認APから読み出されたデータです。これらの値は、アプリ上で作成したものを何らかの方法で予め受け取っておいてください。
rawVerificationPublicKey = "fyGCAjNfToIBKTEwMDAwMDEIBTAwMQAAAAAyODgyMzUyCAUwMDEAAAAAkAMBAAGRggEAmfy3KTSqU9QSwA05TehkOph/DhxrfPMd3opwsfjoHulVXtEsgFG8J+har+/dI2Pb165pQia7OhJiYHrdzgPq0A3eGx50rOhzTTV+weQZ1XOLzprsB6BN9oaI1kG3BFrl6WLZbbUs73DiljJPbshcJK4rka4RwW9BP6Ohp483Tt/KGK8VkZfGxtJsb2HbHluJUtSeR0Tp2zm/f9OUi35Oj68npEOuRzWssvsJNuaS7bq5calMsx24ed7WaQ5/H/s5r+scibFALGhBpzed5gi3GQAP8Drse7KIGCpr/BxX5k7Qtx2y9TBSTwGVoQbEpFvf2QLPI1Dcod259KhXE3lHJV83ggEAK2KsvW3L/1WQBQdnIcWXF6bTOrlaZdyereK+ySbvM0xJWCKnTqvfsJJTM6a6LAkDsyXwxaKSe1FKGnUhzo1sUyeKs0wE+GTaA4tNUm98m6gN1Ca/uLN7BFRc5G8WJ5Cs/wz9OkY9lAY0FrBaUfsQuZedKn/1TG6eClJRlxUwvh8LXzf+xjH6Ao0vmBJR1f9OYmlra/lgF1UQqgybcJHvg/7iXOAFHOEQGavF5J7GO/BxIaLVEwzT9mykCGqwArvddn6e0mX6aX0yUwZuMXonGXD8MzN4uU1pco6biZdoR++O/8eWK/+KJFqNUglAO61DCgvNdOHXN/tKdO8QtdzHUg=="
rawAuthenticationSignaure = "SPzVptSYxa56R2nyMldup21y/RBuJj7GjwTxRMkY2O19NKysI4NaV1RRmXpbsTL0SBVucFvkUKs8xL5At92WKsfY92nDSeJkCMBHAa9lcep8NEdEBNNb9yOe2wWHSkJ3NoudgFC9Bp7e9vmOmpAsSIEkJzciBTfnkmGvnu4wdshAqEXIbteQrbm7s5OyKJLZxlWZIBP9Il/G/RFOYw45Q299t5hjjIanCJCBx9eNuuZk+n8y8pQJNZFnt6y46NDC2R+qTkV/2bssiwr0s3hEMytbu6GE8xq0m8bChA218mp5d4aZn/E9uCJbZUJbejCvUhNzWbxZJ5+ROvLf7B1GdA=="
rawMyNumberContent = "/0CCArPfQYIAm4lQTkcNChoKAAAADUlIRFIAAABIAAAADAEAAAAA6V/GkAAAAGJJREFUCNdj+A8DDOcrHr+xOdhn851hS3ns2d9/S2+7M2wvrz37/Xfp7XKG7fXFawx+94JYdX/XXq8ukwayav/mXy8vB4lV32WHssrvvgWydpcznC9Ifmfxva/mOwPCDjgLAMuUTfqjspQyAAAAAElFTkSuQmCC30KCAQmQAwEAAZGCAQCSeoZrdYI6fsBVnlM9CC3KHhTmO07BG0d4H1Un8L66U+4IBDfbABhK06uaH299ukf+e9XvNWe8kOZKGjtqAcKxpM3iYI9T61KmYpZOytJbAIebzVg+EFovvg/yOIEq6XXrB0d4GJX6QlwcOu4o/R221yiTPzhvm7aYsUgeItktSfY2YqbxN4LwsWbNWDOF4HoCxRq3tVLzkZrpbcOQbomb/g9My/TMo+2VyN1pCdNbR3v4cyw2NjcrGOU8YmyCDJJ7zR/KnrXNm++QzchN+UjdlUvp810B2KjrvccWn2T8j1g4zFh7C3CJQPwFD3561eBaD2oLqFahVVI6p+tm3ZYN30OCAQCTKs9ibBjzemBC9G3F00JmKSCj9Fs+p3AYsuRODTHSKYAoZN/GW5tVH857l4kUMAG4UqETPdqBv8gxl8IR/oFR9MBLCEk6gsEIvOFqUzvZJGd9JkLAX8Hgp5a+xAo9VVtUFy6QqU7DTXcKjcOJQ9CsjFv28it3mDKKh40lAO4BGHlt2ToQd1eccXovmtZWVxK+XUnT5SVLQAYxsF466RVG0zdTFDaUhM3aspN0d/fNzuEk2PntYD5espEASi81IRuEJplsNY0sAbS1x1LZKfu0zAnYP5H0b2VY3lcPixTgQZfp2jigRafJLzljUn1luWozK85I8+UcpvP5cmnAAGXH"
)

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

// Nonceのハッシュ値を計算します。
digest := sha256.Sum256(nonce)

// マイナンバー画像パースリクエストを作成します。
request := connect.NewRequest(&cardinfov1.ParseMyNumberContentRequest{
// 券面事項確認APから読み出されたデータを設定します。
VerificationPublickey: verificationPublickey,
AuthenticationSignature: authenticationSignature,
MyNumberContent: myNumberContent,
// 作成したハッシュ値を送信します。
// もし、内部認証でNonceと異なる値が署名されていた場合はハッシュ値が一致しないため、検証に失敗します。
Digest: digest[:],
HashAlgorithm: verifyv2.Verification_HASH_ALGORITHM_SHA256,
})

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

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

// マイナンバー画像のパースリクエストを送信します。
response, err := client.ParseMyNumberContent(context.Background(), request)
if err != nil {
return err
}

// 結果を表示します。
fmt.Println("マイナンバー画像")
fmt.Printf("MyNumberImage: %s\n", base64.StdEncoding.EncodeToString(response.Msg.GetMyNumber().GetMyNumberImage()))
return nil
}

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

パース・検証に成功すると、以下のように結果が表示されます。 取得したマイナンバー画像は、対面でのマイナンバーカード裏面に記載されているマイナンバーの正確性の確認などに使用することができます。

注意

モック環境では、券面事項確認 AP によって読み出されたマイナンバー画像に記載されているマイナンバーと、 券面事項入力補助 AP からの読み出しによって得られるマイナンバーが異なります。

モック環境の券面事項確認 AP から読み出される画像はダミー画像となっており、カードによらず同じ画像が読み出されます。

MyNumberImage: iVBORw0KGgoAAAANSUhEUgAAAEgAAAAMAQAAAADpX8aQAAAAYklEQVQI12P4DwMM5ysev7E52GfznWFLeezZ339Lb7szbC+vPfv9d+ntcobt9cVrDH73glh1f9dery6TBrJq/+ZfLy8HiVXfZYeyyu++BbJ2lzOcL0h+Z/G9r+Y7A8IOOAsAy5RN+qOylDIAAAAASUVORK5CYII=

次のステップ

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