"Length of the data to decrypt is invalid." exception during Rijndael decryption - exception

I get "Length of the data to decrypt is invalid." exception when i try to decrypt a memory stream. I am beginner, cant figure out whats wrong. whats wrong?
public bool EncryptStream()
{
string password = #"myKey123"; // Your Key Here
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
s_EncryptedStream = new MemoryStream();
int NoOfBytes;
byte[] b_Buffer = new byte[8192];
s_MemoryStream.Seek(0, SeekOrigin.Begin);
RijndaelManaged RMCrypto = new RijndaelManaged();
s_CrytpoStream = new CryptoStream(s_EncryptedStream,
RMCrypto.CreateEncryptor(key, key),
CryptoStreamMode.Write);
while (s_MemoryStream.Length < s_MemoryStream.Position)
{
NoOfBytes = s_MemoryStream.Read(b_Buffer, 0, 8192);
s_CrytpoStream.Write(b_Buffer, 0, NoOfBytes);
}
s_MemoryStream.Seek(0, SeekOrigin.Begin);
while (s_EncryptedStream.Position < s_EncryptedStream.Length)
{
NoOfBytes = s_EncryptedStream.Read(b_Buffer, 0, 8192);
s_MemoryStream.Write(b_Buffer, 0, NoOfBytes);
}
s_CrytpoStream.Flush();
s_CrytpoStream.Close();
return true;
}
public bool DecryptStream()
{
string password = #"myKey123"; // Your Key Here
UnicodeEncoding UE = new UnicodeEncoding();
byte[] key = UE.GetBytes(password);
int NoOfBytes;
byte[] b_Buffer = new byte[8192];
s_DecryptedStream = new MemoryStream();
RijndaelManaged RMCrypto = new RijndaelManaged();
s_CrytpoStream = new CryptoStream(s_MemoryStream,
RMCrypto.CreateDecryptor(key, key),
CryptoStreamMode.Read);
s_MemoryStream.Seek(0, SeekOrigin.Begin);
while (s_MemoryStream.Length > s_MemoryStream.Position)
{
NoOfBytes = s_CrytpoStream.Read(b_Buffer, 0, 8192);
s_DecryptedStream.Write(b_Buffer, 0, NoOfBytes);
}
s_DecryptedStream.Seek(0, SeekOrigin.Begin);
s_MemoryStream.Seek(0, SeekOrigin.Begin);
while (s_DecryptedStream.Position < s_DecryptedStream.Length)
{
NoOfBytes = s_DecryptedStream.Read(b_Buffer, 0, 8192);
s_MemoryStream.Write(b_Buffer, 0, NoOfBytes);
}
s_CrytpoStream.Flush();
s_CrytpoStream.Close();
return true;
}

