SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|

2024-01-16(Tue) マイナンバーカードで遊んでみる

  カミさんがふるさと納税の手続きのため、マイナンバーカードをスマホに読ませてアレコレしてほしいといわれ、パスワードを失念していることに気づいた。確か短いのと長いののふたつがあったような気がするのだが。

  正直に「パスワードを覚えていない」というと「そうなると手続きが面倒なのよねぇ」とのこと。フムン。いや、たぶんアレとアレなんだが、長い方が特に自信がない。なんとかならんかと思ってググると、短い方がわかるなら、コンビニで長い方を再設定することができるらしい。短い方は割と自信がある。試してみるか。で、無事に再設定することができ、ふるさと納税の手続きも完了した。よっしゃよっしゃ。

  画像の説明

  と、そこでフトだいぶ前に買ったカードリーダが手元にあることに気づいた。もしかすると、これで読んだりできるのかしらん。早速、やってみた。

$ pkcs15-tool --dump
Using reader with a card: NTT Communications Corp. SCR3310-NTTCom USB SmartCard Reader [Vendor Interface] 00 00
PKCS#15 Card [JPKI]:
	Version        : 0
	Serial number  : 00000000
	Manufacturer ID: JPKI
	Flags          : 
 
PIN [User Authentication PIN]
	Object Flags   : [0x12], modifiable
	ID             : 01
	Flags          : [0x12], local, initialized
	Length         : min_len:4, max_len:4, stored_len:0
	Pad char       : 0x00
	Reference      : 1 (0x01)
	Type           : ascii-numeric
	Tries left     : 3
 
PIN [Digital Signature PIN]
	Object Flags   : [0x12], modifiable
	ID             : 02
	Flags          : [0x12], local, initialized
	Length         : min_len:6, max_len:16, stored_len:0
	Pad char       : 0x00
	Reference      : 2 (0x02)
	Type           : ascii-numeric
	Tries left     : 5
 
Private RSA Key [User Authentication Key]
	Object Flags   : [0x1], private
	Usage          : [0x4], sign
	Access Flags   : [0x1D], sensitive, alwaysSensitive, neverExtract, local
	ModLength      : 2048
	Key ref        : 1 (0x1)
	Native         : yes
	Auth ID        : 01
	ID             : 01
	MD:guid        : c5a0a252-9d2d-eb60-fec0-41b4fbd722a2
 
Private RSA Key [Digital Signature Key]
	Object Flags   : [0x1], private
	Usage          : [0x204], sign, nonRepudiation
	Access Flags   : [0x1D], sensitive, alwaysSensitive, neverExtract, local
	ModLength      : 2048
	Key ref        : 2 (0x2)
	Native         : yes
	Auth ID        : 02
	ID             : 02
	MD:guid        : e1bc1dae-59f1-16ab-b43f-9dafbb2acc9b
 
Public RSA Key [User Authentication Public Key]
	Object Flags   : [0x0]
	Usage          : [0x0]
	Access Flags   : [0x2], extract
	Key ref        : 1 (0x1)
	Native         : yes
	Path           : 000a
	ID             : 01
 
Public RSA Key [Digital Signature Public Key]
	Object Flags   : [0x0]
	Usage          : [0x0]
	Access Flags   : [0x2], extract
	Key ref        : 2 (0x2)
	Native         : yes
	Path           : 0001
	ID             : 02
 
X.509 Certificate [User Authentication Certificate]
	Object Flags   : [0x0]
	Authority      : no
	Path           : 000a
	ID             : 01
	Encoded serial : xx xx xxxxxxxx
 
X.509 Certificate [Digital Signature Certificate]
	Object Flags   : [0x1], private
	Authority      : no
	Path           : 0001
	ID             : 02
 
X.509 Certificate [User Authentication Certificate CA]
	Object Flags   : [0x0]
	Authority      : yes
	Path           : 000b
	ID             : 03
	Encoded serial : 02 04 0133C349
 
