Force.com(Apex)でJWTを使ってハマったこと


概要

  • Force.com(Salesforce.comのプラットフォーム)でWebAPIで使われるJWT(Json Web Token)を使う場面で秘密鍵ファイルの作り方がズレててハマったときのメモ
  • もう少し詳しく書くと、手順どおりに実装したつもりなのに謎エラーが発生して動かない→数時間かけて対処方法が分かったときのメモ

謎エラーメッセージ

System.SecurityException: Invalid Crypto Key

エラーになっている行の記述

  • アプリケーションからのパラメータである秘密鍵の電子署名を取得する、感じの記述と思われる
Blob x = Crypto.sign('RSA-SHA256', input, privateKeyBlob);

※force.comのApexはJavaに似た記述の言語です

公式のリファレンスページ

最終的に解決につながるページ

※Jeff氏はforce.com MVPの人っぽい
※6年前の2010年に解決していた

要するになんだったのか

  • 渡している秘密鍵のフォーマットが違うというエラー
  • PKCS #8フォーマットである必要がある
  • なんでハマるかって?APIコールの実装サンプルは載っているけど、そこで使う秘密鍵を作成するコマンドは載ってないから
    • 「pemファイルを準備する」という記述だと ssh-keygenopenssl genrsa で作ると思う

対処するためのコマンド

  • うまくいかなかった鍵ファイル=input.pem
  • 下記コマンドで生成された output.pem を使えばOK
$ openssl pkcs8 -topk8 -nocrypt -in input.pem -outform PEM -out output.pem

変更前後のpemファイルを比べてみる

変更前のpemファイル

-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAvmUhsJC9zK2VqGFFdb/AbM227wUhFHjWiVHLim5+CGyQgZvi
wjeObU0dbqLCD0Lr15yr6b9G0cv8zYrL/OjYqEkPj97LQ0/f0Qb3uGm+1rulC6UQ
(snip)
Q+YwQAFA182wiCN0a9sbFrpKeaLlP4BH7f1z1kKMAmVHShg7QaPV39yK2X0vlvHD
YRH2ap45+4GroiQQUBdtd/alnF9A4fKnN+2/Ck8glJnOGvLTOBcStx8=
-----END RSA PRIVATE KEY-----

変更後のpemファイル

  • ヘッダー、フッター部からRSAが消えている
  • (よくわからないけど)文字列部分ももちろん異なる。
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC+ZSGwkL3MrZWo
YUV1v8BszbbvBSEUeNaJUcuKbn4IbJCBm+LCN45tTR1uosIPQuvXnKvpv0bRy/zN
(snip)
gEft/XPWQowCZUdKGDtBo9Xf3IrZfS+W8cNhEfZqnjn7gauiJBBQF2139qWcX0Dh
8qc37b8KTyCUmc4a8tM4FxK3Hw==
-----END PRIVATE KEY-----