For a start, this while loop condition is never right:
while (s_MemoryStream.Length < s_MemoryStream.Position)
How can the position be beyond the length?
Rather than using the length of a stream, the usual pattern to copy a stream is to read repeatedly until the value returned isn't positive. As you're doing that twice in this code anyway, you might as well encapsulate it:
public static void CopyStream(Stream input, Stream output)
{
byte[] buffer = new byte[8192];
int read;
while ( (read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
}
It's also best to use using statements to clean up strings. Additionally, the Encoding.Unicode property means you don't have to create a new UnicodeEncoding yourself. Also, I generally find that setting the Position property is more readable than using Seek. Finally, there's no point in a method returning a value if it's always going to be true. So, your code would become:
public void EncryptStream()
{
string password = #"myKey123"; // Your Key Here
byte[] key = Encoding.Unicode.GetBytes(password);
s_EncryptedStream = new MemoryStream();
s_MemoryStream.Position = 0;
RijndaelManaged RMCrypto = new RijndaelManaged();
using (Stream crytpoStream = new CryptoStream(s_EncryptedStream,
RMCrypto.CreateEncryptor(key, key),
CryptoStreamMode.Write))
{
CopyStream(s_MemoryStream, cryptoStream);
}
s_MemoryStream.Position = 0;
s_EncryptedStream.Position = 0;
CopyStream(s_EncryptedStream, s_MemoryStream);
}
public void DecryptStream()
{
string password = #"myKey123"; // Your Key Here
byte[] key = Encoding.Unicode.GetBytes(password);
s_DecryptedStream = new MemoryStream();
s_MemoryStream.Position = 0;
RijndaelManaged RMCrypto = new RijndaelManaged();
using (Stream crytpoStream = new CryptoStream(s_MemoryStream,
RMCrypto.CreateDecryptor(key, key),
CryptoStreamMode.Read))
{
CopyStream(cryptoStream, s_DecryptedStream);
}
s_DecryptedStream.Position = 0;
s_MemoryStream.Position = 0;
CopyStream(s_DecryptedStream, s_MemoryStream);
}
Even after amending this code, it feels like you've got way too many non-local variables here. I can't see why any of this should be in instance variables. Make the stream to be encrypted or decrypted a parameter (along with the password) and return a memory stream with the encrypted/decrypted data in, or just a byte array.

You may need to call the FlushFinalBlock method on the CryptoStream after you have finished reading the input data. (ie. crytpoStream.FlushFinalBlock() after CopyStream)

I have come up with a solution and I have it posted on my new Blog
constotech.blogspot.com/2009/05/net-encryption-using-symmetricalgorithm.html

Related

Using Newtonsoft JsonConverter to Encrypt JSON object

I'm developing a project that will require me to include credentials for things like an SMTP server. I'd like to store this information along with the complete details of the endpoint in an embedded JSON file, but I would like to have that information encrypted and then let my application decrypt it when it needs to establish a connection and log in. The JSON structure looks something like this:
{
"Endpoints" : [
{
"Endpoint" : {
"Host": "smtp.mydomain.tld",
"Port": 587,
"Username": "user#mydomain.tld",
"Password": "mYp#s$w0?d"
}
}
]
}
While what I'd really like to have actually stored in the file would look something like this:
{
"Endpoints" : [
{
"Endpoint" : "<BASE64_ENCODED_STRING>"
}
]
}
Using Newtonsoft's Json.NET, I've built the class object/properties to desriealize this structure:
<JsonProperty("Endpoints")>
Public Property Endpoints As List(Of EndpointContainer) = Nothing
Public Class EndpointContainer
<EditorBrowsable(EditorBrowsableState.Never)> <DebuggerBrowsable(DebuggerBrowsableState.Never)>
Private Const EncryptedPrefix As String = "myappcipher:"
<EditorBrowsable(EditorBrowsableState.Never)> <DebuggerBrowsable(DebuggerBrowsableState.Never)>
<JsonProperty("Endpoint")> <JsonConverter(GetType(EndpointProtector))>
Public Property Endpoint As Endpoint = Nothing
End Class
And I've built the inherited JsonConverter class ("EndpointProtector") like this:
Public Class EndpointProtector
Inherits JsonConverter
Public Sub New()
Using SHAEncryption = New SHA256Managed()
_EncryptionKey = SHAEncryption.ComputeHash(Encoding.UTF8.GetBytes(TestEncryptionKey))
End Using
End Sub
Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
Dim clearText As String = JsonConvert.SerializeObject(value)
If clearText Is Nothing Then
Throw New ArgumentNullException(NameOf(clearText))
End If
writer.WriteValue(EncryptEndpoint(clearText))
End Sub
Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
Dim DecryptString As String = TryCast(reader.Value, String)
If String.IsNullOrEmpty(DecryptString) Then
Return reader.Value
ElseIf Not DecryptString.StartsWith(EncryptedPrefix, StringComparison.OrdinalIgnoreCase) Then
Return DecryptString
Else
Return DecryptEndpoint(DecryptString)
End If
End Function
Public Overrides Function CanConvert(objectType As Type) As Boolean
Throw New NotImplementedException()
End Function
End Class
Currently I have the JSON file itself with the full object definition (as in the first code block). When my application reads that JSON, it correctly moves to the overridden ReadJson() method I have, but the reader.Value is null (Nothing), so it never actually gets to the DecryptEndpoint() method. Of course, that means there's nothing to encrypt, so the application won't even step into the WriteJson() method.
I've tried a couple of variations, including making the Endpoint property into a private variable with a generic Object type, and then having a separate public property with the <JsonIgnore> decoration to "read" from that, but nothing seems to get me where I need to be. I'm sure I'm overlooking something here, but I can't seem to figure out why it's not getting anything at all.
I looked at a few other SO questions like Encrypt and JSON Serialize an object, but I've still not yet been able to figure out quite where I've gone wrong here.
NOTE: I intentionally didn't include the code for the EncryptEndpoint() or DecryptEndpoint() methods here simply because the code is never making it that far in the process. If you feel it's needed to fully answer the question, please let me know.
this is a linqpad example of working encrypt/decrypt base on JsonAttribute
void Main()
{
string str = "";
var t = new Test() { encName = "some long text some long text some long text", Name = "test" };
JsonSerializerSettings theJsonSerializerSettings = new JsonSerializerSettings();
theJsonSerializerSettings.TypeNameHandling = TypeNameHandling.None;
str = JsonConvert.SerializeObject(t, theJsonSerializerSettings).Dump();
JsonConvert.DeserializeObject<Test>(str, theJsonSerializerSettings).Dump();
}
public class Test
{
[JsonConverter(typeof(EncryptingJsonConverter))]
public string encName { get; set; }
public string Name { get; set; }
}
/// <summary>[JsonConverter(typeof(EncryptingJsonConverter), string 32byte array)]</summary>
public class EncryptingJsonConverter : JsonConverter
{
private readonly byte[] _encryptionKeyBytes;
private readonly string _encryptionKeyString;
///<summary>Key must be 32char length</summary>
public EncryptingJsonConverter()
{
string encryptionKey = "E546C8DF278CD5931069B522E695D4F2"; //get from config
if (string.IsNullOrEmpty(encryptionKey))
throw new ArgumentNullException(nameof(encryptionKey));
_encryptionKeyString = encryptionKey;
_encryptionKeyBytes = Convert.FromBase64String(encryptionKey);
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var stringValue = (string)value;
if (string.IsNullOrEmpty(stringValue))
{
writer.WriteNull();
return;
}
//string enc = stringValue.Encrypt(_encryptionKeyString);
string enc = Crypto.Encrypt(stringValue, _encryptionKeyBytes);
writer.WriteValue(enc);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var value = reader.Value as string;
if (string.IsNullOrEmpty(value))
return reader.Value;
try
{
//return value.Decrypt(_encryptionKeyString);
return Crypto.Decrypt(value, _encryptionKeyBytes);
}
catch
{
return string.Empty;
}
}
/// <inheritdoc />
public override bool CanConvert(Type objectType)
{
return objectType == typeof(string);
}
}
public static class Crypto
{
public static string Encrypt(this string text, string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentException("Key must have valid value.", nameof(key));
if (string.IsNullOrEmpty(text))
throw new ArgumentException("The text must have valid value.", nameof(text));
var buffer = Encoding.UTF8.GetBytes(text);
var hash = SHA512.Create();
var aesKey = new byte[24];
Buffer.BlockCopy(hash.ComputeHash(Encoding.UTF8.GetBytes(key)), 0, aesKey, 0, 24);
using (var aes = Aes.Create())
{
if (aes == null)
throw new ArgumentException("Parameter must not be null.", nameof(aes));
aes.Key = aesKey;
using (var encryptor = aes.CreateEncryptor(aes.Key, aes.IV))
using (var resultStream = new MemoryStream())
{
using (var aesStream = new CryptoStream(resultStream, encryptor, CryptoStreamMode.Write))
using (var plainStream = new MemoryStream(buffer))
{
plainStream.CopyTo(aesStream);
}
var result = resultStream.ToArray();
var combined = new byte[aes.IV.Length + result.Length];
Array.ConstrainedCopy(aes.IV, 0, combined, 0, aes.IV.Length);
Array.ConstrainedCopy(result, 0, combined, aes.IV.Length, result.Length);
return Convert.ToBase64String(combined);
}
}
}
public static string Decrypt(this string encryptedText, string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentException("Key must have valid value.", nameof(key));
if (string.IsNullOrEmpty(encryptedText))
throw new ArgumentException("The encrypted text must have valid value.", nameof(encryptedText));
var combined = Convert.FromBase64String(encryptedText);
var buffer = new byte[combined.Length];
var hash = new SHA512CryptoServiceProvider();
var aesKey = new byte[24];
Buffer.BlockCopy(hash.ComputeHash(Encoding.UTF8.GetBytes(key)), 0, aesKey, 0, 24);
using (var aes = Aes.Create())
{
if (aes == null)
throw new ArgumentException("Parameter must not be null.", nameof(aes));
aes.Key = aesKey;
var iv = new byte[aes.IV.Length];
var ciphertext = new byte[buffer.Length - iv.Length];
Array.ConstrainedCopy(combined, 0, iv, 0, iv.Length);
Array.ConstrainedCopy(combined, iv.Length, ciphertext, 0, ciphertext.Length);
aes.IV = iv;
using (var decryptor = aes.CreateDecryptor(aes.Key, aes.IV))
using (var resultStream = new MemoryStream())
{
using (var aesStream = new CryptoStream(resultStream, decryptor, CryptoStreamMode.Write))
using (var plainStream = new MemoryStream(ciphertext))
{
plainStream.CopyTo(aesStream);
}
return Encoding.UTF8.GetString(resultStream.ToArray());
}
}
}
public static string Encrypt(string text, byte[] key)
{
//string keyString = "encrypt123456789";
//var key = Encoding.UTF8.GetBytes(keyString);//16 bit or 32 bit key string
using (var aesAlg = Aes.Create())
{
using (var encryptor = aesAlg.CreateEncryptor(key, aesAlg.IV))
{
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
using (var swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(text);
}
var iv = aesAlg.IV;
var decryptedContent = msEncrypt.ToArray();
var result = new byte[iv.Length + decryptedContent.Length];
Buffer.BlockCopy(iv, 0, result, 0, iv.Length);
Buffer.BlockCopy(decryptedContent, 0, result, iv.Length, decryptedContent.Length);
return Convert.ToBase64String(result);
}
}
}
}
public static string Decrypt(string cipherText, byte[] key)
{
var fullCipher = Convert.FromBase64String(cipherText);
var iv = new byte[16];
var cipher = new byte[fullCipher.Length - iv.Length];//new byte[16];
Buffer.BlockCopy(fullCipher, 0, iv, 0, iv.Length);
Buffer.BlockCopy(fullCipher, iv.Length, cipher, 0, cipher.Length);
//var key = Encoding.UTF8.GetBytes(keyString);//same key string
using (var aesAlg = Aes.Create())
{
using (var decryptor = aesAlg.CreateDecryptor(key, iv))
{
string result;
using (var msDecrypt = new MemoryStream(cipher))
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (var srDecrypt = new StreamReader(csDecrypt))
{
result = srDecrypt.ReadToEnd();
}
}
}
return result;
}
}
}
}
to activate encryption just add a tag
[JsonConverter(typeof(EncryptingJsonConverter))]

