2015-05-28 2 views
9

OK, ho trovato alcuni articoli here e here, ma non stanno facendo esattamente quello che devo fare, e I ' sto incontrando qualche problema.MemoryStream a String, e ritorno a MemoryStream senza aggiungere alcun byte (codifica, ecc.)

Sto ricevendo un dato crittografato come un memorandtream. Ho bisogno di scrivere in qualche modo il memorystream in un file (il modo in cui ho scritto il mockup, come una stringa sarebbe il migliore), quindi recuperare la stringa dal file e inviarla, come un memorandtream, a un servizio da decifrare. Stavo solo usando uno streamreader per memorizzare il memorystream come una stringa, e stavo leggendo la stringa in memoria usando una codifica.

Il problema era che ho ricevuto un errore che diceva che i miei dati crittografati erano corrotti. Penso che questo significhi che ho cambiato i byte, in qualche modo.

ecco il codice che legge il MemoryStream in una stringa:

using (StreamReader reader = new StreamReader(dataKeyResponse.CiphertextBlob)) 
{ 
    encryptedDataKey = reader.ReadToEnd(); 
} 

E qui è il codice di lettura della stringa, recuperate dal file, in un MemoryStream:

MemoryStream mStream = new MemoryStream(ASCIIEncoding.Default.GetBytes(encryptedKey)); 

ho pensato che la passo che ha fatto è stato ASCIIEncoding, ma poi ho implementato the workaround from above, convertito l'array di byte in un memorystream, e ho ottenuto lo stesso errore.

byte[] bytes = new byte[encryptedKey.Length*sizeof (char)]; 
System.Buffer.BlockCopy(encryptedKey.ToCharArray(), 0, bytes, 0, bytes.Length); 

string decryptedKey; 
using (MemoryStream mStream = new MemoryStream()) 
{ 
    mStream.Write(bytes, 0, bytes.Length); 
    var decryptRequest = new DecryptRequest() 
    {CiphertextBlob = mStream}; 
    var decryptResponse = client.Decrypt(decryptRequest); 
    using (StreamReader reader = new StreamReader(decryptResponse.Plaintext)) 
    { 
     decryptedKey = reader.ReadToEnd(); 
    } 
} 

Io parto dal presupposto (1) che c'è qualcosa di modificare i dati in qualche modo e non qualche altro errore; (2) che è nello stream -> stringa o stringa -> transizione del flusso, e non nella stringa -> file o stringa < - transizione del file; e (3) che una copia perfetta dei dati in arrivo e in uscita risolverà il problema - i dati in arrivo dovrebbero essere una versione crittografata "in chiaro"; forse c'è un'aspettativa che io codifichi il flusso che entra e che esce (la codifica cambia anche i dati? Sto giudicando dal post che fa).

O una conferma che i byte dovrebbero essere equivalenti entrando ed uscendo, o un modo per catturare il memorystream in un file, e inviarlo di nuovo senza cambiare nulla sarebbe fantastico.

+4

Non salvare i dati binari (non di testo) come una stringa. Non ha senso. Tratta semplicemente come un flusso di byte. – Blorgbeard

+0

Ecco come salvare/caricare un memorandtream: http://stackoverflow.com/questions/8624071/save-and-load-memorystream-to-from-a-file – Blorgbeard

+0

Non è possibile memorizzare byte arbitrari come stringhe perché [le stringhe hanno regole ] (http://en.wikipedia.org/wiki/UTF-8#Invalid_byte_sequences) e byte arbitrari no. Devi codificare i byte in qualche modo (ad esempio Base64) o memorizzare byte non elaborati, non stringhe. –

risposta

8

Diciamo, che il MemoryStream contiene i seguenti dati di input: [0x01, 0x02, 0x03, 0x04] Quando si leggono con StreamReader, la rappresentazione binaria della stringa sarà: [0x00, 0x01, 0x00, 0x02 , 0x00, 0x03, 0x00, 0x04], perché le stringhe utilizzano una rappresentazione a due byte per un carattere. Quello che fai in seguito è di allocare 8 byte per la variabile "byte" anziché 4, e riempirlo con i secondi dati (modificati). È possibile utilizzare Convert.ToBase64String() per ottenere una rappresentazione di stringa, inoltre è possibile utilizzare FromBase64String() per analizzarlo indietro. Qualcosa del genere:

var testData = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 }; 
var inputStream = new MemoryStream(testData); 

var inputAsString = Convert.ToBase64String(inputStream.ToArray()); 
Console.WriteLine(inputAsString); 

var outputStream = new MemoryStream(Convert.FromBase64String(inputAsString)); 

var result = BitConverter.ToString(outputStream.ToArray());   
Console.WriteLine(result);