Mono.Security.Cryptography RijndaelManaged class issue using CFB-8 mode - mono

I'm writing to report about cryptography issue. The problem happens using RijndaelManaged class from the System.Security.Cryptography. It is important for me to use RijndaelManaged with CFB-8 (FeedbackSize = 8) mode without padding (PaddingMode.None). Such settings configuration makes encrypted data size equal to the decrypted data size.
Unfortunately Mono (Mono Compiler for MVS2010 IDE v2.0.8152) compiled code throws exception on data encryption with message:
[Unhandled Exception: System.Security.Cryptography.CryptographicException: invalid block length at Mono.Security.Cryptography.SymmetricTransform.FinalEncrypt].
I made tests with the .NET framework 4.0 under Windows XP and Windows 7, using the native Visual Studio 2010 compiler. I found that the native Microsoft .NET compiler does not throw any exceptions, and the code example works well.
Below I have pasted two examples (Repro code), one for Mono which throws an exception and one for native C# compiler in this case there are no exceptions. Also I have also pasted links to online compilers to test the code.
Why is the Mono Compiler throwing this exception?
Mono code Sample (Online compiler for testing, Compile Online)
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
namespace Dela.Mono.Examples
{
public class HelloWorld
{
public static void Main(string[] args)
{
string plainText = "This will be encrypted.";
string plainText2 = "";
RijndaelManaged aesAlg = new RijndaelManaged();
aesAlg.BlockSize = 128;
aesAlg.KeySize = 256;
aesAlg.Mode = CipherMode.CFB;
aesAlg.FeedbackSize = 8;
aesAlg.Padding = PaddingMode.None;
aesAlg.GenerateKey();
aesAlg.GenerateIV();
ICryptoTransform encryptor = aesAlg.CreateEncryptor();
MemoryStream msEncrypt = new MemoryStream();
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) {
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) {
swEncrypt.Write(plainText);
}
}
Console.WriteLine(msEncrypt.ToArray().Length);
Console.WriteLine(System.Text.Encoding.UTF8.GetString(msEncrypt.ToArray()));
byte[] customArray = msEncrypt.ToArray();
ICryptoTransform decryptor = aesAlg.CreateDecryptor();
MemoryStream msDecrypt = new MemoryStream(customArray);
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) {
using (StreamReader swDecrypt = new StreamReader(csDecrypt)) {
plainText2 = swDecrypt.ReadToEnd();
}
}
Console.WriteLine(plainText2.Length);
Console.WriteLine(plainText2);
}
}
}
Native C# Code Sample (Online compiler for testing, Compile Online)
// Rextester.Program.Main is the entry point for your code. Don't change it.
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
string plainText = "This will be encrypted.";
string plainText2 = "";
RijndaelManaged aesAlg = new RijndaelManaged();
aesAlg.BlockSize = 128;
aesAlg.KeySize = 256;
aesAlg.Mode = CipherMode.CFB;
aesAlg.FeedbackSize = 8;
aesAlg.Padding = PaddingMode.None;
aesAlg.GenerateKey();
aesAlg.GenerateIV();
ICryptoTransform encryptor = aesAlg.CreateEncryptor();
MemoryStream msEncrypt = new MemoryStream();
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) {
using (StreamWriter swEncrypt = new StreamWriter(csEncrypt)) {
swEncrypt.Write(plainText);
}
}
Console.WriteLine(msEncrypt.ToArray().Length);
Console.WriteLine(System.Text.Encoding.UTF8.GetString(msEncrypt.ToArray()));
byte[] customArray = msEncrypt.ToArray();
ICryptoTransform decryptor = aesAlg.CreateDecryptor();
MemoryStream msDecrypt = new MemoryStream(customArray);
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) {
using (StreamReader swDecrypt = new StreamReader(csDecrypt)) {
plainText2 = swDecrypt.ReadToEnd();
}
}
Console.WriteLine(plainText2.Length);
Console.WriteLine(plainText2);
}
}
}

The bug was fixed. The sources can be taken from the mono GIT repository.
master: e094d3dc0cf186f1de32d5340d847dc18aeca0e2
mono-2-10: 98e4842eb19dfd60000ada19e9bfb265fad7c84b

Related

How does C# know the length of string using Binary Writer?