How to insert uploaded image into varbinary(max) database column

I want process form submit and save jpg image into varbinary sql column.
I have code but it does not work properly, it is saving only empty bytes like 0x00...0000. So no errors are raised and database row is inserted successfully, but varbinary column seems to me corrupted.
The code is following
Models
public class FrontendModel
{
public HttpPostedFileBase Photo1 { get; set; }
}
public class SubmitModel
{
public byte[] ImageData { get; set; }
public decimal ImageSizeB { get; set; }
public SubmitModel
(
HttpPostedFileBase Photo
)
{
this.ImageData = new byte[Photo.ContentLength];
Photo.InputStream.Read(ImageData, 0, Convert.ToInt32(Photo.ContentLength));
this.ImageSizeB = Photo.ContentLength;
}
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(FrontendModel m)
{
using (var db = new ABC.Models.ABCDBContext())
{
using (var scope = new TransactionScope())
{
if (m.Photo1 != null && m.Photo1.ContentLength > 0)
db.InsertSubmit(new SubmitModel(m.Photo1));
scope.Complete();
}
}
return View(new FrontendModel());
}
DB Insert Function
public void InsertSubmit(SubmitModel m)
{
Database.ExecuteSqlCommand(
"spInsertSubmit #p1",
new SqlParameter("p1", m.ImageData),
);
}
SQL DB Procedure
CREATE PROCEDURE [dbo].[spInsertSubmit]
#ImageData VARBINARY(max)
AS
INSERT INTO dbo.Images (Image)
VALUES (#ImageData)
what am I doing wrong ? Thank you
PS:
I also tried something like this but it behave the same
using (var binaryReader = new BinaryReader(Photo.InputStream))
{
this.ImageData = binaryReader.ReadBytes(Photo.ContentLength);
}
then I tried
using (Stream inputStream = Photo.InputStream)
{
MemoryStream memoryStream = inputStream as MemoryStream;
if (memoryStream == null)
{
memoryStream = new MemoryStream();
inputStream.CopyTo(memoryStream);
}
ImageData = memoryStream.ToArray();
}
but error shows in calling DB function with error message, Parameter is not valid
i have the same problem as is mentioned here
File uploading and saving to database incorrectly
I found that when i assign Input stream to memory stream, the memory stream is empty ?!
Your procedure specifies that the parameter is called #ImageData but your code
Database.ExecuteSqlCommand(
"spInsertSubmit #p1",
new SqlParameter("p1", m.ImageData),
);
seems to be passing a parameter called #p1
Edit
Also I think that you have to specify the type explicitly when working with a byte array larger than 8k. See this link: Inserting a byte array larger than 8k bytes
Database.ExecuteSqlCommand(
"spInsertSubmit #p1",
new SqlParameter("#p1", SqlDbType.VarBinary) { Value = m.ImageData },
);
Ok i found a solution. This code works!
this.ImageData = new byte[streamLength];
Photo.InputStream.Position = 0;
Photo.InputStream.Read(this.ImageData, 0, this.ImageData.Length);
The line added is Photo.InputStream.Position = 0;

How to implement AES Encrypt (AesManaged Rfc2898DeriveBytes) in Windows Runtime

I met a blocking issue when I tried to immigrate my project from Windows Phone Silverlight 8.1 to Windows Runtime.
In Windows Runtime the AES-encrypted string is not the same as the one on Silverlight before.
In Silverlight:
public static string EncryptAES(string encryptString)
{
AesManaged aes = null;
MemoryStream ms = null;
CryptoStream cs = null;
string encryptKey = "testtest123";
string salt = "abcabcabcd";
try
{
Rfc2898DeriveBytes rfc2898 = new Rfc2898DeriveBytes(encryptKey, Encoding.UTF8.GetBytes(salt));
aes = new AesManaged();
aes.Key = rfc2898.GetBytes(aes.KeySize / 8);
aes.IV = rfc2898.GetBytes(aes.BlockSize / 8);
ms = new MemoryStream();
cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write);
byte[] data = Encoding.UTF8.GetBytes(encryptString);
cs.Write(data, 0, data.Length);
cs.FlushFinalBlock();
return Convert.ToBase64String(ms.ToArray());
}
catch
{
return encryptString;
}
finally
{
if (cs != null)
cs.Close();
if (ms != null)
ms.Close();
if (aes != null)
aes.Clear();
}
}
In Windows Runtime:
public static string EncryptAES(string plainText)
{
string pw = "testtest123";
string salt = "abcabcabcd";
IBuffer plainBuffer = CryptographicBuffer.ConvertStringToBinary(plainText, BinaryStringEncoding.Utf8);
IBuffer saltBuffer = CryptographicBuffer.ConvertStringToBinary(salt, BinaryStringEncoding.Utf8);
IBuffer pwBuffer = CryptographicBuffer.ConvertStringToBinary(pw, BinaryStringEncoding.Utf8);
KeyDerivationAlgorithmProvider keyDerivationProvider = Windows.Security.Cryptography.Core.KeyDerivationAlgorithmProvider.OpenAlgorithm(KeyDerivationAlgorithmNames.Pbkdf2Sha256);
// using salt and 1000 iterations
KeyDerivationParameters pbkdf2Parms = KeyDerivationParameters.BuildForPbkdf2(saltBuffer, 1000);
// create a key based on original key and derivation parmaters
CryptographicKey keyOriginal = keyDerivationProvider.CreateKey(pwBuffer);
IBuffer keyMaterial = CryptographicEngine.DeriveKeyMaterial(keyOriginal, pbkdf2Parms, 32);
CryptographicKey derivedPwKey = keyDerivationProvider.CreateKey(pwBuffer);
// derive buffer to be used for encryption salt from derived password key
IBuffer saltMaterial = CryptographicEngine.DeriveKeyMaterial(derivedPwKey, pbkdf2Parms, 16);
// display the buffers - because KeyDerivationProvider always gets cleared after each use, they are very similar unforunately
string keyMaterialString = CryptographicBuffer.EncodeToBase64String(keyMaterial);
string saltMaterialString = CryptographicBuffer.EncodeToBase64String(saltMaterial);
//AES_CBC_PKCS7
SymmetricKeyAlgorithmProvider symProvider = SymmetricKeyAlgorithmProvider.OpenAlgorithm("AES_CBC_PKCS7");
// create symmetric key from derived password key
CryptographicKey symmKey = symProvider.CreateSymmetricKey(keyMaterial);
// encrypt data buffer using symmetric key and derived salt material
IBuffer resultBuffer = CryptographicEngine.Encrypt(symmKey, plainBuffer, saltMaterial);
string result = CryptographicBuffer.EncodeToBase64String(resultBuffer);
return result;
}
In Silverlight Project, string "123456" encrypted by AES is "4UfdhC/0MFQlMhl7N7gqLg==";
While in Windows Runtime Project, the AES-encrypted string is "jxsR5EuhPXgRsHLs4N3EGQ=="
So how can I get the same string on WinRT as the one on Silverlight ?
The AES classes default to a random IV on the Microsoft runtimes. To get the same ciphertext you'll need to use a static IV. That's however not secure. Instead you should just check if you get the same key bytes and let the ciphertext differ for each run. Otherwise you can clearly distinguish identical plaintext.
You also seem to be using the wrong hash algorithm, Rfc2898DeriveBytes uses SHA-1 instead of SHA-256 as underlying hash function.
I've created class which works for me as replacement for System.Security.Cryptography.Rfc2898DeriveBytes:
public class Rfc2898DeriveBytes
{
private readonly string _password;
private readonly byte[] _salt;
public Rfc2898DeriveBytes(string password, byte[] salt)
{
_password = password;
_salt = salt;
IterationCount = 1000;
}
public uint IterationCount { get; set; }
public byte[] GetBytes(uint cb)
{
var provider = KeyDerivationAlgorithmProvider.OpenAlgorithm(KeyDerivationAlgorithmNames.Pbkdf2Sha1);
var buffSecret = CryptographicBuffer.ConvertStringToBinary(_password, BinaryStringEncoding.Utf8);
var buffsalt = CryptographicBuffer.CreateFromByteArray(_salt);
var keyOriginal = provider.CreateKey(buffSecret);
var par = KeyDerivationParameters.BuildForPbkdf2(buffsalt, IterationCount);
var keyMaterial = CryptographicEngine.DeriveKeyMaterial(keyOriginal, par, cb);
byte[] result;
CryptographicBuffer.CopyToByteArray(keyMaterial, out result);
return result;
}
}

Windows phone can't save CookieContainer

I apologize for my english :)
I catch cookies from server. And try to save it in order to use cookeis later.
var Settings = IsolatedStorageSettings.ApplicationSettings;
CookieContainer _Cookie = new CookieContainer()
_Cookie.Add(new Uri("http://www.portal.fa.ru/Job/SearchResultDiv"), response.Cookies);
Settings.Clear();
Settings["UserID"] = userID;
Settings["Cookie"] = _Cookie;
Settings.Save();
Ok it working. But after restart app cookie has losted. (Object has remain but cookies count = 0). I don't know.
So i try to convert from CookieContainer to array byte than save and load it when i need it.
public static byte[] ToByte(CookieContainer data)
{
byte[] CookieByte;
DataContractSerializer serializer = new DataContractSerializer(typeof(CookieContainer));
using (var memoryStream = new MemoryStream())
{
serializer.WriteObject(memoryStream, data);
CookieByte = memoryStream.ToArray();
}
return CookieByte;
}
public static CookieContainer FromByte(byte[] data)
{
CookieContainer Cookie;
DataContractSerializer serializer = new DataContractSerializer(typeof(CookieContainer));
using (var memoryStream = new MemoryStream(data))
{
Cookie = (CookieContainer)serializer.ReadObject(memoryStream);
}
return Cookie;
}
But this code did not work again. When i convert to byte and back i losing cookies (count = 0).
So what can i do?
PS write pls your code when you deal with authorization and cookies. Thx