X.509 Certificate [Digital Signature Certificate CA]
	Object Flags   : [0x0]
	Authority      : yes
	Path           : 0002
	ID             : 04
	Encoded serial : 02 04 0132C4AB

  えらくゾロソロと出てくるが、わからんようなわかるようなで面白い。特に冒頭の「PIN」「Tries left」なんて、どう見てもパスワードの失敗許容回数だ。当たり前だがカード内で管理されてるんだな。なかなか高機能なカードであるといえよう。

  そのほか「Private RSA Key」「Public RSA Key」「X.509 Certificate」なんてのも、普段からSSLをガチャガチャしているオイラには見慣れた概念だ。証明書の内容を読み出してみる。

$ pkcs15-tool --read-certificate 1
-----BEGIN CERTIFICATE-----
XXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxx
xxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXX
 :
XXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxx
xxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXX
-----END CERTIFICATE-----

  完全にpem形式である。opensslで読めそうだ。ちな、2番目の証明書だけはPINコードでロックされているので、以下の指定が必要になる。指定すると入力を促されるので、入力してやると出力される。

$ pkcs15-tool --read-certificate 2 --auth-id 2 --verify-pin
Please enter PIN [Digital Signature PIN]: 
-----BEGIN CERTIFICATE-----
XXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxx
xxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXX
 :
XXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxx
xxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXXxxXX
-----END CERTIFICATE-----

  自分の環境では公開鍵は読み出せなかった。PINコードが正しくてもダメ。

$ pkcs15-tool --read-public-key 1
Public key enumeration failed: Required ASN.1 object not found
$ pkcs15-tool --read-public-key 2 --auth-id 1 --verify-pin
Please enter PIN [User Authentication PIN]: 
Public key enumeration failed: Security status not satisfied

  さらに秘密鍵にもなると読み出すコマンドすらない。そもそも「neverextract」だから読み出せなくて正しそう。カードに暗号文を渡し、カード内で(秘密鍵を使って)復号して平文を返してもらう、という形なんだろう。実に高機能なカードである。いくらすんだろね、これ。

  以上をまとめると以下のようになる。

カード情報 JPKI
(PIN1) PIN ユーザ認証PIN 4桁 残3回
(PIN2) PIN デジタル署名PIN 6-16桁 残5回
(秘密鍵1) 秘密RSA鍵 ユーザ認証鍵 署名用 機密 2048桁
 →読み出し不可
 →カード内で復号させる、PIN1で保護されている
(秘密鍵2) 秘密RSA鍵 デジタル署名鍵 署名用 非否認 機密 2048桁
 →読み出し不可
 →カード内で復号させる、PIN2で保護されている
(公開鍵1) 公開RSA鍵 ユーザ認証鍵
 →読み出し失敗
(公開鍵2) 公開RSA鍵 デジタル署名鍵
 →PIN2で保護されている、読み出し失敗
(証明書1) X.509 証明書 ユーザ認証証明書
(証明書2) X.509 証明書 デジタル署名証明書
 →PIN2で保護されている
(証明書3) X.509 証明書 ユーザ認証認証局証明書
(証明書4) X.509 証明書 デジタル署名認証局証明書

  pem形式の証明書が読み出せたので、デコードして可視化してみる。