Please look at the code below. This program simply saves a 33-character-length string "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" with an additional byte value of "33".
using System.Text;
namespace Test
{
internal class Program
{
static void Main(string[] args)
{
string filepath = args[0];
using (var stream = File.Open(filepath, FileMode.Create))
{
using (var writer = new BinaryWriter(stream, Encoding.UTF8, false))
{
writer.Write(new string('!', 33));
writer.Write((byte)33);
}
}
using (var stream = File.Open(filepath, FileMode.Open))
{
using (var reader = new BinaryReader(stream, Encoding.UTF8, false))
{
Console.WriteLine(reader.ReadString());
Console.WriteLine(reader.ReadByte());
}
}
Console.ReadKey();
}
}
}
And here is the binary representation of it:
Apparently, the first starting "ox21" is the length of the string - but how on earth does C# know?

X509Certificate2.CreateFromCertFile() on .NET Core

I am trying to use X509Certificate2.CreateFromCertFile() method in an ASP.NET Core application, but it seems like it's not supported for .NET Core.
Is there an alternative way of creating an X509Certificate2 object from a cert/pfx file?
Maybe something like this?
public Certificate CreateFromCertFile()
{
string cerFile = #"c:\cer.txt";
string keyFile = #"c:\key.txt";
var cert = new X509Certificate2(cerFile);
cert.PrivateKey = CreateRSAFromFile(keyFile);
return cert;
}
private RSACryptoServiceProvider CreateRSAFromFile(string filename)
{
byte[] pvk = null;
using (var fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read))
{
pvk = new byte[fs.Length];
fs.Read(pvk, 0, pvk.Length);
}
var rsa = new RSACryptoServiceProvider();
rsa.ImportCspBlob(pvk);
return rsa;
}

transfer local database (SQILLIT) on the Web(internet) in xamarin cod C# for Android

