オブジェクトがシリアル化可能としてマークされている限り、オブジェクトをバイト配列に変換する1つの方法は、.NetのBinaryFormatterクラスを使用することです。
次のusingステートメントをコードファイルに追加する必要があります。
using System.Runtime.Serialization.Formatters.Binary;
バイナリフォーマッタは、クラスをストリームに出力できます。オブジェクトをバイト配列に変換する場合は、System.IO.MemoryStreamを一時ストレージとして使用できます。
MemoryStream memStream = new MemoryStream();
その後、新しいバイナリフォーマッタを作成できます。
BinaryFormatter formatter = new BinarryFomatter();
これを使用してオブジェクトをシリアル化します。
formatter.Serialize(memStream, someObject);
使用できるバイトを取得するには、次のようにします。
return memStream.ToArray();
バイト配列を逆シリアル化するには、バイトをメモリストリームに書き込む必要があります。
memStream.Write(arrBytes, 0, arrBytes.Length);
ストリームの最初に戻ります。
memStream.Seek(0, SeekOrigin.Begin);
次に、フォーマッタを使用してオブジェクトを再作成します。
Object obj = (Object)formatter.Deserialize(memStream);
すでに暗号化機能を使用している場合は、作成したバイト配列をデータベースに保存する前に非常に簡単に暗号化できるはずです。
うまくいけば、それは正しい方向にあなたを助けるでしょう。運が良ければ、BouncyCastleオブジェクトはシリアル化可能としてマークされますが、そうでない場合は、追加のコードが必要になります。後で、これをテストできるようにBouncyCastleライブラリを確認する機会があり、必要に応じてさらにコードを投稿します。
...私はこれまでBouncyCastleを使用したことがありません。いくつかのテストの結果、公開鍵オブジェクトと秘密鍵オブジェクトはシリアル化できないようです。そのため、これらのオブジェクトをシリアル化できるものに変換する必要があります。
公開鍵と秘密鍵は、プロパティをさまざまなBouncyCastle.Math.BigInteger値として公開しているようです。(キーはこれらのBigIntegerから作成することもできます)。さらに、BigIntegersにはToByteArray()関数があり、バイト配列から構築することもできます。非常に便利..
各キーをBigIntegerに分割し、これらをバイト配列に分割することができ、その逆も可能であることを知っているので、これらすべてをシリアル化可能なオブジェクトに格納する方法があります。単純な構造体またはクラスは、たとえば
[Serializable]
private struct CipherPrivateKey
{
public byte[] modulus;
public byte[] publicExponent;
public byte[] privateExponent;
public byte[] p;
public byte[] q;
public byte[] dP;
public byte[] dQ;
public byte[] qInv;
}
[Serializable]
private struct CipherPublicKey
{
public bool isPrivate;
public byte[] modulus;
public byte[] exponent;
}
これにより、使いやすいシリアル化可能なオブジェクトのペアが得られます。
AsymmetricCipherKeyPairは、公開キーと秘密キーをAsymmetricKeyParameterオブジェクトとして公開します。より詳細なプロパティを取得するには、これらを次のようにキャストする必要があります。
keyPair.PublicからBouncyCastle.Crypto.Parameters.RsaKeyParameterskeyPair.PrivateからBouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters
次の関数は、これらを以前に宣言された構造体に変換します。
private static CipherPublicKey getCipherPublicKey(Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters cPublic)
{
CipherPublicKey cpub = new CipherPublicKey();
cpub.modulus = cPublic.Modulus.ToByteArray();
cpub.exponent = cPublic.Exponent.ToByteArray();
return cpub;
}
private static CipherPrivateKey getCipherPrivateKey(Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters cPrivate)
{
CipherPrivateKey cpri = new CipherPrivateKey();
cpri.dP = cPrivate.DP.ToByteArray();
cpri.dQ = cPrivate.DQ.ToByteArray();
cpri.modulus = cPrivate.Modulus.ToByteArray();
cpri.p = cPrivate.P.ToByteArray();
cpri.privateExponent = cPrivate.Exponent.ToByteArray();
cpri.publicExponent = cPrivate.PublicExponent.ToByteArray();
cpri.q = cPrivate.Q.ToByteArray();
cpri.qInv = cPrivate.QInv.ToByteArray();
return cpri;
}
前述のバイナリフォーマッタを使用して、作成したばかりのシリアル化可能なオブジェクトをバイト配列に変換できます。
CipherPublicKey cpub = getCipherPublicKey((Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters)keypair.Public);
MemoryStream memStream = new MemoryStream();
BinaryFormatter formatter = new BinarryFomatter();
formatter.Serialize(memStream, cpub);
return memStream.ToArray();
その場合、欲求不満は前述のように逆になります。パブリック構造体またはプライベート構造体のいずれかを逆シリアル化したら、BouncyCastle構造体を使用してキーを再作成できます。これらの関数はこれを示しています。
private static Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters recreateASymCipherPublicKey(CipherPublicKey cPublicKey)
{
Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters key;
key = new Org.BouncyCastle.Crypto.Parameters.RsaKeyParameters(
cPublicKey.isPrivate,
createBigInteger(cPublicKey.modulus),
createBigInteger(cPublicKey.exponent));
return key;
}
private static Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters recreateASymCipherPrivateKey(CipherPrivateKey cPrivateKey)
{
Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters key;
key = new Org.BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters(
createBigInteger(cPrivateKey.modulus),
createBigInteger(cPrivateKey.publicExponent),
createBigInteger(cPrivateKey.privateExponent),
createBigInteger(cPrivateKey.p),
createBigInteger(cPrivateKey.q),
createBigInteger(cPrivateKey.dP),
createBigInteger(cPrivateKey.dQ),
createBigInteger(cPrivateKey.qInv));
return key;
}
何らかの理由で元のキーペアを再作成する必要がある場合:
AsymmetricKeyParameter publ = (AsymmetricKeyParameter)recreateASymCipherPublicKey(cKeyPair.publicKey);
AsymmetricKeyParameter priv = (AsymmetricKeyParameter)recreateASymCipherPrivateKey(cKeyPair.privateKey);
AsymmetricCipherKeyPair keyPair = new AsymmetricCipherKeyPair(publ, priv);
うまくいけば、それはすべて理にかなっています!コードサンプルは、途中で役立つはずです。