SSH 公開鍵ユーティリティを Go と Python で作った
はじめに
こんにちは、 NHK 技研公開に行った所、何度も「学生さんですか?」と訊かれた yosida95 です。
タイトルのとおり、 Pure Go と Pure Python で SSH 公開鍵ユーティリティを作ったのでご案内します。
- Go
- yosida95/golang-sshkey
- Python
- yosida95/python-sshkey
SSH 公開鍵ユーティリティ
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMjH3YZMNFG8cnl98t6w6Ca152cnTsWyrZ56WYSYNkEax1grChZB3P4NcxmtqFxrN2wMXuATiqp62cNkj8wAQUIwRgUnqKkkaQTDyLEDVaTZ75RsZIE4vM/YJ5AzmbCIHK8u6YvfM8fIlv4PKzbMHIIcZvuG9ZYQ+ZEKmSIVxIKZNVfUYyoRK6RFPEMjZPGGoOFRBo8sifsJDLDIBLWOgR4Nf2rWuV+ZuySXX9wjsv42iIdp9RVJcjQXHmi7AKVifKfFJwM+6aPiQcAaWnINzvUnqQK5yrWEp5tVH49bFL92UNriT+LTozloILCj5SdqXQ+JbKp/6EobY96bWhkwyZ yosida95@yosida95
上に示したのが SSH 公開鍵で、ちなみに普段ぼくが使っているものです。 よく見るフォーマットだと思います。
この公開鍵は、目に見える通り3つのパートから成っていて、左からアルゴリズム、公開鍵、コメントとなっています。 また、2つめの公開鍵のパートは BASE64 エンコードされていて、デコードすると RSA の場合は "ssh-rsa", exponent (E), modulus (N) のように、アルゴリズムと公開鍵のパラメーターが含まれています。
今回作ったユーティリティでは、 Printable ASCII で表現される公開鍵をデコードし、コメントや鍵長を取得したり、フィンガープリント(鍵指紋)を計算したり、 golang-sshkey の場合は crypto/rsa の *rsa.PublicKey のような標準的な構造体に変換したりできます。
インストール
golang-sshkey
$ go get github.com/yosida95/golang-sshkey
python-sshkey
$ pip install sshkey
使い方
golang-sshkey
package main
import (
"crypto"
"crypto/rsa"
"fmt"
"github.com/yosida95/golang-sshkey"
)
const (
marshaledPub = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMjH3YZMNFG8cnl98t6w6Ca152cnTsWyrZ56WYSYNkEax1grChZB3P4NcxmtqFxrN2wMXuATiqp62cNkj8wAQUIwRgUnqKkkaQTDyLEDVaTZ75RsZIE4vM/YJ5AzmbCIHK8u6YvfM8fIlv4PKzbMHIIcZvuG9ZYQ+ZEKmSIVxIKZNVfUYyoRK6RFPEMjZPGGoOFRBo8sifsJDLDIBLWOgR4Nf2rWuV+ZuySXX9wjsv42iIdp9RVJcjQXHmi7AKVifKfFJwM+6aPiQcAaWnINzvUnqQK5yrWEp5tVH49bFL92UNriT+LTozloILCj5SdqXQ+JbKp/6EobY96bWhkwyZ yosida95@yosida95"
)
func main() {
pubkey, err := sshkey.UnmarshalPublicKey(marshaledPub)
if err != nil {
panic(err)
}
nativePub := pubkey.Public().(*rsa.PublicKey)
fmt.Println(pubkey.Type() == sshkey.KEY_RSA)
fmt.Println(nativePub.E)
fmt.Println(pubkey.Length())
fmt.Println(pubkey.Comment())
fp, _ := sshkey.PrettyFingerprint(pubkey, crypto.MD5)
fmt.Println(fp)
// Output:
// true
// 65537
// 2048
// yosida95@yosida95
// 17:59:d1:53:0a:38:33:91:ff:8c:f8:f6:16:89:ed:f0
}
python-sshkey
# -*- coding: utf-8 -*-
import sshkey.public
marshaled_pub = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDMjH3YZMNFG8cnl98t6w6Ca152cnTsWyrZ56WYSYNkEax1grChZB3P4NcxmtqFxrN2wMXuATiqp62cNkj8wAQUIwRgUnqKkkaQTDyLEDVaTZ75RsZIE4vM/YJ5AzmbCIHK8u6YvfM8fIlv4PKzbMHIIcZvuG9ZYQ+ZEKmSIVxIKZNVfUYyoRK6RFPEMjZPGGoOFRBo8sifsJDLDIBLWOgR4Nf2rWuV+ZuySXX9wjsv42iIdp9RVJcjQXHmi7AKVifKfFJwM+6aPiQcAaWnINzvUnqQK5yrWEp5tVH49bFL92UNriT+LTozloILCj5SdqXQ+JbKp/6EobY96bWhkwyZ yosida95@yosida95'
def main():
pub = sshkey.public.from_openssh(marshaled_pub)
print(pub.type) # => sshkey.public.SSHKeyType.RSA
print(pub.length) # => 2048
print(pub.comment) # => yosida95@yosida95
print(pub.pretty_finger_print()) # => 17:59:d1:53:0a:38:33:91:ff:8c:f8:f6:16:89:ed:f0
if __name__ == '__main__':
main()
実績
実は今回作ったのは golang-sshkey の方だけで、 python-sshkey の方は半年前に作って公開していたものです。 この python-sshkey にはすでに、私が所属するゲヒルンが提供する Gehirn Infrastructure Services の RS2 Plus で使われているという実績があります。
[シリーズGWS]第4回 Gehirn RS2 Plus のアカウントを作り SSH でログインする
また、近々 golang-sshkey の方も同様に Gehirn RS2 Plus で利用する予定があります。
おわりに
どちらのパッケージも3条項 BSD ライセンスで公開しています。 ご活用ください。 また、コントリビュートをお待ちしています。
こちらからは以上です。