I want to transfer my local database on the Web, Please help me.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using System.IO;
using Mono.Data.Sqlite;
using Java.IO;
namespace Forooshgah
{
class cls_Connection
{
private static string DatabaseName = "DB_Forooshgah.db3";
private static string path = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
private static string DatabaseNameEndofYear;
private static Java.IO.File _dirBackup = new Java.IO.File(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), "Do2ta/backup");
public static string getConnectionString()
{
string db = Path.Combine (path, DatabaseName);
return db;
}
public static SqliteConnection setConnection()
{
var databasePath = Path.Combine(path, DatabaseName);
//return new SqliteConnection(String.Format("Data Source={0};Password={1}", databasePath, "test"));
return new SqliteConnection(String.Format("Data Source={0};", databasePath));
}
This code is "Upload File using FTP"
protected void Upload(string dbpath)
{
try
{
// Get the object used to communicate with the server.
string url = "ftp://xxx.xxx.xxx.xxx/xxx/xxx";
FtpWebRequest request =(FtpWebRequest)WebRequest.Create(url);
request.Method = WebRequestMethods.Ftp.UploadFile;
request.UseBinary = true;
// This example assumes the FTP site uses anonymous logon.
request.Credentials = new NetworkCredential ("anonymous","someone#somesite.com");
FileStream file = File.OpenRead(dbpath);
byte[] buffer = new byte[file.Length];
file.Read (buffer, 0, (int)file.Length);
file.Close ();
Stream ftpStream = request.GetRequestStream ();
ftpStream.Write (buffer, 0, buffer.Length);
ftpStream.Close ();
FtpWebResponse response = (FtpWebResponse)request.GetResponse();
Console.WriteLine("Upload File Complete, status {0}", response.StatusDescription);
response.Close();
}
catch(Exception exc)
{
}
}

SerializeObject and DeserializeObject

I use this following code but it gives error
Service1.svc.cs
public static byte[] SerializeObject<T>(T obj)
{
using (MemoryStream ms = new MemoryStream())
{
using (XmlDictionaryWriter writer = XmlDictionaryWriter.CreateBinaryWriter(ms))
{
DataContractSerializer dcs = new DataContractSerializer(typeof(T));
dcs.WriteObject(writer, obj); writer.Flush();
return ms.ToArray();
}
}
}
client code Windows phone
public static T DeserializeObject<T>(byte[] xml)
{
using (MemoryStream memoryStream = new MemoryStream(xml))
{
using (XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(memoryStream, XmlDictionaryReaderQuotas.Max))
{
DataContractSerializer dcs = new DataContractSerializer(typeof(T));
return (T)dcs.ReadObject(reader);
}
}
}
I call this DeserializeObject from below code
void svc_Get_Conn(object send, GetConnCompletedEventArgs e)
{
CookieContainer con =DeserializeObject<CookieContainer>(e.Result);
}
This gives following error
Message = "Type 'System.Net.PathList' with data contract name 'PathList:http://schemas.datacontract.org/2004/07/System.Net' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using...
How to solve this?
CookieContainer can't be serializable. Check this workaround
cheers

How to merge PDFs into a PDF Portfolio?

I am looking for the functionality that creates PDF Portfolios:
The image shows the free adobe reader that can be downloaded from Adobe (duh!). When I open this particular PDF, I was surprised that it has all these Layout, Files and Attachment features. It is definitely not the normal "PDF merge". It is more like a package with multiple PDFs.
Can itextsharp do this? What is the search term for this PDF functionality?
The term you're looking for is PDF Portfolios. You can create PDFs like this with iTextSharp. Here are a couple of C# examples from the iText book:
Chapter16 - KubrickCollection
Chapter16 - KubrickMovies
If you choose to download the KubrickMovies result file, change the extension to ".pdf". Just noticed it now - will try and fix the error this weekend.
To generate pdf portfolio (using iTextSharp) first we need to create a collection, then store it.
Example read one pdf file, create from it a collection of 2 files hello.pdf,united_states.pdf finally store as Test.pdf
static void Main(string[] args)
{
Document pdfDoc = null;
FileStream fstr = null;
try
{
pdfDoc = new Document(PageSize.A4);
fstr = new FileStream("Test.pdf", FileMode.Create);
var pdfWriter = PdfWriter.GetInstance(pdfDoc, fstr);
pdfDoc.Open();
pdfDoc.Add(new Chunk());
PdfCollection collection = new PdfCollection(PdfCollection.TILE);
var filePath = #"somePDF.pdf";
var fileInfo = new FileInfo(filePath);
var pdfDictionary = new PdfDictionary();
pdfDictionary.Put(PdfName.Moddate, new PdfDate(fileInfo.LastWriteTime));
pdfWriter.Collection = collection;
PdfFileSpecification fileSpec = PdfFileSpecification.FileEmbedded(
pdfWriter,
filePath,
fileInfo.Name,
null
);
pdfWriter.AddFileAttachment("united_states.pdf", fileSpec);
fileSpec = PdfFileSpecification.FileEmbedded(pdfWriter, filePath, fileInfo.Name, null);
pdfWriter.AddFileAttachment("hello.pdf", fileSpec);
pdfDoc.Close();
}
finally
{
pdfDoc.Close();
pdfDoc = null;
fstr.Close();
}
}
Here is the simple sample to show how we can attach files to a new PDF file:
using System.Diagnostics;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace PDFAttachment
{
class Program
{
static void Main(string[] args)
{
using (var pdfDoc = new Document(PageSize.A4))
{
var pdfWriter = PdfWriter.GetInstance(pdfDoc, new FileStream("Test.pdf", FileMode.Create));
pdfDoc.Open();
pdfDoc.Add(new Phrase("Test"));
var filePath = #"C:\path\logo.png";
var fileInfo = new FileInfo(filePath);
var pdfDictionary = new PdfDictionary();
pdfDictionary.Put(PdfName.MODDATE, new PdfDate(fileInfo.LastWriteTime));
var fs = PdfFileSpecification.FileEmbedded(pdfWriter, filePath, fileInfo.Name, null, true, null, pdfDictionary);
pdfWriter.AddFileAttachment("desc.", fs);
}
Process.Start("Test.pdf");
}
}
}
Or to an existing PDF file:
using System.Diagnostics;
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace PDFAttachment
{
class Program
{
static void Main(string[] args)
{
var reader = new PdfReader("Test.pdf");
using (var stamper = new PdfStamper(reader, new FileStream("newTest.pdf", FileMode.Create)))
{
var filePath = #"C:\path\logo.png";
addAttachment(stamper, filePath, "desc.");
stamper.Close();
}
Process.Start("newTest.pdf");
}
private static void addAttachment(PdfStamper stamper, string filePath, string description)
{
var fileInfo = new FileInfo(filePath);
var pdfDictionary = new PdfDictionary();
pdfDictionary.Put(PdfName.MODDATE, new PdfDate(fileInfo.LastWriteTime));
var pdfWriter = stamper.Writer;
var fs = PdfFileSpecification.FileEmbedded(pdfWriter, filePath, fileInfo.Name, null, true, null, pdfDictionary);
stamper.AddFileAttachment(description, fs);
}
}
}