I have to use Aes encryption in our Xamarin PCL project. Our project uses the portable framework and not the standard so I can't use the new built in classes. I tried changing to the .NET Standard but ended up with countless errors and since I've never used it before, I figured I probably shouldn't make such a change now.
I thought this could be done using the PCLCrypto package but haven't been able to get it to work.
We currently support iOS and Android.
I'm trying to figure out how to convert the following code from our server side.
private static readonly byte[] CipherKey = ConvertHexStringToByteArray("some key");
static public string EncryptString(string originalPayload)
{
return Encrypt(originalPayload, CipherKey);
}
static private string Encrypt(string originalPayload, byte[] privateKey)
{
string encryptedPayload = "";
using (var aes = new AesCryptoServiceProvider()
{
Key = privateKey,
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7
})
{
var input = Encoding.UTF8.GetBytes(originalPayload);
aes.GenerateIV();
var iv = aes.IV;
using (var encrypter = aes.CreateEncryptor(aes.Key, iv))
using (var cipherStream = new MemoryStream())
{
using (var tCryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write))
using (var tBinaryWriter = new BinaryWriter(tCryptoStream))
{
//Prepend IV to data
cipherStream.Write(iv, 0, iv.Length); //Write iv to the plain stream (not tested though)
tBinaryWriter.Write(input);
tCryptoStream.FlushFinalBlock();
}
encryptedPayload = Convert.ToBase64String(cipherStream.ToArray());
}
}
return encryptedPayload;
}
static public string DecryptString(string data)
{
return DecryptString(Convert.FromBase64String(data), CipherKey);
}
static private string DecryptString(byte[] encryptedString, byte[] encryptionKey)
{
using (var provider = new AesCryptoServiceProvider())
{
provider.Key = encryptionKey;
provider.Mode = CipherMode.CBC;
using (var ms = new MemoryStream(encryptedString))
{
// Read the first 16 bytes which is the IV.
byte[] iv = new byte[16];
ms.Read(iv, 0, 16);
provider.IV = iv;
using (var decryptor = provider.CreateDecryptor())
{
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
return sr.ReadToEnd();
}
}
}
}
}
}
Update
I found some code using PCLCrypto but can't get it working right. The decrypted string turns out to be squares.
Here's what I'm trying to use to decrypt the string from the server.
public static string DecryptAes(byte[] data, byte[] key)
{
ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithmName.Aes,
SymmetricAlgorithmMode.Cbc, SymmetricAlgorithmPadding.None);
ICryptographicKey symetricKey = aes.CreateSymmetricKey(key);
string returnValue = "";
using (var ms = new MemoryStream(data))
{
// Read the first 16 bytes which is the IV.
byte[] iv = new byte[16];
ms.Read(iv, 0, 16);
using (var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symetricKey, iv))
{
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
returnValue = sr.ReadToEnd();
}
}
}
}
return returnValue;
}
I was able to get it working. Here's the code in case someone runs into the same issue.
static public string Encrypt(string originalPayload, byte[] privateKey)
{
string encryptedPayload = "";
ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
ICryptographicKey symetricKey = aes.CreateSymmetricKey(privateKey);
var iv = WinRTCrypto.CryptographicBuffer.GenerateRandom(aes.BlockLength);
var input = Encoding.UTF8.GetBytes(originalPayload);
using (var encrypter = WinRTCrypto.CryptographicEngine.CreateEncryptor(symetricKey, iv))
{
using (var cipherStream = new MemoryStream())
{
using (var tCryptoStream = new CryptoStream(cipherStream, encrypter, CryptoStreamMode.Write))
using (var tBinaryWriter = new BinaryWriter(tCryptoStream))
{
//Prepend IV to data
cipherStream.Write(iv, 0, iv.Length); //Write iv to the plain stream (not tested though)
tBinaryWriter.Write(input);
tCryptoStream.FlushFinalBlock();
}
encryptedPayload = Convert.ToBase64String(cipherStream.ToArray());
}
}
return encryptedPayload;
}
public static string DecryptAes(byte[] data, byte[] key)
{
ISymmetricKeyAlgorithmProvider aes = WinRTCrypto.SymmetricKeyAlgorithmProvider.OpenAlgorithm(SymmetricAlgorithm.AesCbcPkcs7);
ICryptographicKey symetricKey = aes.CreateSymmetricKey(key);
string returnValue = "";
using (var ms = new MemoryStream(data))
{
// Read the first 16 bytes which is the IV.
byte[] iv = new byte[16];
ms.Read(iv, 0, 16);
using (var decryptor = WinRTCrypto.CryptographicEngine.CreateDecryptor(symetricKey, iv))
{
using (var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
using (var sr = new StreamReader(cs))
{
returnValue = sr.ReadToEnd();
}
}
}
}
return returnValue;
}
Related
I have around 100 files in a container . I want to call a function to zip all files and send it to another container . I am using the Azure.Storage.Blobs version 12.9.1
var blob = container.GetBlockBlobReference(outputFilename);
using (var stream = await blob.OpenWriteAsync())
using (var zip = new ZipArchive(stream, ZipArchiveMode.Create))
{
for (int i = 0; i < 2000; i++)
{
using (var randomStream = CreateRandomStream(2))
{
var entry = zip.CreateEntry($"{i}.zip", CompressionLevel.Optimal);
using (var innerFile = entry.Open())
{
await randomStream.CopyToAsync(innerFile);
}
}
}
}
This is for the older version . How can we achieve it using the new sdk
Can you please try with this code.
Solution 1: Try this code to generate Zip file. After generating zip file upload it to container
public void ZipFilesToResponse(HttpResponseBase response, IEnumerable<Asset> files, string zipFileName)
{
using (var zipOutputStream = new ZipOutputStream(response.OutputStream))
{
zipOutputStream.SetLevel(0); // 0 - store only to 9 - means best compression
response.BufferOutput = false;
response.AddHeader("Content-Disposition", "attachment; filename=" + zipFileName);
response.ContentType = "application/octet-stream";
foreach (var file in files)
{
var entry = new ZipEntry(file.FilenameSlug())
{
DateTime = DateTime.Now,
Size = file.Filesize
};
zipOutputStream.PutNextEntry(entry);
storageService.ReadToStream(file, zipOutputStream);
response.Flush();
if (!response.IsClientConnected)
{
break;
}
}
zipOutputStream.Finish();
zipOutputStream.Close();
}
response.End();
}
For more details refer this link
Solution 2:Also try with this code
using System;
using System.Threading.Tasks;
using Azure.Storage.Blobs;
using Azure.Storage.Blobs.Models;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
namespace SO68566758
{
class Program
{
private const string connectionString = "DefaultEndpointsProtocol=https;AccountName=account-name;AccountKey=account-key";
private const string sourceContainer = "source-container";
private const string targetContainer = "target-container";
private const string outputBlobName = "backup.zip";
static async Task Main(string[] args)
{
BlobServiceClient serviceClient = new BlobServiceClient(connectionString);
BlobContainerClient sourceContainerClient = serviceClient.GetBlobContainerClient(sourceContainer);
BlobContainerClient targetContainerClient = serviceClient.GetBlobContainerClient(targetContainer);
var blobs = sourceContainerClient.GetBlobsAsync();
using (var fs = new FileStream(outputBlobName, FileMode.OpenOrCreate))
{
using (var zipOutputStream = new ZipOutputStream(fs))
{
await foreach (var blob in blobs)
{
var blobName = blob.Name;
var blobClient = sourceContainerClient.GetBlobClient(blobName);
//var downloadResponse = await blobClient.DownloadAsync();
//var streamContent = downloadResponse.Value.Content;
var entry = new ZipEntry(blobName);
zipOutputStream.PutNextEntry(entry);
await blobClient.DownloadToAsync(zipOutputStream);
}
}
}
BlobClient targetBlob = targetContainerClient.GetBlobClient(outputBlobName);
using (FileStream fs = new FileStream(outputBlobName, FileMode.Open))
{
await targetBlob.UploadAsync(fs);
}
}
}
}
I have tried to read IMB barcode from an image with the below code snippet, but it always return null. I have also tried with the IMB barcode images in the blackbox testing below, but doesn't work.
https://github.com/micjahn/ZXing.Net/tree/master/Source/test/data/blackbox/imb-1
private static void Decode()
{
Bitmap bitmap = new Bitmap(#"\07.png");
try
{
MemoryStream memoryStream = new MemoryStream();
bitmap.Save(memoryStream, ImageFormat.Bmp);
byte[] byteArray = memoryStream.GetBuffer();
ZXing.LuminanceSource source = new RGBLuminanceSource(byteArray, bitmap.Width, bitmap.Height);
var binarizer = new HybridBinarizer(source);
var binBitmap = new BinaryBitmap(binarizer);
IMBReader imbReader = new IMBReader();
Result str = imbReader.decode(binBitmap);
}
catch { }
}
I have solved this problem by using the below code snippet shared through the below link.
https://github.com/micjahn/ZXing.Net/issues/59
private static void Decode2()
{
var bitmap = new Bitmap(#"\07.png"); // make sure that the file exists at the root level
try
{
var imbReader = new BarcodeReader
{
Options =
{
PossibleFormats = new List<BarcodeFormat> {BarcodeFormat.IMB}
}
};
var result = imbReader.Decode(bitmap);
if (result != null)
System.Console.WriteLine(result.Text);
else
System.Console.WriteLine("nothing found");
}
catch (System.Exception exc)
{
System.Console.WriteLine(exc.ToString());
}
}
Using image handler to convert relative path to absolute.
protected byte[] ConvertHTMLToPDF(string HTMLCode)
{
if (Request.Url == null)
throw new Exception();
var doc = new Document(PageSize.A4);
doc.Open();
var interfaceProps = new Hashtable();
var ih = new ImageHander {BaseUri = Request.Url.ToString()};
interfaceProps.Add("img_provider", ih);
foreach (IElement element in HTMLWorker.ParseToList(new StringReader(HTMLCode), null, interfaceProps))
{
doc.Add(element);
}
var _xmlr = new XmlTextReader(new StringReader(HTMLCode));
HtmlParser.Parse(doc, _xmlr);
var stream = new MemoryStream();
PdfWriter.GetInstance(doc, stream);
doc.Close();
return stream.ToArray();
}
class:
public class ImageHander : IImageProvider
{
public string BaseUri;
public Image GetImage(string src, Hashtable h, ChainedProperties cprops, IDocListener doc)
{
string imgPath;
if (src.ToLower().Contains("http://") == false)
imgPath = HttpContext.Current.Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + src;
else
imgPath = src;
return Image.GetInstance(imgPath);
}
}
imgPath at the end is correct. But it's not static file, it's url of action that returns image, so I need to pass cookies when requesting image. Is it possible?
Yes, it is possible, but you're gonna have to send the request yourself and not rely on the Image.GetInstance method. For example using the HttpClient you could send cookies along with the request:
var imageUrl = new Uri(imagePath);
var cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler { CookieContainer = cookieContainer })
using (var client = new HttpClient(handler))
{
cookieContainer.Add(
new Uri(imageUrl.GetLeftPart(UriPartial.Authority)),
new Cookie("CookieName", "cookie_value")
);
var response = client.GetAsync(imageUrl).Result;
response.EnsureSuccessStatusCode();
Stream imageStream = response.Content.ReadAsStreamAsync().Result;
// You've got the Stream here, read the documentation of iTextSharp
// how to create an Image instance from a Stream:
return Image.FromStream(imageStream); // ?????
// or maybe there's a method allowing you to create an Image from byte[]
byte[] imageData = new byte[imageStream.Length];
imageStream.Read(imageData, 0, imageData.Length);
return Image.FromByteArray(imageData); // ?????
}
I am using code I found in another question to compress an array of doubles and then test the size. I do this a huge number of times. Can I make this code more efficient?
public static byte[] Compress(byte[] bytData)
{
try
{
MemoryStream ms = new MemoryStream();
Stream s = new GZipStream(ms, CompressionMode.Compress);
s.Write(bytData, 0, bytData.Length);
s.Close();
byte[] compressedData = ms.ToArray();
return compressedData;
}
catch
{
return null;
}
}
static void Main(string[] args)
{
public List<double> B;
while (true)
{
datum = getNewDatum();
B.Insert(0, datum);
if (B.Count > 500)
B.RemoveAt(B.Count - 1);
byte[] byteArray = B.SelectMany(BitConverter.GetBytes).ToArray();
byte[] compressedData = Compress(byteArray);
//Console.WriteLine(compressedData.Length);
}
}
EDIT 1
Two areas might be able to be made faster:
The compression method.
How I am creating the byteArray in Main. Perhaps storing as a list of double and using SelectMany is not very efficient?
When it comes to optimization, I can propose a deterministic destruction and can rewrite as below,
public static byte[] Compress(byte[] bytData)
{
try
{
using (var ms = new MemoryStream())
{
using (var s = new GZipStream(ms, CompressionMode.Compress))
{
s.Write(bytData, 0, bytData.Length);
s.Close();
byte[] compressedData = ms.ToArray();
return compressedData;
}
}
}
catch
{
return null;
}
}
i have created some files in the IO
in the "car" files, i would like to put some other reference like model, color etc...
so my question is : is it possible to have a multi-lining files in the IO
if yes how can i get them in the streamreader
// i want to storage many parameters in a file and find them again with the streamreader
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
//reception des parametres de la listbox
base.OnNavigatedTo(e);
string parameter = this.NavigationContext.QueryString["parameter"];
this.tbTitre.Text = parameter;
try
{
//Create a new StreamReader
StreamReader editionDevisReader = null;
IsolatedStorageFile probyOrange = IsolatedStorageFile.GetUserStoreForApplication();
//Read the file from the specified location.
editionDevisReader = new StreamReader(new IsolatedStorageFileStream("devis\\"+parameter+".txt", FileMode.Open, probyOrange));
//Read the contents of the file .
string textFile = editionDevisReader.ReadLine();
//Write the contents of the file to the TextBlock on the page.
tbTitre.Text = textFile;
while (editionDevisReader != null)
{
RowDefinition rowdefinition = new RowDefinition();
TextBlock textblock = new TextBlock();
textblock.HorizontalAlignment = new System.Drawing.Size(48, 20);
}
editionDevisReader.Close();
}
catch
{
//If the file hasn't been created yet.
tbTitre.Text = "veuillez d abord creer le fichier";
}
thx a lot all
Yes, you can save anything (up to a point) in a file:
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
using (var isfs = new IsolatedStorageFileStream("myfile.txt", FileMode.OpenOrCreate, store))
{
using (var sw = new StreamWriter(isfs))
{
sw.Write("anything really. Here it's just a string but could be a serialized object, etc.");
sw.Close();
}
}
}
You can then read the file with:
var result = string.Empty;
try
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!store.FileExists("myfile.txt"))
{
return result;
}
using (var isfs = new IsolatedStorageFileStream("myfile.txt", FileMode.Open, store))
{
using (var sr = new StreamReader(isfs))
{
string lineOfData;
while ((lineOfData = sr.ReadLine()) != null)
{
result += lineOfData;
}
}
}
}
}
catch (IsolatedStorageException)
{
result = string.Empty; // may have partial data/file before error
}
return result;
You can use
StreamReader.Writeline
and
StreamRead.ReadLine
to write and read blocks of text seperated by line feeds.