2.4 KiB
2.4 KiB
+++ date = "2022-07-06" tags = ["make","card"] title = "カードを作ってみた5" slug = "card" +++
カードに秘密鍵を刻印して認証する仕組みを作ってみました。
$ openssl genrsa -out private.pem 31
$ openssl rsa -in private.pem -pubout -out public.pem
$ openssl rsa -text -pubin < public.pem
$ openssl rsa -text < private.pem
modulus INTEGER, -- n = p*q
publicExponent INTEGER, -- e = 65537 (=0x10001)
privateExponent INTEGER, -- d == e^(-1) mod (p-1)*(q-1)
prime1 INTEGER, -- p
prime2 INTEGER, -- q
exponent1 INTEGER, -- d mod (p-1)
exponent2 INTEGER, -- d mod (q-1)
coefficient INTEGER, -- q^(-1) mod p
### gh-actions
$ openssl rsa -in pull-private.pem -pubout -out pull-public.pem
a=`openssl md5 public.pem|cut -d " " -f 2`
b=`openssl md5 pull-public.pem|cut -d " " -f 2`
if [ "$a" = "$b" ];then
echo verify
else
exit
fi
いろんな問題はあるけど、簡易版はこんな感じになりました。
例えば、一つのカードにつき秘密鍵を一つだけ発行することにして、その所有者が秘密鍵をpull-reqすると認証できるようにします。
送られた秘密鍵から公開鍵を作り、アップロードされている公開鍵に一致すれば、jsonのowner要素にpull-reqのusernameを入れて更新する仕組み。
問題の一つとしては、鍵長をカードに刻印できるほど短くしてしまうと、総当たり攻撃で簡単に突破されてしまいます。
2つ目の問題として、公開鍵のmd5で一致するか見ていますが、本来は個々の処理を計算に置き換えるべきでしょう。
rsaは、例えばprime1 x prime2 = modulus
になります。秘密鍵に記述された数値を計算していくと、公開鍵に記述された数値になることをもってペアであるか判断します。具体的な計算式は上記に載せています。
私は処理書くのも面倒なので、送られてきた秘密鍵をもとに公開鍵を作り、それが一致するか見るだけにしています。
ここまで鍵長が短いと署名もできませんので、カードに見栄え良く刻印できる文字列のみで完璧な認証を作るのは難しいのかもしれません。