I have problem with reading from encrypted files. have 2 sources of files, one is Rapsberry PI (Java), the second is desktop appliaction (.Net 4.6.1).
When I'm creating a encrypted file on my device and then want to read it in my desktop app, there is no problem with decrypting and encoding to string.
In the same app I create the same file, adding next element to list in the file on each 5s. When I read the file in my app, I got Unexpected end when reading json. path error.
I have checked models and they are both the same and valid.
For encryption/decryption I'm using AES algorithm.
There is my code from my desktop app:
Writing data:
Aes myAes = Aes.Create();
myAes.Key = Encoding.ASCII.GetBytes("abcde");
byte[] roundtrip = EncryptStringToBytes_Aes(output, myAes.Key, myAes.IV);
DirectoryInfo info = new DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
string pathSave =info + "\\test.plkx";
using (FileStream sourceStream = new FileStream (pathSave , FileMode.Append))
{
sourceStream.Write(roundtrip, 0, roundtrip.Length);
};
The method byte[] EncryptStringToBytes_Aes(string plainText, byte[] Key, byte[] IV)
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.Mode = CipherMode.ECB;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
// Return the encrypted bytes from the memory stream.
return encrypted;
There is my reader:
byte[] data = null;
data = new byte[fileStream.Length];
fileStream.Position = 0;
fileStream.Read(data, 0, (int)fileStream.Length);
Aes myAes = Aes.Create();
myAes.Key = Encoding.ASCII.GetBytes("abcde");
byte[] roundtrip = DecryptStringFromBytes_Aes(data, myAes.Key, myAes.IV);
return new MemoryStream(roundtrip);
And byte[] DecryptStringFromBytes_Aes(byte[] cipherText, byte[] Key, byte[] IV) method:
byte[] plaintext = null;
using (Aes aesAlg = Aes.Create())
{
aesAlg.Mode = CipherMode.ECB;
aesAlg.Key = Key;
aesAlg.IV = IV;
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
using (MemoryStream msDecrypt = new MemoryStream())
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
{
csDecrypt.Write(cipherText, 0, cipherText.Length);
}
plaintext = msDecrypt.ToArray();
var ads = ASCIIEncoding.ASCII.GetString(plaintext);
//There I got exception
var ab = DeserializeStream(new MemoryStream(plaintext));
}
}
return plaintext;
DeserializeStream method:
public RecorderValueTest DeserializeStream(MemoryStream stream)
{
RecorderValueTest r = new RecorderValueTest();
using (BsonDataReader reader = new BsonDataReader(stream))
{
JsonSerializer serializer = new JsonSerializer();
r = serializer.Deserialize<RecorderValueTest>(reader);
}
return r;
}
edit
I have tried this:
xxx = new xxx
{
data = listRecord,
};
string output = JsonConvert.SerializeObject(plkx);
try
{
using (BsonDataReader reader = new BsonDataReader(new MemoryStream(Encoding.UTF8.GetBytes(output))))
{
JsonSerializer serializer = new JsonSerializer();
var r = serializer.Deserialize<xxx>(reader);
}
} catch (Exception exc)
{ }
and still get the same error while deserialization. JsonConvert.DeserializeObject<xxx>(plkx); also didn't work.
Related
Sonarlint is warning me a bout a critical security risk on my encrypt routines
I don't understand why it triggers the first aes.CreateEncryptor(aes.Key, aes.IV); but not the second
Sonar gives me an example on how to fix it, but if the IV is generated randomly, how do I get it back in the decrypt part ?
and why is the sonar example called Encrypt() and not generateRandomIV() ?
I found these on SO I believe
Can someone help me out?
public static string EncryptString(string plainText, string key)
{
byte[] iv = new byte[16];
byte[] array;
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
{
streamWriter.Write(plainText);
}
array = memoryStream.ToArray();
}
}
}
return Convert.ToBase64String(array);
}
public static string DecryptString(string cipherText, string key)
{
byte[] iv = new byte[16];
byte[] buffer = Convert.FromBase64String(cipherText);
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream(buffer))
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Read))
{
using (StreamReader streamReader = new StreamReader((Stream)cryptoStream))
{
return streamReader.ReadToEnd();
}
}
}
}
}
sonar example:
public byte[] Encrypt(byte[] key, byte[] data, MemoryStream target)
{
using var aes = new AesCryptoServiceProvider();
var encryptor = aes.CreateEncryptor(key, aes.IV); // aes.IV is automatically generated to random secure value
using var cryptoStream = new CryptoStream(target, encryptor, CryptoStreamMode.Write);
cryptoStream.Write(data);
return aes.IV;
}
I am trying to encrypt and decrypt a stream (a PDF document at base), but I am having issues with this. When I try to open the document after decryption and download, I get the error Failed to load the PDF document.
Do you know why this might be happening?
Here is the code for encryption:
public EncryptResult EncryptStream(Stream dataStream, bool reuseIV = false)
{
RijndaelManaged crypto = new RijndaelManaged();
crypto.Key = _key;
if (!reuseIV || _iv == null)
{
// make a copy of the current IV
_iv = crypto.IV;
}
else
{
// reuse the previous IV
crypto.IV = _iv;
}
var result = new EncryptResult() { IV = crypto.IV };
using (var encryptor = crypto.CreateEncryptor())
{
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
var byteArrayInput = new byte[dataStream.Length];
dataStream.Read(byteArrayInput, 0, byteArrayInput.Length);
csEncrypt.Write(byteArrayInput, 0, byteArrayInput.Length);
dataStream.Close();
result.Cipher = msEncrypt.ToArray();
msEncrypt.Flush();
msEncrypt.Position = 0;
return result;
}
}
}
}
and decryption:
public Stream DecryptStream(byte[] cipher, byte[] iv)
{
RijndaelManaged crypto = new RijndaelManaged();
crypto.Key = _key;
crypto.IV = iv;
crypto.Padding = PaddingMode.Zeros;
using (var decryptor = crypto.CreateDecryptor())
{
using (MemoryStream msDecrypt = new MemoryStream(cipher))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
var sOutputFilename = new MemoryStream();
var fsDecrypted = new StreamWriter(sOutputFilename);
fsDecrypted.Write(new StreamReader(csDecrypt).ReadToEnd());
sOutputFilename.Position = 0;
return sOutputFilename;
}
}
}
}
Thanks in advance.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
//var byteArrayInput = new byte[dataStream.Length];
//dataStream.Read(byteArrayInput, 0, byteArrayInput.Length);
//csEncrypt.Write(byteArrayInput, 0, byteArrayInput.Length);
dataStream.CopyTo(csEncrypt);
dataStream.Close();
//result.Cipher = msEncrypt.ToArray(); // not here - not flushed yet
//msEncrypt.Flush(); // don't need this
//msEncrypt.Position = 0;
}
result.Cipher = msEncrypt.ToArray();
return result;
}
and in the decryptor, get rid of all the StreamReader/StreamWriter stuff.
A PDF file is compressed, ie binary. But this is after the decryption so it can't be your error.
using (var decryptor = crypto.CreateDecryptor())
{
using (MemoryStream msDecrypt = new MemoryStream(cipher))
{
var outputStream = new MemoryStream();
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
csDecrypt.CopyTo(outputStream );
}
outputStream .Position = 0;
return outputStream ;
}
}
One issue is, you are likely encrypting excess bytes at the end of your stream, you need to work out how many bytes are read or use
Stream.CopyTo Method
Reads the bytes from the current stream and writes them to another
stream.
Hello Friendly OverFlowers:
I have a line of code in the bigger example that is not working:
plaintext = srDecrypt.ReadToEnd();
It reports an exception:
The input data is not a complete block.
I have:
1) Looked at Encodings
2) Verified Decrypt (args) were correct.
Oh the intention from the simple main was to get back the encrypted value from the decrypted value. The plaintext = line is in the Decryption portion.
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
namespace Encryptor
{
class Program
{
static void Main(string[] args)
{
CryptDecrypt cd = new CryptDecrypt(new Guid());
string s = cd.Encrypt("Password");
Console.WriteLine(s);
string t = cd.Decrypt(s);
Console.WriteLine(t);
Console.ReadKey();
}
}
public class CryptDecrypt
{
private byte[] Key;
private byte[] IV;
public CryptDecrypt(Guid keyBase)
{
string Hash = keyBase.ToString();
Key = Encoding.UTF8.GetBytes(Hash.Take(32).ToArray());
IV = Encoding.UTF8.GetBytes(Hash.Reverse().Take(16).ToArray());
}
public string Encrypt(string plainText)
{
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.IV = IV;
aesAlg.Key = IV;
aesAlg.Padding = PaddingMode.Zeros;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return Convert.ToBase64String(encrypted);
}
public string Decrypt(string inputStr)
{
// Check arguments.
if (inputStr == null || inputStr.Length <= 0)
throw new ArgumentNullException("cipherText");
byte[] cipherText = Encoding.UTF8.GetBytes(inputStr);
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.Padding = PaddingMode.Zeros;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
}
}
You have two errors. First is that you use IV as the Key in the Encrypt method, and second you forgot to convert back from Base64 before decrypting.
See the code amended to correct these problems.
void Main()
{
CryptDecrypt cd = new CryptDecrypt(new Guid());
string s = cd.Encrypt("Password");
Console.WriteLine(s);
string t = cd.Decrypt(s);
Console.WriteLine(t);
}
public class CryptDecrypt
{
private byte[] Key;
private byte[] IV;
public CryptDecrypt(Guid keyBase)
{
string Hash = keyBase.ToString();
Key = Encoding.UTF8.GetBytes(Hash.Take(32).ToArray());
IV = Encoding.UTF8.GetBytes(Hash.Reverse().Take(16).ToArray());
}
public string Encrypt(string plainText)
{
byte[] encrypted;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.IV = IV;
aesAlg.Key = Key; <- HERE
aesAlg.Padding = PaddingMode.Zeros;
// Create a decrytor to perform the stream transform.
ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for encryption.
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
//Write all data to the stream.
swEncrypt.Write(plainText);
swEncrypt.Flush();
}
encrypted = msEncrypt.ToArray();
}
}
}
return Convert.ToBase64String(encrypted);
}
public string Decrypt(string inputStr)
{
// Check arguments.
if (inputStr == null || inputStr.Length <= 0)
throw new ArgumentNullException("cipherText");
byte[] cipherText = Convert.FromBase64String(inputStr); <- HERE
// Declare the string used to hold
// the decrypted text.
string plaintext = null;
// Create an Aes object
// with the specified key and IV.
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = Key;
aesAlg.IV = IV;
aesAlg.Padding = PaddingMode.Zeros;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
}
I've been trying to understand encryption/decryption code of TripleDES for some days. And I have seen many codes in the google, and the code shown below is one of them.
static void Main(string[] args)
{
string original = "Here is some data to encrypt!";
TripleDESCryptoServiceProvider myTripleDES = new TripleDESCryptoServiceProvider();
byte[] encrypted = EncryptStringToBytes(original, myTripleDES.Key, myTripleDES.IV);
string encrypt = Convert.ToBase64String(encrypted);
string roundtrip = DecryptStringFromBytes(encrypted, myTripleDES.Key, myTripleDES.IV);
Console.WriteLine("encryted: {0}", encrypt);
Console.WriteLine("Round Trip: {0}", roundtrip);
Console.ReadLine();
}
static byte[] EncryptStringToBytes(string plainText, byte[] Key, byte[] IV)
{
byte[] encrypted;
using (TripleDESCryptoServiceProvider tdsAlg = new TripleDESCryptoServiceProvider())
{
tdsAlg.Key = Key;
tdsAlg.IV = IV;
ICryptoTransform encryptor = tdsAlg.CreateEncryptor(tdsAlg.Key, tdsAlg.IV);
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
{
swEncrypt.Write(plainText);
}
encrypted = msEncrypt.ToArray();
}
}
}
return encrypted;
}
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key, byte[] IV)
{
string plaintext = null;
using (TripleDESCryptoServiceProvider tdsAlg = new TripleDESCryptoServiceProvider())
{
tdsAlg.Key = Key;
tdsAlg.IV = IV;
ICryptoTransform decryptor = tdsAlg.CreateDecryptor(tdsAlg.Key, tdsAlg.IV);
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
return plaintext;
}
There is no error in the code. I works fine. But strangely I noticed that the plainText is never been encoded. There is no line like Encoding.Unicode.GetBytes(plainText); or Encoding.UTF8.GetBytes(plainText); or similar like that. So, my question is , how does (in the code) the plainText which is a string gets converted to the encrypted byte? Is there any work done inside the streams? If thats so then where and how? As far as I understood there is no such line in between the streams that converts the string to byte. So , How does the overall code is working without this basic transformation?
Update:
Is this code really a valid code?
You are sending the plaintext to the encryption stream in the line swEncrypt.Write(plaintext). This does the byte conversion.
The StreamWriter is doing the encoding. The constructor being used specifies UTF-8 encoding:
This constructor creates a StreamWriter with UTF-8 encoding without a
Byte-Order Mark (BOM)
I've been researching an issue I'm having while attempting to decrypt using the Rijndael C# libraries. I've tried several solutions that have been posted on here but none seem to work or apply.
The issue: I'm attempting to decrypt a HTTP Request that is sent from a piece of hardware. However, I'm not getting the HTTP request converted into the correct number of bytes that match my decryption methods( I Think this is the issue?).
Here is my code:
System.Text.Encoding enc = System.Text.Encoding.ASCII;
System.Text.Encoding req = System.Text.Encoding.ASCII;
if (curContext != null)
{
string decrypted = "";
int totalBytes = curContext.Request.TotalBytes;
StreamReader sr = new StreamReader(curContext.Request.InputStream);
string request = sr.ReadToEnd();
if (!String.IsNullOrEmpty(request))
{
using (RijndaelManaged myRijndael = new RijndaelManaged())
{
myRijndael.Mode = CipherMode.ECB;
myRijndael.Padding = PaddingMode.None;
byte[] key = enc.GetBytes(WebConfigurationManager.AppSettings["32B"].ToString());
myRijndael.KeySize = 256;
myRijndael.Key = key;
decrypted = DecryptStringFromBytes(req.GetBytes(request), myRijndael.Key);
}
}
}
And Decrypt method:
static string DecryptStringFromBytes(byte[] cipherText, byte[] Key)
{
using (RijndaelManaged rijAlg = new RijndaelManaged())
{
rijAlg.Key = Key;
rijAlg.Mode = CipherMode.ECB;
rijAlg.Padding = PaddingMode.None;
// Create a decrytor to perform the stream transform.
ICryptoTransform decryptor = rijAlg.CreateDecryptor();
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
}
On the srDecrypt.ReadToEnd() I get the error message stated in title.
I'm rather new to this so I'm not sure where I'm going wrong. Any advice would be appreciated. Thanks~!
"Stream to string to bytes" conversion sequence feels very wrong. Make sure you really need to do it instead of simply reading bytes from response.
Try this instead at the bottom of your Decrypt method:
int plainByteCount = int.MinValue;
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(cipherText))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
plainBytes = new byte[cipherText.Length];
plainByteCount = cryptoStream.Read(plainBytes, 0, plainBytes.Length);
}
}
string plainText = Encoding.UTF8.GetString(plainBytes, 0, plainByteCount);
return plainText;
I think I might have found your problem. According to the constructor for StreamReader, the default encoding is UTF8Encoding. Trying using the other constructor overload and pass in the ASCII encoding:
StreamReader sr = new StreamReader(
curContext.Request.InputStream, Encoding.ASCII);
string request = sr.ReadToEnd();