[解決済]AWS Glueでマイナンバーが一部検知できないバグについて
TL;DR
- GlueのSensitive Data Detectionで、日本のマイナンバーを検知させるとスルーされるものがある
- チェックデジットの計算過程でmod11が10のときのみ、検知されないことがわかった
- 単純にバグだと思われます
Issue
書いたんですが、出せそうなGitHub repoがないので放置中。(いい方法あったら教えてください。。)とりあえずで、ここに貼っておきます。 AWSJの方からご連絡いただきました。
Issue case
Sensitive data detection was updated to cover some of the PII used in Japan, including "My Number". But Glue does not seem to detect My Numbers with the specific check digit.
My Number is a unique identifier with 12 digits. The last digit is the check digit calculated in mod 11 using the other 11 numbers.
If we assign a=1st of 11, b=2nd of 11, .... , k=11th of 11
, check digit x will be:
x = 11 – (6a + 5b + 4c + 3d + 2e + 7f + 6g + 5h + 4i + 3j + 2k) mod 11 (if x≧10 x=0)
When x = 10 or 11, check digit is set as 0.
The problem is that Glue does not detect "My Number" when x = 0 derived from 10.
Replication
We use Glue studio in almost the default setting.
Data format: CSV
Glue version: 3.0
Worker type G.1X
Transform - Find sensitive data in each row
Select specific patterns Japan My Number
Replace detected text with #####
Input csv
This is a sample csv for the replication. 1st column is "My Number" and 2nd column is x. Note: We have to use col name マイナンバー
(My Number in Japanese) to tell Glue.
When transformed by the glue job, the numbers with x = 10 are remain unchanged.
マイナンバー,x
100000000005,5
100000000013,3
100000000021,1
100000000030,10
100000000048,8
100000000056,6
100000000064,4
100000000072,2
100000000080,11
100000000099,9
100000000102,2
100000000110,11
100000000129,9
100000000137,7
100000000145,5
100000000153,3
100000000161,1
100000000170,10
100000000188,8
100000000196,6
Output
マイナンバー,x
"#####",5
"#####",3
"#####",1
100000000030,10
"#####",8
"#####",6
"#####",4
"#####",2
"#####",11
"#####",9
"#####",2
"#####",11
"#####",9
"#####",7
"#####",5
"#####",3
"#####",1
100000000170,10
"#####",8
"#####",6
説明
GlueのSensitive Data Detectionについて
こちらが詳しいのでご参照ください(ちなみに、今回のバグも現れています)
マイナンバーについて
マイナンバーは12桁なのですが、最後の桁はチェックデジットという、他の11桁の値を使って計算する数値です。こちらのコラムの解説が、とても良かったです。
法律で決まっていて、計算式はこうですよと。
人手での入力間違いが発生しても機械的にすぐわかるように、チェックデジットと俗に呼ばれる1桁が付け加えられており、マイナンバー法では「検査用数字」と呼ばれています。個人番号の検査用数字は最下位の桁、つまり一番右側の1桁で、その計算式は総務省令第八十五号で定められて
個人番号を11桁の数字abcdefghijkxとしますと、検査用数字xはx = 11 – (6a + 5b + 4c + 3d + 2e + 7f + 6g + 5h + 4i + 3j + 2k) mod 11 ただしx≧10ならx=0です
Glueは何がバグっているのか
上記の引用2つ目にあるように、検査用数字(チェックデジット)がx=11, 10
のときは、12桁目は0になります。上のサンプルでいくと、100000000030
はx=10
、100000000080
はx=11
です。
しかし、ジョブを実行しても100000000030
は秘匿情報として検知されていないので、そのまま残っています。
おそらく、マイナンバーであることを確認するために計算する中で、何かが起きているのだと思われます。
ちょっとよくわからないこと
上記コラムに書かれているように、0が末尾のときはチェックデジットとしての精度が悪いので、使わないのが無難、という考え方もあるようです。一方で、マイナンバー番号の払い出しルールは不明です(例えば、法律で定めているものの、末尾0のものは実際は使われないとか)。人のマイナンバーを知ることもできませんので、確かめようがないですね。
ただし、今の時点で「使われていない」という情報もないですし、巷のダミーデータにもx=10
由来のマイナンバーは入っていますし、x=11
由来ならいいのかという疑問もあります。
実はGlueの開発チームがx=10
由来の番号は使われない、という情報を知っていたりして・・・?
まとめ
GlueのSensitive Data Detectionでマイナンバーの一部が検知できないというバグ報告でした。
Appendix
チェックデジット計算用のPythonスニペットです。print出力ですのでよしなにしてください。デフォルトでは上のサンプルデータが出力されます。digit_11str
には、ゼロ埋めも含めて11桁の文字列を入れてください。
def get_check_digit(digit_11str):
"""
Param
: digit_11str : str : 11 digit numbers (zero padding required)
"""
x = [i for i in digit_11str]
y = [6, 5, 4, 3, 2, 7, 6, 5, 4, 3, 2]
tmp = sum([int(i) * j for i, j in zip(x, y)])
check_digit_calc = 11 - (tmp % 11)
if check_digit_calc >= 10:
last_digit = 0
else:
last_digit = check_digit_calc
print(f"{digit_11str}{last_digit},{check_digit_calc}")
start = "10000000000" # 11 digit include zero padding
end = int(start) + 20
assert start.isdigit()
assert len(start) == 11
for i in range(int(start), end):
digit_11str = str(i)
get_check_digit(digit_11str)
Discussion