Ejemplo n.º 1
0
        private void ParseFile()
        {
            var    directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var    path      = $"{directory}\\Resources\\crypto\\encrypted_jpg_01.jpg";
            string magic     = "__CLOUDSYNC_ENC__";

            byte[] magicBytes = Encoding.ASCII.GetBytes(magic);

            using FileStream fs   = new FileStream(path, FileMode.Open);
            using BinaryReader br = new BinaryReader(fs);

            byte[] value = br.ReadBytes(magicBytes.Length);
            Console.WriteLine(ByteArrayCompare(magicBytes, value));

            //check "__CLOUDSYNC_ENC__" Md5 hash
            value = br.ReadBytes(32);
            byte[] expectedMagicHash =
                Encoding.ASCII.GetBytes(BytesUtils.ByteArrayToLowerHexString(Md5(magicBytes)));
            Assert.AreEqual(expectedMagicHash, value);

            //
            HandlerFactory     handlerFactory   = new HandlerFactory();
            StringHandler      stringHandler    = new StringHandler();
            IntHandler         intHandler       = new IntHandler();
            ByteSteamHandler   byteSteamHandler = new ByteSteamHandler();
            OrderedDictHandler dictHandler      = new OrderedDictHandler(handlerFactory);

            handlerFactory.AddHandler(stringHandler);
            handlerFactory.AddHandler(dictHandler);
            handlerFactory.AddHandler(intHandler);
            handlerFactory.AddHandler(byteSteamHandler);

            byte metaTag = br.ReadByte();

            if (metaTag != 0x42)
            {
                throw new InvalidDataException();
            }

            IFileStreamHandler <IDictionary <string, object> > metaHandler =
                handlerFactory.GetHandler <IDictionary <string, object> >(metaTag);
            IDictionary <string, object> metaDict = metaHandler.Handle(br);

            if (!(metaDict.ContainsKey("type") && "metadata".Equals(metaDict["type"])))
            {
                throw new InvalidDataException();
            }

            FileMeta3 fileMeta = FileMeta3.fromDictionary(metaDict);

            Console.WriteLine(fileMeta);

            AsymmetricKeyParameter akp = CryptoUtils.readPemPk(this.privateKey);

            byte[] sessionKeyCharArray = CryptoUtils.RsaOaepDeciper(fileMeta.EncKey2, akp);

            string computedSessionKeyHash = CryptoUtils.SaltedMd5(
                fileMeta.SessionKeyHash.Substring(0, 10), sessionKeyCharArray);

            if (!fileMeta.SessionKeyHash.Equals(computedSessionKeyHash))
            {
                throw new InvalidDataException("key is incorrect");
            }

            //decrypt content
            byte[] sessionKey = BytesUtils.HexStringToByteArray(
                Encoding.ASCII.GetString(sessionKeyCharArray));
            Console.Write(sessionKey);
            ParametersWithIV keys =
                CryptoUtils.DeriveAESKeyParameters(sessionKey, null);
            AesCbcCryptor decryptor =
                new AesCbcCryptor(((KeyParameter)keys.Parameters).GetKey(), keys.GetIV());
            List <byte[]> decryptedData = new List <byte[]>();

            byte[] buf    = null;
            byte[] decBuf = null;
            IDictionary <string, object> dataResult = null;

            while (true)
            {
                byte dataTag = br.ReadByte();
                if (dataTag == 0x40)
                {
                    Console.WriteLine("come here");
                }

                if (dataTag != 0x42)
                {
                    decBuf = decryptor.DecryptBlock(buf, true);
                    decryptedData.Add(decBuf);
                    break;
                }

                if (buf != null)
                {
                    decBuf = decryptor.DecryptBlock(buf, false);
                    decryptedData.Add(decBuf);
                }

                IFileStreamHandler <IDictionary <string, object> > dataHandler =
                    handlerFactory.GetHandler <IDictionary <string, object> >(metaTag);
                dataResult = dataHandler.Handle(br);
                object typeValue = null;
                dataResult.TryGetValue("type", out typeValue);
                string typeValueString = typeValue as string;
                if (!"data".Equals(typeValueString))
                {
                    break;
                }

                buf = (byte[])dataResult["data"];
            }

            byte[] decData = CryptoUtils.Concat(decryptedData.ToArray());
            File.WriteAllBytes("z:\\123.jpg.lz4", decData);

            //last directory

            //TODO validate dataResult["type"] == "metadata"
            string fileMd5 = (string)dataResult["file_md5"];

            Console.Write(fileMd5);
        }
