RSACryptoServiceProvider にて「指定された状態で使用するには無効なキーです。」

ref: Key not valid for use in specified state...what do you mean?
ref: novolocus.com - このウェブサイトは販売用です! -&nbspnovolocus リソースおよび情報
ref: RSACryptoServiceProvider.Encrypt Method (System.Security.Cryptography) | Microsoft Docs

System.Security.Cryptography.RSACryptoServiceProvider.Encrypt を使って byte[] を暗号化しようとしたときに、表題にある文言の CryptographicException が出てハマったのでメモ。

要するに

ref 先にあるとおり、この例外は暗号化しようとしているバイナリの長さが長すぎる場合に発生する。

ので、暗号化したいバイト列を長くしない必要がある。具体的には、鍵の長さ(RSACryptoServiceProvider.KeySize)から一定数を引いた長さを超えないようにする必要がある。具体的な長さは RSACryptoServiceProvider.Encrypt Method (System.Security.Cryptography) | Microsoft Docs を参照のこと。

憶測と感想

RSAアルゴリズムは、一度に暗号化・復号化できるソースの長さに鍵の長さに応じた限界がある*1

ここで、どうやら RSACryptoServiceProvider の Encrypt/Decrypt は、その限界を超えるソースを渡されたときの例外をちゃんと扱ってくれないようである。長さが足りないときはパディングを足してくれるので良いが、長すぎる場合には RSACryptoServiceProvider のラップしている CSP が発した例外がほぼそのまま露出しているので、このような結果になってしまうようだ。

が、それにしても、この例外の文言には惑わされた。すっかり ImportParameters なり FromXmlString なりの使い方に問題があるのかと思い込んでしまっていたのだが、よもやこのような原因であったとは。リンク先の

I was totally off the mark, this problem has nothing to do with keys, much unlike what the exception message reports.

には心から同意する所である。

*1:RSA のみならずとも、暗号アルゴリズムは、特定の長さのソースを扱うアルゴリズムになっていることが多い。