Goのcrypto/rsaのEncryptPKCS1v15の使い方メモ
ちょっと自信がないので、OpenSSLでやったのと同じ結果になるか確かめてみる。
とりあえずこの記事を見ながらやってみる。
鍵の生成
まずは鍵の生成。デフォルトだと2048bitだけど、RStudioが使っている鍵と合わせたいのであえて1024bitの鍵を生成する。public exponentはF4(0x10001)にする。これはデフォルトのままで大丈夫だけどいちおう明示的に指定している。
$ openssl genrsa -f4 1024 > test.key Generating RSA private key, 1024 bit long modulus ...............................................++++++ ..................++++++ e is 65537 (0x10001)
modulus
この鍵のmodulusを確かめる。modulusを確かめるにはopenssl rsa -modulus
で確かめられる。
$ openssl rsa -modulus -noout < test.key Modulus=C39863E719AD6022C444BE38FB6F396795CBA307534CFB3B0DB674F0741BEB498C543F5D3706716C99AF11282D45EF105784FEBC19D9095737376612978C8B1C01391ADE12CD7D0F4D6D64B558BDB9A6792AD2902C0EDE9B0649282B1B8A04DF930825AB4B95B2EF261594F7EE3CFDA6C39C42E044317E7E072220017FFF160B
暗号化
適当なテキストを暗号化する。openssl rsautl -encrypt
というコマンドがあるらしい。知らんかった。
$ echo test | openssl rsautl -encrypt -pkcs -inkey test.key u↑S�T����◄↔��E��§?8♦�↔¶ۧת�☼�?��,♣�p�s?&�Y~�����♦H↨�/��S��c�.�o�y�Le�ӎ�!4N����{Na§RϼN�%3���☺�w����h�6↕■�o���qb%m��R�a
なにやら文字化けした。これはバイト列なのでBASE64化しといたほうがいいらしい。openssl base64 -e
を使う。乱数があるので毎回結果は違う。
$ echo -n "test" | openssl rsautl -encrypt -pkcs -inkey test.key | openssl base64 -e naqVeUXTPwgL7I3+Fhcg2SUzPjvIsbD4ZEywxxBc8hhlUSsKpufyurxVlP0PHxbr 9xKMH5Ry/Y+wB3FWGTEsUMDYOXyV53CDUa9ohNrcZVHpXP+fzBRLXdFkqvBCwFP8 SkLrCMp6m32bY9KpHn1GJ60tqCQeo2EozqAj5PrpG/M=
OpenSSLで復号
今度はさっきと逆に、BASE64をでコードして、同じ鍵でdecryptしてやればいい。Goで暗号化した文字列も同じ方法で復号できるはず。
$ echo 'UAgUOzol/YCryxdocFkLJ5FtaPlrJ3TJXU9SwjIeYBaqEfutCphJU+vllkY3kNIWJn0wqI5HTZAyYmhjDO+/yniNDO+gRbhDAHcRYlSpCMeS6VgAV3meDUNfwl0UxPiB0JqTsR9aXxUoLPKLc+ESlbNPAZ0jVQ97vqTS1czICyM=' \ > | openssl base64 -d | openssl rsautl -decrypt -pkcs -inkey test.key test
Go
いよいよGoでやってみる。
まず、modulusをbig.Int
に変換する。math/big
にはParseFloat()
とParse()
があるけどどっちもFloatしか返さなくてどうするの??と混乱してたけど、まずnew
してからsetString()
するらしい。
big - The Go Programming Language
modulusString := "C39863E719AD6022C444BE38FB6F396795CBA307534CFB3B0DB674F0741BEB498C543F5D3706716C99AF11282D45EF105784FEBC19D9095737376612978C8B1C01391ADE12CD7D0F4D6D64B558BDB9A6792AD2902C0EDE9B0649282B1B8A04DF930825AB4B95B2EF261594F7EE3CFDA6C39C42E044317E7E072220017FFF160B" modulusInt := new(big.Int) modulusInt.SetString(modulusInt, 16)
このmodulusを使ってrsa.PublicKey
をつくる。N
がmodulus、E
がpublic exponent。
rsa - The Go Programming Language
pubkey := &rsa.PublicKey{N: modulusInt, E: 0x10001}
rsa.EncryptPKCS1v15()
は、他に乱数生成器として?io.Reader
を引数に取る。rand.Reader
とかを指定しておくのがお作法らしい。
https://golang.org/pkg/crypto/rsa/#EncryptPKCS1v15
result, _ := rsa.EncryptPKCS1v15(rand.Reader, pubkey, []byte("test"))
base64 - The Go Programming Language
encoded := base64.StdEncoding.EncodeToString(result)
https://play.golang.org/p/C4Ersc5Gub
OpenSSLで復号
やってみる。
$ echo 'm0ofaVSC8djEIUCU/OwDmz1fnSlnhzHMUWCrx5jkNDrlG7ixD20/1tqGHRGhoCJ1jQCrg3ZHkD3bnWOKHeBlGld9In8WObdpJFrBQXIm8vVh+GqOlzHxumt45K3n68cJ6uZpZwsxuoOL5+an4yIPjgBENqmcW4amfyrOo/+3ICw=' \
> | openssl base64 -d | openssl rsautl -decrypt -pkcs -inkey test.key
test
ということであってそう。