Is there any Checksum like mechanism for JSON?

I need to upload large amount of JSON data to a webservice. Whats the best way to analyse that the server received the data correctly and all data is uploaded? Please let me know if anyone has any experience in this regards. Thanks.
You can check out my project :
https://github.com/hidayetcolkusu?tab=repositories
Calculation:
ChecksumCalculator checksumCalculator = new ChecksumCalculator();
string json = #"{""Name"":""Hidayet Raşit"",""Surname"":""ÇÖLKUŞU""}";
ushort checksum = checksumCalculator.Calculate(json);
Result: 43460
Comparing:
ChecksumCalculator checksumCalculator = new ChecksumCalculator();
string json = #"{""Name"":""Hidayet Raşit"",""Surname"":""ÇÖLKUŞU""}";
bool result = checksumCalculator.Compare(json, 43460);
Resut:true
Or
ChecksumCalculator checksumCalculator = new ChecksumCalculator();
string json = #"{""Name"":""Hidayet Raşit"",""Surname"":""ÇÖLKUŞU"",""Checksum"":43460}";
bool result = checksumCalculator.Compare(json);
Result:true
You can calculate json's hash value like this:
var sha1 = System.Security.Cryptography.SHA1.Create();
byte[] buf = System.Text.Encoding.UTF8.GetBytes(jsonString);
byte[] hash= sha1.ComputeHash(buf, 0, buf.Length);
var hashstr = System.BitConverter.ToString(hash).Replace("-", "");
You can calculate md5 to compare two json.
public static string CreateMD5(string json)
{
// Use json string to calculate MD5 hash
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(json);
byte[] hashBytes = md5.ComputeHash(inputBytes);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("X2"));
}
return sb.ToString();
}
}