Finché l'oggetto è contrassegnato come serializzabile, un modo per convertire un oggetto in un array di byte consiste nell'utilizzare la classe BinaryFormatter in .Net.
Sarà necessario aggiungere questo using al file di codice:
using System.Runtime.Serialization.Formatters.Binary;
Un formattatore binario può produrre la classe in un flusso. Poiché si intende convertire l'oggetto in un array di byte, è possibile utilizzare System.IO.MemoryStream come memoria temporanea.
MemoryStream memStream = new MemoryStream();
È quindi possibile creare un nuovo formattatore binario.
BinaryFormatter formatter = new BinarryFomatter();
e utilizzare questo per serializzare l'oggetto.
formatter.Serialize(memStream, someObject);
Per ottenere i byte che è possibile utilizzare:
return memStream.ToArray();
per deserializzare l'array di byte è necessario scrivere i byte a un flusso di memoria.
memStream.Write(arrBytes, 0, arrBytes.Length);
Ritorno all'inizio del flusso.
memStream.Seek(0, SeekOrigin.Begin);
Quindi utilizzare il formattatore per ricreare l'oggetto.
Object obj = (Object)formatter.Deserialize(memStream);
Se si sta già utilizzando le funzioni di crittografia si dovrebbe essere in grado di crittografare l'array di byte creato abbastanza facilmente prima di riporla nel database.
Speriamo che questo ti aiuti nella giusta direzione. Se sei fortunato, gli oggetti BouncyCastle saranno contrassegnati come serializzabili, in caso contrario avrai bisogno di un po 'di codice aggiuntivo. Più tardi, avrò la possibilità di guardare i librerie di BouncyCastle per poterlo testare e pubblicherò altro codice se necessario.
... Non ho mai usato BouncyCastle prima. Dopo alcuni test, sembra che gli oggetti chiave pubblici e privati non siano serializzabili, quindi sarà necessario convertire questi oggetti in qualcosa che sia!
Sembra che le chiavi pubbliche e private espongano le proprietà come vari valori BouncyCastle.Math.BigInteger. (Le chiavi possono anche essere costruite da questi BigIntegers). Inoltre, BigIntegers ha una funzione ToByteArray() e può anche essere costruita da una matrice di byte. Molto utile ..
Sapendo che è possibile suddividere ogni chiave in BigIntegers e questi a sua volta in un array di byte e che è possibile anche il contrario, è un modo per archiviarli tutti in un oggetto serializzabile. Ad esempio, una struttura o una classe semplice farebbe
[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;
}
Questo ci dà un paio di oggetti serializzabili facili da usare.
AsymmetricCipherKeyPair espone le chiavi pubbliche e private come oggetti AsymmetricKeyParameter. Per ottenere le proprietà più dettagliate è necessario lanciare questi per il seguente:
keyPair.Public a BouncyCastle.Crypto.Parameters.RsaKeyParameters keyPair.Private a BouncyCastle.Crypto.Parameters.RsaPrivateCrtKeyParameters
Il seguente funzioni convertirà questi ai struct a dichiarato in precedenza:
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;
}
Utilizzando il formattatore binario accennato in precedenza, siamo in grado di convertire gli oggetti serializzabili abbiamo appena creato a un array di byte.
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();
La desesiizzazione è quindi solo l'inversa come descritto in precedenza. Una volta che le strutture pubbliche o private sono state deserializzate, puoi utilizzare i contrasti di BouncyCastle per ricreare le chiavi. Queste funzioni lo dimostrano.
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;
}
Se è necessario ricreare la coppia di chiavi originale per qualsiasi motivo:
AsymmetricKeyParameter publ = (AsymmetricKeyParameter)recreateASymCipherPublicKey(cKeyPair.publicKey);
AsymmetricKeyParameter priv = (AsymmetricKeyParameter)recreateASymCipherPrivateKey(cKeyPair.privateKey);
AsymmetricCipherKeyPair keyPair = new AsymmetricCipherKeyPair(publ, priv);
Speriamo che tutto ha un senso! I campioni di codice dovrebbero aiutarti a raggiungere la tua strada.
Qualcuno ha qualche idea su questo? – TravisPUK