概要
環境変数から読み込んだ秘密鍵の文字列の改行コードがエスケープされてしまうことによって、秘密鍵としてパースできないときの文字列処理を共有します。
解決策
たとえば下記のような秘密鍵があったとき、
-----BEGIN RSA PRIVATE KEY-----
MIGrAgEAAiEAvnrd8LBnzAGxCW+i7KtVQSiTsssMtbwcs5styeKsn2kCAwEAAQIh
AKBF8glb5Xqa0cQG0ygg4hIFdipmvEJhiCuhX93krDCBAhEA51bAM0gFPvxyk9Xe
ioIOBQIRANLJEv4Xw7MwT7EEEARL5RUCEBa8bu1bUbCsDPK8nT+NoqUCEQCIzFCU
MY4j7BW8N3vBnhPlAhBgs4tSfe6RbpertixmCygk
-----END RSA PRIVATE KEY-----
環境変数に設定するときは下記のように改行コードを使って、文字列を1行にして設定すると思います。
-----BEGIN RSA PRIVATE KEY-----\nMIGrAgEAAiEAvnrd8LBnzAGxCW+i7KtVQSiTsssMtbwcs5styeKsn2kCAwEAAQIh\nAKBF8glb5Xqa0cQG0ygg4hIFdipmvEJhiCuhX93krDCBAhEA51bAM0gFPvxyk9Xe\nioIOBQIRANLJEv4Xw7MwT7EEEARL5RUCEBa8bu1bUbCsDPK8nT+NoqUCEQCIzFCU\nMY4j7BW8N3vBnhPlAhBgs4tSfe6RbpertixmCygk\n-----END RSA PRIVATE KEY-----\n
この1行にした秘密鍵をアプリケーション内で読み込むと、下記のようにバックスラッシュが2つになってしまいます。
"-----BEGIN RSA PRIVATE KEY-----\\nMIGrAgEAAiEAvnrd8LBnzAGxCW+i7KtVQSiTsssMtbwcs5styeKsn2kCAwEAAQIh\\nAKBF8glb5Xqa0cQG0ygg4hIFdipmvEJhiCuhX93krDCBAhEA51bAM0gFPvxyk9Xe\\nioIOBQIRANLJEv4Xw7MwT7EEEARL5RUCEBa8bu1bUbCsDPK8nT+NoqUCEQCIzFCU\\nMY4j7BW8N3vBnhPlAhBgs4tSfe6RbpertixmCygk\\n-----END RSA PRIVATE KEY-----\\n"
このまま秘密鍵オブジェクトを作成しようとすると、エラーになります。
OpenSSL::PKey::RSA.new(str)
=> OpenSSL::PKey::RSAError: Neither PUB key nor PRIV key: nested asn1 error
そこで、この2つのバックスラッシュを1つのバックスラッシュに置換することで、秘密鍵オブジェクを作成することができるようになります。
str.gsub(/\\n/, "\n")
=> "-----BEGIN RSA PRIVATE KEY-----\nMIGrAgEAAiEAvnrd8LBnzAGxCW+i7KtVQSiTsssMtbwcs5styeKsn2kCAwEAAQIh\nAKBF8glb5Xqa0cQG0ygg4hIFdipmvEJhiCuhX93krDCBAhEA51bAM0gFPvxyk9Xe\nioIOBQIRANLJEv4Xw7MwT7EEEARL5RUCEBa8bu1bUbCsDPK8nT+NoqUCEQCIzFCU\nMY4j7BW8N3vBnhPlAhBgs4tSfe6RbpertixmCygk\n-----END RSA PRIVATE KEY-----\n"
OpenSSL::PKey::RSA.new(str.gsub(/\\n/, "\n"))
=> #<OpenSSL::PKey::RSA:0x00007f9d7dd734e0>
もちろん、秘密鍵だけではなく、改行コードのバックスラッシュがエスケープされたすべての文字列に対しても同様の解決策が有効です。