opensslで公開鍵暗号方式を使ってみる
Web上にバイナリデータを置きたいのだが、ただノホホンと置いておくと悪い人達に改ざんされてしまう恐れもあるので、公開鍵暗号を使って署名をつけることにした。今まで、やったことがないので、ちょっと調べてみたが、Linux(今回はUbuntuを使う)で使える公開鍵暗号方式が幾つかあった。
最初にgpgを使おうとしたが、これはメールでの利用が前提となっているみたいで、特定の相手に対して暗号したりする機能しかなかった。また、秘密鍵では暗号化できないみたい。(それほど深く調べたわけではないが。)メールの暗号化や署名には便利そうだが。
そこで、次にopensslを調べてみた。これはWebサーバとブラウザの間で暗号通信するために作らているしくみだが、Webサーバ無しでも単体で使えるし、署名目的で秘密鍵での暗号も出来る。ただし、鍵の長さにもよるが暗号化できるデータの長さが数十文字しか出来なかった。他に方法があるのかも知れないが、今回は署名目的なので十分だ。
■ opensslをインストールする
Ubuntu Desktopなどには標準でインストールされているが、Ubuntu Serverではインストールされていない場合もあるので、コマンドが無ければ最初にインストールする。
$ sudo apt-get install openssl
■ 秘密鍵と公開鍵を作る
まずは鍵をつくらないといけない。誰にも教えてあげない秘密鍵、と、みんなに教える公開鍵。
秘密鍵の作り方:
$ openssl genrsa -out adsaria_private.pem -aes256 2048
この例では、“adsaria_private.pem”というファイルに2048ビット長の秘密鍵を生成する。秘密鍵なので、他の人には知られないように aes256という方法で暗号化しておく。(従って、この秘密鍵を使う時は必ずパスワードを聞かれる。)
公開鍵の作り方:
$ openssl rsa -in adsaria_private.pem -pubout -out adsaria_public.pem
先程作った秘密鍵のペアとなる公開鍵を“adsaria_public.pem”というファイルに生成する。
以下は実際に秘密鍵と公開鍵を作った例である。
adsaria@ubuntu:~/tmp$ openssl genrsa -out adsaria_private.pem -aes256 2048 Generating RSA private key, 2048 bit long modulus ..........................+++ ............+++ e is 12345 (0x12345) Enter pass phrase for adsaria_private.pem: password Verifying - Enter pass phrase for adsaria_private.pem: password adsaria@ubuntu:~/tmp$ adsaria@ubuntu:~/tmp$ ls adsaria_private.pem adsaria@ubuntu:~/tmp$ adsaria@ubuntu:~/tmp$ cat adsaria_private.pem -----BEGIN RSA PRIVATE KEY----- Proc-Type: 4,ENCRYPTED DEK-Info: AES-256-CBC,78BAE587D284CE7CDF97E8AFE6740086 9zeZ5AJYlbuZdXyb3tfPWDHviooh237/9/IP9zImGds2HGqvbCtcnSRuGw66e7qu XKUG/qyKJy+sD5Rug06YIkLlTifrH+auGdbl4ZBw4cTH3s9I4TUALAd8v0CURDiM z8r8TAYh/aF8Ui9rWiEtcAblMklyb1QlEIRtO4WSkTebcsosZjCOx5z14c76vZCq : 中略 : ofESmlnYlNwL8IcT8/zHU11Xe+HY3r5Bi1nnHUX0rkXd4JZW1UAuCvj9hoXPgpB2 kKdnL5oUrphAGBWoSVK3QNHwC1vqheA7SqDNCDbSeOkPbv+4p9mX/j0InIVG3xOl HAbnR/scuNQTdKOYnBA/HU2JRm/bdoIGScZ5zn/7Gxj/C6afK4OK0oaP2m6IvXKV -----END RSA PRIVATE KEY----- adsaria@ubuntu:~/tmp$ adsaria@ubuntu:~/tmp$ openssl rsa -in adsaria_private.pem -pubout -out adsaria_public.pem Enter pass phrase for adsaria_private.pem: password writing RSA key adsaria@ubuntu:~/tmp$ adsaria@ubuntu:~/tmp$ ls adsaria_private.pem adsaria_public.pem adsaria@ubuntu:~/tmp$ adsaria@ubuntu:~/tmp$ cat adsaria_public.pem -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw7n3Oo1qekaWhnD5GRuj bv/mB1/J/brdf3K0HKARGdph1mPmYDUNr/y+4meHvfqyAMpe/eK2O20F19N7EFxx PicCG1LxKB6v9LZCQlvRRixEEQokN+2Xv+xv07m4iWPZNPWmZXrngoP8eeBfAuNF oS5UtBCVY/t6sTsleLZbvGIoadCXZryDm1UepmW44DRMj1Em5Oncn2LL98f2wGRA zBB9vm63jtEAB+0Jr3C0GvAypmck5e5wgQ2TepJ6MhO9Y1oeieTguYL41uEuh8/j W8B+EC0v2Vtmkx1+elOBnwx+w/Iw9GHTotYkhetOunKsSOB0Qev/CqrQZ6CVzmh1 owIDAQAB -----END PUBLIC KEY----- adsaria@ubuntu:~/tmp$
■ 応用例1:メールアドレスを暗号化して送る
先ずは公開鍵暗号方式の基本である、公開鍵で暗号化してデータを送り、秘密鍵で復号する例。ここではメールを他の誰にも知られないで私に送る例。
まず、私の公開鍵で暗号化する:
$ echo "name@address" | openssl rsautl -encrypt -pubin -inkey adsaria_public.pem | base64 > address.cry $ cat address.cry wbxEvimBRSXehlhKCpuoSzSbxItWVsFmIsWtaQAH2OfYWKCePilpfXf8IeV8x7N9/mX5JJhd5aU2 WRsjrWwZRRp2PBm6mi4GPd47Q73mwVvelEKZHgTS15n0PQ3DzAJoohFadJheF5HLcjvZ8Jc+fam1 1iq67rrmTfIQ+OxzQrYqCvd2RluRbgCZUYslfGIH8bIizy7ezQvKFxDoDuuza2+SDxnThhZnfA9N Or9SFaoMnA75nQsTMvKO9HFuSVdTIQTJo7IXbnsFF/M2G87TwvLy9Llyca4aipZY5mB+UQLPVkth 9eR3W08BciZuepu9bUFx5NJ4MQUjrsHT5MoJPw==
(opensslで生成する暗号ファイルはバイナリなのでここではbase64でASCIIデータに直している。)
このaddress.cryというファイルを送ってもらい、私の秘密鍵で復号する。
$ base64 -d address.cry | openssl rsautl -decrypt -inkey adsaria_private.pem Enter pass phrase for adsaria_private.pem: password name@address
■ 応用例2:ファイルに署名する(秘密鍵で暗号化する)
秘密鍵で暗号化する場合は“-encrypt”ではなく“-sign”を使う。まず、改ざんされては困るファイルのハッシュ値をmd5sumで計算して、それに対して暗号化する。
$ md5sum important 295402db735cb1096b0ad784f41d5819 important $ md5sum important | cut -f1 -d" " | openssl rsautl -sign -inkey adsaria_private.pem | base64 > important.sig Enter pass phrase for adsaria_private.pem: password $ cat important.sig EIjSHr/oNLgG0PZa7DhfIn6O0TiMhk6sg53PIDa8Kjxc+vEW+R2Y0BAoB9Ew9+4P0SrYYM04haiR XQOX4NEK1pJ45c17DpzEClFh9K3gzhD4HRhGprKlQugib428L6i4SFQk791mj7R+LLmRBXAJ0+9x hTF9pUchB3oa2aGMtMVMeCEGH4EFPZN5GGPUty3TU8hGnHIwJHBW2fRcFhoitWVPC7XoYZhKkCEd yh5UXNYWqDeE0VSvZr3BLFpk2Rgjy8Qcn41nvQkD11WbbO3nTwQUCvSc2cdrgjhDJEkbV7MqbYTl FbTg96wvu24SzyAMLCvTppWJtVH6jX7Y+Eg4/w==
ここでは大切なファイルを“important”とし、そのファイルに対する署名を“important.sig”として生成している。この2つを送って、受け取った人は署名ファイルを私の公開鍵で復号する。その場合は“-decrypt”ではなく、“-verify”を使う。
$ base64 -d important.sig | openssl rsautl -verify -pubin -inkey adsaria_public.pem 295402db735cb1096b0ad784f41d5819
これは“画像データとしてプログラムを保存する”といった使い方に応用できる。