Пока объект помечен как сериализуемый, одним из способов преобразования объекта в байтовый массив является использование класса BinaryFormatter в .Net.
Вам необходимо добавить это с помощью оператора в ваш файл кода:
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. (Ключи также могут быть построены из этих BigIntegers). Кроме того, BigIntegers имеют функцию ToByteArray () и также могут быть построены из байтового массива. Очень полезно ..
Зная, что вы можете разбить каждый ключ на BigIntegers, а они, в свою очередь, на байтовый массив и что возможно и обратное, вы сможете хранить все это в сериализуемом объекте. Простая структура или класс будут делать, например,
[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 to BouncyCastle.Crypto.Parameters.RsaKeyParameters
keyPair.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);
Надеюсь, все это имеет смысл! Примеры кода должны помочь вам на вашем пути.