はじめに

OpenSSHの公開鍵といえば、

ssh-keygen -t rsa -b 4096 -N '' -f id_rsa

といったコマンドで作成できます。
これで作成した鍵で別のものをopensslコマンドを使って暗号化したくて変換する必要があったので調べました。

以下の内容はMac OS X & Homebrewで普通にコマンドを揃えたときの話です :smiley_cat:

公開鍵

OpenSSHの公開鍵は~/.ssh/authorized_keysにおいて使うことが多いと思いますが、こんな形になっています。

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC77LdFUQeT2/YiNveZKe6fANforzJ9C6q+XETRqgegmeP/Yv4ep3H45XafK2Fax+ACJc9bh0DH0j/UPgRLauHzr9Y4LhngvMf/tjjX0P5cuQfuZjY7kKVn1bXCiRjLSNpdMnBwEgnRfDC7JrseAACAgIj8EnBmmxk46qYjIkVW9n2Phh/EwHTvPuSyCsnTQjsKzWVIwI5z+RYLN+3PqPxihf99ttW+VmnSfG6fTHww4SiZrj1YsAJjY4TicZVEg5moe9B7Gncj2ZjiJmw0sagWMXq/kjjB5nxlWycZm4C/1T4tNV7Sg+xI9fRIzJpiyo82xNy6BWDrgv3vWbrG932KFHDWoB55jByyOPHSd30ZAuv67f4JdzX76LAp73mQdJTwAuOJaXhC8Gy22PTObXUKtcOJQFXR1sBOmeNspd61FukXZRzI7JZHa1Z3tXGiAZyCRPKhlwxWPD80FPZ6yStjmjsGfG+dh7W021u2PUXQM8epV7e+vh3jLnHrM2k4A0cATQ5NAPf6yUNmtjL78M0KdRuzY8Q2+YckTp0NCT/hfvQoDoAlCtBxEVPwzKBI55KDa34SzZDQZnWmyONQ1syPKvsFICyL04hCSoCNME0wsVXgGlyLdN4TMdsmfmFfVPusEjLCMGw7gUrtk9YzDv0TjrrwXsiWhLA3ZZ2twnr8bQ== nownabe demo

ところが公開鍵暗号方式の暗号化キーとして用いられるのはこういう形式(PEM)が多いです。

-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAw7Vc9YJ9zw0VjRTdcX3b
hzhLD47WKwiiYoA4DxfrhczyxQBkCF/UBAfi/FsguLSyzTShnsU486yijseHPVAJ
tbl9DfqHw0dXxyJY7MuRsjtj5ULYM0m0TIx3RIJvEb1lX57f8QUvRSEtUIbfRJwb
+8ZNgDpTjqOQs+FbagvO+TnFvxMUsZFTd2QHjRjHQcrkBTU1ya60nCMOdkhxQYnE
K62hCvNYrbSkagYFNpcysz7E/D/Tzo7PYjGt1qTNfTac58YzpkSZ+MUA5l0zSbUd
QrmBtJG/YgAS7GO3xFW7hnNNG11i/aFWgIqmzkYMS+vubz1C80fBuKXqjvdGZmbc
zM1hOEPkBwJWh2ix6Hmvjo0xPfBCw5OlYA7YWer4zq/PSrYwRhyHUDMRPOMKJLf/
2PsFV02hn5RojMliaX8Dz4WsDA6LMJtyD/Bf3rE2NdKDpu3P6mDMxIxTuSUBdr65
TRJq4YSBZkN4HN5yHOqm2DEuT8bHZvFxEXwnN9aKR59Y4hlYkpU/ABaHWIugR48H
tjqUK/2E6MpugfC/2FQTJWXlfVwCP2R0x6QcKPMy4BdpPlEo9VaFYDTNjXfKPi/G
fYC4PyQ+DPdQZ/ftV46tSAMwwsR71O/petUSz7bo+/wfQx9zfAD+MLaF5mcPaosX
jOCcNogzMejl7cEpdh2vaCMCAwEAAQ==
-----END PUBLIC KEY-----

opensslコマンドを使うと非常に簡単に公開鍵暗号が実現できますが、扱えるのは後者なのでOpenSSH形式の公開鍵を使うには後者の形式に変換してやる必要があります。

変換

変換するには次のコマンドを使います。

ssh-keygen -f id_rsa.pub -e -m PKCS8 > id_rsa.pub.pem

詳しく調べてませんが、-mオプションにはPEMではなくPKCS8を指定してやる必要があります。

暗号化

変換できれば、暗号化は簡単にできます :key:
(暗号化の結果はバイナリになるのでBase64で符号化してます)

$ echo "password" | openssl rsautl -encrypt -pubin -inkey id_rsa.pub.pem | base64
sL+YgyAQ8O4CS7UHYy/h++P++fqZ21X0YInO/I27GmsOIrVtCX5ZZgoobLeIxZz3nXpPe6L4SSxcsUs0mW77m5ChvkCCj4d5fHuZyn0F0spa/0nrrR/ypue5PPbFEhNZHRI6YoWlG+4f5rRe3tyqcWpae9V2Bp8W9JHKrqil2DztBx/SpEhbtrkttyKm9DDANaiJBhTrPa0TMopdoZ3tOHhcjkcCskgzpLMPdxB/gNyO9cwa/fOtyGUcZ5asm+Om2e9UqUUlXGfloaIbGF7AynmKVbfwPVI19cgXLsT4W2pWeywhKcko2d83G77rOxTMyilPj/wZq2GpZobt8HHhTvB8X1imP7a92WCywLmOD1mEXL6Tz7ybra3RxPw9QjllBLq7Yvp0JCwdrncuWUZ33CasWgWfzG5P3Jbc3hmcqAblwTzff0d26pjCPoLqcjfDGmGsm+Bz5s9kCh+XPzvkwmh3zx/gV4/orajzY4As6XTyu7QP3AVGKkc9Cdwlu1pVqnelbG86HxTbqMtdC4LjbHvsoKasOXKAbjUXCyMo7LdMjoVuYElKRODc7XFDnuAy8ChNrs2nW7K9qYhJsOAPi7vEFbiqtdeTcmQCKhxieEA4/eLsAbz2IOTQrTAulHZ25Ny6D3YGC6ncG/Lme58J0hoHfckizV6NE1FlSITQKeY=

ちなみに復号するのはこんな感じです。
秘密鍵はssh-keygenのものでも変換なしに使えます。

$ echo "password" | openssl rsautl -encrypt -pubin -inkey id_rsa.pub.pem | base64 | base64 -D | openssl rsautl -decrypt -inkey id_rsa
password