require 'openssl'
cert = OpenSSL::X509::Certificate.new($stdin.read)
puts(cert.to_text)
$ ./pem_dec.rb < UserAuthenticationCertificateCA.pem
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 20169545 (0x133c349)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C=JP, O=JPKI, OU=JPKI for user authentication, OU=Japan Agency for Local Authority Information Systems
        Validity
            Not Before: Sep 14 23:41:59 2019 GMT
            Not After : Sep 14 14:59:59 2029 GMT
        Subject: C=JP, O=JPKI, OU=JPKI for user authentication, OU=Japan Agency for Local Authority Information Systems
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Certificate Sign, CRL Sign
            X509v3 Subject Alternative Name: 
                DirName:/C=JP/O=\xE5\x85\xAC\xE7\x9A\x84\xE5\x80\x8B\xE4\xBA\xBA\xE8\xAA\x8D\xE8\xA8\xBC\xE3\x82\xB5\xE3\x83\xBC\xE3\x83\x93\xE3\x82\xB9
            X509v3 Basic Constraints: critical
                CA:TRUE
            X509v3 CRL Distribution Points: 
                Full Name:
                  DirName:C = JP, O = JPKI, OU = JPKI for user authentication, OU = Japan Agency for Local Authority Information Systems
            X509v3 Subject Key Identifier: 
                8C:D5:58:6A:89:14:85:E5:59:37:9B:7E:29:D4:10:CF:D2:8B:35:93

  上記は「(証明書3) X.509 証明書 ユーザ認証認証局証明書」の抜粋だ。いわば、日本国の(オレオレ)証明書であり、日本国民なら共通の情報であるから、内容を公開しても問題ない。

  公開するとマズいのは、(私自身の)個人情報を含んでいる「(証明書1) X.509証明書 ユーザ認証証明書」「(証明書2) X.509 証明書 デジタル署名証明書」の方だが、前者は(おそらく)マイナンバーの番号だけで、直接的な情報は後者に含まれているはずだ。

  んが、上記のスクリプトで後者を読み出してみても、たいした内容が出てこない。せいぜい、以下の「区」くらいで、これは証明書の発行元の情報である。

            X509v3 CRL Distribution Points: 
                Full Name:
                  DirName:C = JP, O = JPKI, OU = JPKI for digital signature, OU = CRL Distribution Points, OU = Aichi-ken, CN = Nagoya-shi-Xxxx-ku CRLDP

  クサイのは以下。デコードができていないっぽい。そういえば、「othername:<unsupported>」って、先日の自分に会社から支給されている証明書でも出てたな。その時は深く考えなかったけれど。

            X509v3 Subject Alternative Name: 
                othername:<unsupported>, othername:<unsupported>, othername:<unsupported>, othername:<unsupported>, othername:<unsupported>, othername:<unsupported>

  で、調べていくと、これは「ASN.1」という形式らしく、まさにソコに情報が入っているようなのだが、opensslのtext出力ではその中身までデコードしてくれないようなのである。

  そんならRubyのOpenSSL::ASN1クラスを使ってデコードすりゃええか……と、思ったらその中身がムチャクチャに複雑で、ちっとも意図した結果が得られない。結局、どうにかこうにか再帰を使って出力に成功したが、実際にその中身はムチャクチャに複雑だった。これは再帰なしで書いたら日が暮れるな。文字列なのに、それがデコードできる場合と、単なる文字列の場合があるって、どういう構造なんだよ。

def asn_decode(value, n)
    puts('%sdecode[%s]' % [(indent = '  ') * n, value.class])
    if(value.is_a?(Array))
        value.each {|v|
            asn_decode(v, n + 1)
        }
    else
        begin
            asn = OpenSSL::ASN1.decode(value)
            asn_decode(asn.value, n + 1)
        rescue
            puts('%smay be string[%s]' % [indent * n, value])
        end 
    end
end
 
cert.extensions.each {|ext|
    puts('*%s' % ext.to_h['oid'])
    asn_decode(ext, 1)
}

  「(証明書4) X.509 証明書 デジタル署名認証局証明書」をデコードすると、以下の結果が得られた(抜粋)。

$ ./pem_dec.rb < UserAuthenticationCertificateCA.pem
*subjectAltName
  decode[OpenSSL::X509::Extension]
    decode[Array]
      decode[OpenSSL::ASN1::ObjectId]
        decode[String]
        may be string[subjectAltName]
      decode[OpenSSL::ASN1::OctetString]
        decode[String]
          decode[Array]
            decode[OpenSSL::ASN1::ASN1Data]
              decode[Array]
                decode[OpenSSL::ASN1::Sequence]
                  decode[Array]
                    decode[OpenSSL::ASN1::Set]
                      decode[Array]
                        decode[OpenSSL::ASN1::Sequence]
                          decode[Array]
                            decode[OpenSSL::ASN1::ObjectId]
                              decode[String]
                              may be string[C]
                            decode[OpenSSL::ASN1::PrintableString]
                              decode[String]
                              may be string[JP]
                    decode[OpenSSL::ASN1::Set]
                      decode[Array]
                        decode[OpenSSL::ASN1::Sequence]
                          decode[Array]
                            decode[OpenSSL::ASN1::ObjectId]
                              decode[String]
                              may be string[O]
                            decode[OpenSSL::ASN1::UTF8String]
                              decode[String]
                              may be string[公的個人認証サービス]
                    decode[OpenSSL::ASN1::Set]
                      decode[Array]
                        decode[OpenSSL::ASN1::Sequence]
                          decode[Array]
                            decode[OpenSSL::ASN1::ObjectId]
                              decode[String]
                              may be string[OU]
                            decode[OpenSSL::ASN1::UTF8String]
                              decode[String]
                              may be string[公的個人認証サービス署名用]
                    decode[OpenSSL::ASN1::Set]
                      decode[Array]
                        decode[OpenSSL::ASN1::Sequence]
                          decode[Array]
                            decode[OpenSSL::ASN1::ObjectId]
                              decode[String]
                              may be string[OU]
                            decode[OpenSSL::ASN1::UTF8String]
                              decode[String]
                              may be string[地方公共団体情報システム機構]

  さらに抜粋するとこう。

