Calculate the MD5 hash from an online image - c#

I need to calculate the MD5 hash of an online image
For a locally saved image, I tried this code and it works as expected:
public static string GetHashFromFile(string fileName, HashAlgorithm algorithm)
{
HashAlgorithm MD5 = new MD5CryptoServiceProvider();
using (var stream = new BufferedStream(File.OpenRead(fileName), 100000))
{
return BitConverter.ToString(MD5.ComputeHash(stream)).Replace("-", string.Empty);
}
}
How can I get the BufferedStream of an online file?

Use the WebClient class to download the data from a given address. Use the downloaded bytes array to create a MemoryStream object to be the source stream of the BufferedStream object.
You have two ways to download:
1. The Synchronize Way
static string GetHashFromUrl(string url)
{
using (var wc = new WebClient())
{
var bytes = wc.DownloadData(url);
using (var md5 = new MD5CryptoServiceProvider())
using (var ms = new MemoryStream(bytes))
using (var bs = new BufferedStream(ms, 100_000))
return BitConverter.ToString(md5.ComputeHash(bs)).Replace("-", string.Empty);
}
}
... and a caller:
void TheCaller()
{
try
{
var hash = GetHashFromUrl(url);
//...
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
2. The Asynchronous Way
static async Task<string> GetHashFromUrlAsync(string url)
{
using (var wc = new WebClient())
using (var md5 = new MD5CryptoServiceProvider())
{
byte[] bytes = await wc.DownloadDataTaskAsync(url);
using (var ms = new MemoryStream(bytes))
using (var bs = new BufferedStream(ms, 100_000))
return BitConverter.ToString(md5.ComputeHash(bs)).Replace("-", string.Empty);
}
}
... and an async caller:
async void TheCaller()
{
try
{
var hash = await Task.Run(() => GetHashFromUrlAsync(url));
//...
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Both functions return the FA544EB95534BA35AE9D6EA0B3889934 hash for this photo which it's address is assigned to the url variable in the callers.

Related

Aspose.zip error Unexpected end of data corrupted error

I am trying to compress several excel files, but when generate the excel it generates corrupt. I don't know what could be any idea?
var Clients = getClients();
var carpetaUrl = string.Format(#"{0}/{1}/{2}.zip", IdCuenta, IdListado, "Folder");
try
{
using (MemoryStream zipFile = new MemoryStream())
{
using (var archive = new Archive())
{
foreach (var item in Clients)
{
var (fileUrl, stream) = GenerateFileExcel(item.archivoNombre,item.IdClient);
archive.CreateEntry(fileUrl, stream);
}
archive.Save(zipFile, new ArchiveSaveOptions() { Encoding = Encoding.ASCII });
}
var uri = B.Azure.Storages.UploadFile("tttt", zipFile, carpetaUrl, false).ToString();
return uri;
}

How to save audio from using Windows.Media.SpeechSynthesis?

I´m using Windows.Media.SpeechSynthesis for TTS and playing an audio signal works fine in my WPF application. I have wanted to save an audio signal but if I call StorageFolder I get an error: HRESULT: 0x80073D54 - The process has no package identity. How to fix it? The whole code is below. I would also like to know what rights apply to the use of an audio file from Win 10 TTS? I didn't find it anywhere - but I wasn't looking for that much...
private async void Talk(string text)
{
var stream = await speechSynthesizer.SynthesizeTextToStreamAsync(text);
StorageFolder localfolder = ApplicationData.Current.LocalFolder;
StorageFile sampleFile = await localfolder.CreateFileAsync("sample.wav", CreationCollisionOption.ReplaceExisting);
using (var reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
IBuffer buffer = reader.ReadBuffer((uint)stream.Size);
await FileIO.WriteBufferAsync(sampleFile, buffer);
}
}
Finally, I have found a solution, how to save a stream from tts into *.wav or to *.mp3 by Naudio. I don´t know if it is clear but it is functional:
public bool ByteArrayToFile(string fileName, byte[] byteArray)
{
try
{
using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
{
fs.Write(byteArray, 0, byteArray.Length);
return true;
}
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in process: {0}", ex);
return false;
}
}
private async Task SaveAudio(string text)
{
var stream = await speechSynthesizer.SynthesizeTextToStreamAsync(text);
using (var reader = new DataReader(stream))
{
await reader.LoadAsync((uint)stream.Size);
IBuffer buffer = reader.ReadBuffer((uint)stream.Size);
DataReader dataReader = DataReader.FromBuffer(buffer);
byte[] bytes = new byte[buffer.Length];
dataReader.ReadBytes(bytes);
//ByteArrayToFile("sample.wav", bytes);
ConvertWavStreamToMp3File(bytes, TB_File.Text);
MessageBox.Show("Audio was saved to file: " + TB_File.Text, "Info");
}
}
public static void ConvertWavStreamToMp3File(byte[] wavFile, string savetofilename)
{
using (var retMs = new MemoryStream())
using (var ms = new MemoryStream(wavFile))
using (var rdr = new WaveFileReader(ms))
using (var wtr = new LameMP3FileWriter(savetofilename, rdr.WaveFormat, LAMEPreset.VBR_90))
{
rdr.CopyTo(wtr);
}
}

Storing text file in Oracle DB as BLOB cuts off the end of the file

I'm generating a text file in a process which at the end loops through a list of strings that were fed to it, and through a MemoryStream and StreamWriter it converts that list to byte[]. The byte[] is then saved to an Oracle Database using a BLOB datatype. While it works for the majority of the data (typically thousands of lines. I've had anywhere between 5,000 and 40,000, and it's the same result regardless), I have a specific message that goes at the end, but it's always missing. Generally the last line that does end up in the file is cut off halfway.
The function that generates the byte[]:
public byte[] GenerateFileData()
{
var fileData = new byte[0];
using (var ms = new MemoryStream())
{
using (var sw = new StreamWriter(ms))
{
Messages.ForEach(x => sw.WriteLine(x)); // Messages is a list of strings in this class
fileData = ms.ToArray();
}
}
return fileData;
}
The function that saves the byte[] to the database:
public void SaveLogFile(int entityId, byte[] fileData)
{
using (var context = new SomeDBContext())
{
var entity= context.SomeEntity.FirstOrDefault(x => x.Id == runId);
if(entity != null)
{
entity.LOG_FILE = fileData;
context.SaveChanges();
}
}
}
And lastly, the function that turns the data into a file:
[HttpGet]
public FileResult GetLogFile(int id = 0)
{
var fileData = new byte[0];
using (var context = new SomeDbContext())
{
var entity = context.SomeEntity.FirstOrDefault(x => x.Id == id);
fileData = entity.LOG_FILE;
}
var fileName = "SomethingSomething" + id.ToString();
return File(fileData, "text/plain", fileName);
}
Try to get the MemoryStream content after the writer close asthis code:
public byte[] GenerateFileData()
{
var fileData = new byte[0];
using (var ms = new MemoryStream())
{
using (var sw = new StreamWriter(ms))
{
Messages.ForEach(x => sw.WriteLine(x)); // Messages is a list of strings in this class
}
ms.Flush();
fileData = ms.ToArray();
}
return fileData;
}

Why is it that after I compress a string, save it to SQL Server, then retrieve it, the data looks different?

I have an XML Audit log which is represented by a string in my c# code. I wanted to save this to my database as bytes to reduce the size of a table. When I use my code to compress/decompress the string and show it in C#, the audit log shows correctly. However if I compress --> save to the database-->decompress, all I get is a blank string.
My code for compressing/decompressing:
private static byte[] ZipFile(string auditLog) {
var bytes = Encoding.UTF8.GetBytes(auditLog);
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(mso, CompressionMode.Compress)) {
//msi.CopyTo(gs);
CopyTo(msi, gs);
}
return mso.ToArray();
}
}
private static string UnzipFile(byte[] bytes) {
using (var msi = new MemoryStream(bytes))
using (var mso = new MemoryStream()) {
using (var gs = new GZipStream(msi, CompressionMode.Decompress)) {
//gs.CopyTo(mso);
CopyTo(gs, mso);
}
return Encoding.UTF8.GetString(mso.ToArray());
}
}
My code for retrieving from the database:
private void populateFromCursor(DbReader cursor, Job value) {
value.id = (int)(cursor.GetInt64(0));
value.functionId = cursor.GetString(1);
byte[] binaryAuditLog = (byte[]) cursor.GetDbValue(2);
string auditLog = UnzipFile(binaryAuditLog);
value.auditLog = auditLog;
}
In my table the column type is set as varbinary.

OpenPGP encryption with BouncyCastle

I have been trying to put together an in-memory public-key encryption infrastructure using OpenPGP via Bouncy Castle. One of our vendors uses OpenPGP public key encryption to encrypt all their feeds, and requires us to do the same, so I'm stuck with the technology and the implementation. So now I'm coding an OpenPGP encryption/ decryption toolkit for automating these feeds.
The examples at bouncycastle.org inexplicably default to writing encrypted data to and collecting keys from a file system; this is not what I want to do, so I've been trying to get everything stream-based.
I have gotten to the point where I can actually get my code to compile and run, but my encrypted payload is empty. I think I'm missing something silly, but after several days of trying this and that, I have lost the ability to objectively examine this.
My utility class contains these methods:
public static PgpPublicKey ImportPublicKey(
this Stream publicIn)
{
var pubRings =
new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(publicIn)).GetKeyRings().OfType<PgpPublicKeyRing>();
var pubKeys = pubRings.SelectMany(x => x.GetPublicKeys().OfType<PgpPublicKey>());
var pubKey = pubKeys.FirstOrDefault();
return pubKey;
}
public static Stream Streamify(this string theString, Encoding encoding = null)
{
encoding = encoding ?? Encoding.UTF8;
var stream = new MemoryStream(encoding.GetBytes(theString));
return stream;
}
public static string Stringify(this Stream theStream,
Encoding encoding = null)
{
encoding = encoding ?? Encoding.UTF8;
using (var reader = new StreamReader(theStream, encoding))
{
return reader.ReadToEnd();
}
}
public static byte[] ReadFully(this Stream stream)
{
if (!stream.CanRead) throw new ArgumentException("This is not a readable stream.");
var buffer = new byte[32768];
using (var ms = new MemoryStream())
{
while (true)
{
var read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
return ms.ToArray();
ms.Write(buffer, 0, read);
}
}
}
public static void PgpEncrypt(
this Stream toEncrypt,
Stream outStream,
PgpPublicKey encryptionKey,
bool armor = true,
bool verify = true,
CompressionAlgorithmTag compressionAlgorithm = CompressionAlgorithmTag.Zip)
{
if (armor) outStream = new ArmoredOutputStream(outStream);
var compressor = new PgpCompressedDataGenerator(CompressionAlgorithmTag.Zip);
outStream = compressor.Open(outStream);
var data = toEncrypt.ReadFully();
var encryptor = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, verify, new SecureRandom());
encryptor.AddMethod(encryptionKey);
outStream = encryptor.Open(outStream, data.Length);
outStream.Write(data, 0, data.Length);
}
My test method looks like this:
private static void EncryptMessage()
{
var pubKey = #"<public key text>";
var clearText = "This is an encrypted message. There are many like it but this one is cryptic.";
using (var stream = pubKey.Streamify())
{
var key = stream.ImportPublicKey();
using (var clearStream = clearText.Streamify())
using (var cryptoStream = new MemoryStream())
{
clearStream.PgpEncrypt(cryptoStream,key);
cryptoStream.Position = 0;
Console.WriteLine(cryptoStream.Stringify());
Console.WriteLine("Press any key to continue.");
}
}
Console.ReadKey();
}
The result I get looks like this:
-----BEGIN PGP MESSAGE-----
Version: BCPG C# v1.7.4114.6378
Press any key to continue.
Can someone tell me what I am doing wrong?
OK, I managed to get this working. There were several problems with this implementation. One problem was that certain things had to be done in order. Here is what seems to need to happen:
The raw data needs to be put into a PgpLiteralData object
The literal data needs to be encrypted.
The encrypted data needs to be compressed.
The compressed data (optionally) needs to be armored.
The underlying streams need to be closed in order of usage.
There should be a more elegant way to do this, but the streams used by the BouncyCastle library are all frustratingly one-way, and at several points, I needed to convert the stream to a byte array to get another part to work. I include the code I used and independently verified; if someone has a verifyably better way of doing this, I would be quite interested.
public static class OpenPgpUtility
{
public static void ExportKeyPair(
Stream secretOut,
Stream publicOut,
AsymmetricKeyParameter publicKey,
AsymmetricKeyParameter privateKey,
string identity,
char[] passPhrase,
bool armor)
{
if (armor)
{
secretOut = new ArmoredOutputStream(secretOut);
}
var secretKey = new PgpSecretKey(
PgpSignature.DefaultCertification,
PublicKeyAlgorithmTag.RsaGeneral,
publicKey,
privateKey,
DateTime.UtcNow,
identity,
SymmetricKeyAlgorithmTag.Cast5,
passPhrase,
null,
null,
new SecureRandom()
);
secretKey.Encode(secretOut);
if (armor)
{
secretOut.Close();
publicOut = new ArmoredOutputStream(publicOut);
}
var key = secretKey.PublicKey;
key.Encode(publicOut);
if (armor)
{
publicOut.Close();
}
}
public static PgpPublicKey ImportPublicKey(
this Stream publicIn)
{
var pubRings =
new PgpPublicKeyRingBundle(PgpUtilities.GetDecoderStream(publicIn)).GetKeyRings().OfType<PgpPublicKeyRing>();
var pubKeys = pubRings.SelectMany(x => x.GetPublicKeys().OfType<PgpPublicKey>());
var pubKey = pubKeys.FirstOrDefault();
return pubKey;
}
public static PgpSecretKey ImportSecretKey(
this Stream secretIn)
{
var secRings =
new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(secretIn)).GetKeyRings().OfType<PgpSecretKeyRing>();
var secKeys = secRings.SelectMany(x => x.GetSecretKeys().OfType<PgpSecretKey>());
var secKey = secKeys.FirstOrDefault();
return secKey;
}
public static Stream Streamify(this string theString, Encoding encoding = null)
{
encoding = encoding ?? Encoding.UTF8;
var stream = new MemoryStream(encoding.GetBytes(theString));
return stream;
}
public static string Stringify(this Stream theStream,
Encoding encoding = null)
{
encoding = encoding ?? Encoding.UTF8;
using (var reader = new StreamReader(theStream, encoding))
{
return reader.ReadToEnd();
}
}
public static byte[] ReadFully(this Stream stream, int position = 0)
{
if (!stream.CanRead) throw new ArgumentException("This is not a readable stream.");
if (stream.CanSeek) stream.Position = 0;
var buffer = new byte[32768];
using (var ms = new MemoryStream())
{
while (true)
{
var read = stream.Read(buffer, 0, buffer.Length);
if (read <= 0)
return ms.ToArray();
ms.Write(buffer, 0, read);
}
}
}
public static void PgpEncrypt(
this Stream toEncrypt,
Stream outStream,
PgpPublicKey encryptionKey,
bool armor = true,
bool verify = false,
CompressionAlgorithmTag compressionAlgorithm = CompressionAlgorithmTag.Zip)
{
var encryptor = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, verify, new SecureRandom());
var literalizer = new PgpLiteralDataGenerator();
var compressor = new PgpCompressedDataGenerator(compressionAlgorithm);
encryptor.AddMethod(encryptionKey);
//it would be nice if these streams were read/write, and supported seeking. Since they are not,
//we need to shunt the data to a read/write stream so that we can control the flow of data as
//we go.
using (var stream = new MemoryStream()) // this is the read/write stream
using (var armoredStream = armor ? new ArmoredOutputStream(stream) : stream as Stream)
using (var compressedStream = compressor.Open(armoredStream))
{
//data is encrypted first, then compressed, but because of the one-way nature of these streams,
//other "interim" streams are required. The raw data is encapsulated in a "Literal" PGP object.
var rawData = toEncrypt.ReadFully();
var buffer = new byte[1024];
using (var literalOut = new MemoryStream())
using (var literalStream = literalizer.Open(literalOut, 'b', "STREAM", DateTime.UtcNow, buffer))
{
literalStream.Write(rawData, 0, rawData.Length);
literalStream.Close();
var literalData = literalOut.ReadFully();
//The literal data object is then encrypted, which flows into the compressing stream and
//(optionally) into the ASCII armoring stream.
using (var encryptedStream = encryptor.Open(compressedStream, literalData.Length))
{
encryptedStream.Write(literalData, 0, literalData.Length);
encryptedStream.Close();
compressedStream.Close();
armoredStream.Close();
//the stream processes are now complete, and our read/write stream is now populated with
//encrypted data. Convert the stream to a byte array and write to the out stream.
stream.Position = 0;
var data = stream.ReadFully();
outStream.Write(data, 0, data.Length);
}
}
}
}
}
My test method looked like this:
private static void EncryptMessage()
{
var pubKey = #"<public key text here>";
var clearText = #"<message text here>";
using (var stream = pubKey.Streamify())
{
var key = stream.ImportPublicKey();
using (var clearStream = clearText.Streamify())
using (var cryptoStream = new MemoryStream())
{
clearStream.PgpEncrypt(cryptoStream, key);
cryptoStream.Position = 0;
var cryptoString = cryptoStream.Stringify();
Console.WriteLine(cryptoString);
Console.WriteLine("Press any key to continue.");
}
}
Console.ReadKey();
}
Since someone asked, my decryption algorithm looked like this:
public static Stream PgpDecrypt(
this Stream encryptedData,
string armoredPrivateKey,
string privateKeyPassword,
Encoding armorEncoding = null)
{
armorEncoding = armorEncoding ?? Encoding.UTF8;
var stream = PgpUtilities.GetDecoderStream(encryptedData);
var layeredStreams = new List<Stream> { stream }; //this is to clean up/ dispose of any layered streams.
var dataObjectFactory = new PgpObjectFactory(stream);
var dataObject = dataObjectFactory.NextPgpObject();
Dictionary<long, PgpSecretKey> secretKeys;
using (var privateKeyStream = armoredPrivateKey.Streamify(armorEncoding))
{
var secRings =
new PgpSecretKeyRingBundle(PgpUtilities.GetDecoderStream(privateKeyStream)).GetKeyRings()
.OfType<PgpSecretKeyRing>();
var pgpSecretKeyRings = secRings as PgpSecretKeyRing[] ?? secRings.ToArray();
if (!pgpSecretKeyRings.Any()) throw new ArgumentException("No secret keys found.");
secretKeys = pgpSecretKeyRings.SelectMany(x => x.GetSecretKeys().OfType<PgpSecretKey>())
.ToDictionary(key => key.KeyId, value => value);
}
while (!(dataObject is PgpLiteralData) && dataObject != null)
{
try
{
var compressedData = dataObject as PgpCompressedData;
var listedData = dataObject as PgpEncryptedDataList;
//strip away the compression stream
if (compressedData != null)
{
stream = compressedData.GetDataStream();
layeredStreams.Add(stream);
dataObjectFactory = new PgpObjectFactory(stream);
}
//strip the PgpEncryptedDataList
if (listedData != null)
{
var encryptedDataList = listedData.GetEncryptedDataObjects()
.OfType<PgpPublicKeyEncryptedData>().First();
var decryptionKey = secretKeys[encryptedDataList.KeyId]
.ExtractPrivateKey(privateKeyPassword.ToCharArray());
stream = encryptedDataList.GetDataStream(decryptionKey);
layeredStreams.Add(stream);
dataObjectFactory = new PgpObjectFactory(stream);
}
dataObject = dataObjectFactory.NextPgpObject();
}
catch (Exception ex)
{
//Log exception here.
throw new PgpException("Failed to strip encapsulating streams.", ex);
}
}
foreach (var layeredStream in layeredStreams)
{
layeredStream.Close();
layeredStream.Dispose();
}
if (dataObject == null) return null;
var literalData = (PgpLiteralData)dataObject;
var ms = new MemoryStream();
using (var clearData = literalData.GetInputStream())
{
Streams.PipeAll(clearData, ms);
}
ms.Position = 0;
return ms;
}

Categories

Resources