Ejemplo n.º 2
0
        public bool ProcessFile(string sourcePath, string destDir, bool respectFileNameInMeta = true)
        {
            string destPath = null;

            try
            {
                FileItem fi = new FileItem(sourcePath);
                using (CloudSyncFile cloudSyncFile = new CloudSyncFile(fi, _handlerFactory))
                {
                    cloudSyncFile.InitParsing();
                    FileMeta3 fileMeta = cloudSyncFile.GetFileMeta();

                    //Generate session key and make sure it matches the file
                    byte[] sessionKeyComputed =
                        CryptoUtils.RsaOaepDeciper(fileMeta.EncKey2, this._cloudSyncKey.KeyPair.Private);
                    string sessionKeyHashStrComputed = CryptoUtils.SaltedMd5(
                        fileMeta.SessionKeyHash.Substring(0, 10), sessionKeyComputed);

                    if (!fileMeta.SessionKeyHash.Equals(sessionKeyHashStrComputed))
                    {
                        throw new InvalidDataException($"File {fi.Name}, Computed session key is incorrect.");
                    }

                    //decrypt content
                    byte[] sessionKeyBytes = BytesUtils.HexStringToByteArray(
                        Encoding.ASCII.GetString(sessionKeyComputed));
                    ParametersWithIV keys =
                        CryptoUtils.DeriveAESKeyParameters(sessionKeyBytes, null);
                    AesCbcCryptor decryptor =
                        new AesCbcCryptor(((KeyParameter)keys.Parameters).GetKey(), keys.GetIV());

                    destPath = Path.Join(destDir,
                                         respectFileNameInMeta ? fileMeta.FileName : Path.GetFileName(sourcePath));

                    using (var hasher = MD5.Create())
                    {
                        using (AesCryptoServiceProvider aes = new AesCryptoServiceProvider())
                        {
                            aes.Mode = CipherMode.CBC;
                            aes.Key  = ((KeyParameter)keys.Parameters).GetKey();
                            aes.IV   = keys.GetIV();
                            //Stopwatch stopwatch =  new Stopwatch();
                            //stopwatch.Start();
                            //byte[] buffer = new byte[1024 * 1024];
                            long             bytesRead = 0;
                            ICryptoTransform decoder   = aes.CreateDecryptor();
                            using (CloudSyncPayloadStream cspls =
                                       new CloudSyncPayloadStream(cloudSyncFile.GetDataBlocks(decryptor)))
                                using (CryptoStream aesStream = new CryptoStream(cspls, decoder, CryptoStreamMode.Read))
                                    using (LZ4DecoderStream lz4ds = LZ4Stream.Decode(aesStream))
                                        using (FileStream writeFs = new FileStream(destPath, FileMode.OpenOrCreate,
                                                                                   FileAccess.ReadWrite, FileShare.ReadWrite, 1024 * 1024))
                                            using (CryptoStream md5HashStream =
                                                       new CryptoStream(writeFs, hasher, CryptoStreamMode.Write))
                                            {
                                                lz4ds.CopyTo(md5HashStream, 1024 * 1024);
                                                // int read;
                                                // while ((read = md5HashStream.Read(buffer, 0, buffer.Length)) > 0)
                                                // {
                                                //     //do nothing
                                                //     bytesRead += read;
                                                //     long elapsed = stopwatch.ElapsedMilliseconds;
                                                //     if (elapsed > 1000)
                                                //     {
                                                //         double readInM = (double) bytesRead / 1024.0 / 1024.0/elapsed*1000.0;
                                                //         bytesRead = 0;
                                                //         Console.WriteLine($"Speed:{readInM} M/s");
                                                //         stopwatch.Reset();
                                                //         stopwatch.Start();
                                                //     }
                                                // }
                                            }

                            //stopwatch.Stop();
                            if (!cloudSyncFile.VerifyContentHash(hasher.Hash))
                            {
                                throw new InvalidDataException("File Md5 doesn't match.");
                            }
                        }
                    }

                    return(true);
                }
            }
            catch (Exception ex)
            {
                if (File.Exists(destPath))
                {
                    File.Delete(destPath);
                }

                this._exceptionHandler.Handle(ex);
            }

            return(false);
        }