$ ./pem_dec.rb < DigitalSignatureCertificateCA.pem | grep may
        may be string[subjectAltName]
                              may be string[C]
                              may be string[JP]
                              may be string[O]
                              may be string[公的個人認証サービス]
                              may be string[OU]
                              may be string[公的個人認証サービス署名用]
                              may be string[OU]
                              may be string[地方公共団体情報システム機構]

  そしてクライマックスだ。「(証明書2) X.509 証明書 デジタル署名証明書」をデコードすると、以下の結果が得られた(抜粋)。

$ ./pem_dec.rb < DigitalSignatureCertificate.pem | grep may
        may be string[subjectAltName]
                  may be string[1.2.392.200149.8.5.5.1]
                      may be string[山田 太郎]
                  may be string[1.2.392.200149.8.5.5.4]
                      may be string[319700101]
                  may be string[1.2.392.200149.8.5.5.3]
                      may be string[1]
                  may be string[1.2.392.200149.8.5.5.5]
                      may be string[愛知県名古屋市中区栄3丁目]
                  may be string[1.2.392.200149.8.5.5.2]
                      may be string[00000]
                  may be string[1.2.392.200149.8.5.5.6]
                      may be string[00000000000000000000]

  当然だが上記は改ざんしている。んが、モロに自分の個人情報が入っていた。「デジタル署名」をするという行為は、上記の情報を提供するということであり、それが意図に反して行われないようにするためのものが、長い方のPINコードなのであった。逆に言えば、長い方のPINコードの要求に応じた場合は「自分の個人情報が提供される」ということだ。

  しかし、だ。「名前、生年月日、性別、住所」なんて、役所で気にもせずに一番に書面に書き出す内容である。たかが、それだけの情報なのである。マイナンバー制度に関してはマスゴミの意味不明のFUDキャンペーンで、すっかりネガティブイメージが付いてしまっているが、フタを開けてみればそれだけのこと。ボールペンで書くか、PINコードを打つかの違いしかないといえよう。仮に落として紛失したところで、運転免許証と同程度の危険性しかない。

  ちょっと前にマイナンバーカードを普及するため「マイナポイント事業」というのがあった。調べると「2020年9月に始まった第1弾では2979億円、今年6月から本格実施した第2弾では1兆8134億円を計上した」とあり、例によってマスゴミはこの予算について批判をしていたが、それは「無知なオマエラが無駄に騒ぎ立ててFUDしたから必要になった予算」ではないのか。マイナンバーで事務処理が円滑になれば役所の運営費も減るんだよ。しかも恒久的に。少しくらいは考えてモノを言えっつーの。オマエラが騒ぐとアホな国民の方々はその通りに踊っちゃうんだからさ。

  別に自分は常に日本国万歳ではないが、ことこの件については、マイナンバーカードの返納とか、日本国運営の方々に於かれては、本当にアホな国民の方々をお持ちのようで心から同情いたします。草々。

  あー、そうだ。とりあえずホテルの宿帳を書くの毎度メンドいんで、マイナンバーカードのタッチだけで済むようにしてほしいです。はい。