Decrypt serializable struct is not work
What is my error when trying to decrypt?
When calling DecrypToken shown this message:
An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll
Additional information: The input stream is not a valid binary format.
[EDIT]
Data now converted data back from the hex format.
Key and IV now is saved to reuse.
Now getting this error:
An unhandled exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll
Additional information: End of Stream encountered before parsing was completed.
The code:
using System; using System.Runtime.Serialization; using System.Runtime.Serialization.Formatters.Binary; using System.IO; using System.Security.Cryptography; namespace DecryptStruct { class Program { static byte[] theKey = null; static byte[] theIV = null; [Serializable] internal struct Token { public string user; public string host; public string now; } static string EncryptToken(string user, string host) { Token token = new Token(); token.user = user; token.now = DateTime.Now.ToString(); token.host = host; //serialize IFormatter form = new BinaryFormatter(); MemoryStream ser = new MemoryStream(); form.Serialize(ser, (object)token); //setup crypto Rijndael alg = Rijndael.Create(); alg.GenerateIV(); alg.GenerateKey(); //save keys theKey = alg.Key; theIV = alg.IV; //rewind stream ser.Position = 0; //encrypt MemoryStream enc = new MemoryStream(); CryptoStream cw = new CryptoStream(enc, alg.CreateEncryptor(), CryptoStreamMode.Write); cw.Write(ser.ToArray(), 0, (int)ser.Length); cw.FlushFinalBlock(); enc.Position = 0; //rewind byte[] benc = enc.ToArray(); string hex = Convert.ToBase64String(benc); cw.Close(); return hex; } static Token DecrypToken(string hex) { byte[] benc = Convert.FromBase64String(hex); MemoryStream enc = new MemoryStream(benc); //setup crypto Rijndael alg = Rijndael.Create(); alg.Key = theKey; alg.IV = theIV; CryptoStream cr = new CryptoStream(enc, alg.CreateDecryptor(), CryptoStreamMode.Read); IFormatter form = new BinaryFormatter(); MemoryStream ser = new MemoryStream(); form.Serialize(ser, (object)new Token()); byte[] buf = new byte[(int)ser.Length]; cr.Read(buf, 0, (int)ser.Length); MemoryStream unenc = new MemoryStream(buf); unenc.Position = 0; //deserialize Token tk = (Token)form.Deserialize(unenc); return tk; } static void Main(string[] args) { string enc = EncryptToken("username", "myhost"); Token token = DecrypToken(enc); } } }
You encode it in hex and transform it here:
byte[] benc = enc.ToArray();
string hex = BitConverter.ToString(benc);
cw.Close();
return hex.Replace("-", "");
But you don't do the reverse!
The GenerateIV()
and GenerateKey()
methods initialize the algorithm with a new, random IV and key respectively. You must use the exact same key and IV to decrypt the data as was used to encrypt it, but you're not storing the either value when you encrypt, and instead generate another (completely different) key/IV during your decrypt routine.
As another answer indicates, you're also forgetting to reverse the text encoding you use when encrypting. I would suggest using Convert.ToBase64String()
to convert the encrypted data to a string value, and Convert.FromBase64String()
to convert it back into a byte array when decrypting.
上一篇: 如何复制Java中的对象?
下一篇: 解密可串行结构不起作用