Example #1
0
        /// <summary>
        ///     Desencripta un valor en AES_CTR
        /// </summary>
        /// <param name="dataIn">Data Encriptada</param>
        /// <param name="llave">Arreglo de bytes (32 bytes)</param>
        /// <param name="resultado">Cadena de texto obtenida del arreglo de bytes</param>
        /// <returns> Cantidad de Bytes obtenido al desencriptar </returns>
        public int Desencripta(byte[] data, byte[] llave, out byte[] resultado)
        {
            int result = -1;

            byte[] iv = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            resultado = null;

            try
            {
                resultado = new byte[data.Length];

                Aes128CounterMode am  = new Aes128CounterMode(iv);
                ICryptoTransform  ict = am.CreateDecryptor(llave, null);
                ict.TransformBlock(data, 0, data.Length, resultado, 0);


                result = resultado.Length;
            }
            catch (Exception e)
            {
                resultado = Encoding.UTF8.GetBytes(e.Message);
            }

            return(result);
        }
Example #2
0
        private static byte[] Crypt(byte[] data, byte[] key, byte[] iv)
        {
            Aes128CounterMode am  = new Aes128CounterMode(iv);
            ICryptoTransform  ict = am.CreateDecryptor(key, iv);

            byte[] dec = new byte[data.Length];
            ict.TransformBlock(data, 0, data.Length, dec, 0);
            return(dec);
        }
    static byte[] AesCtr(byte[] input, byte[] Key, byte[] IV)
    {
        IV = (byte[])IV.Clone();                      //use a copy to avoid updating original IV.

        //Since we're always decrypting an in-memory chunk we don't bother with streams
        using (Aes128CounterMode aesAlg = new Aes128CounterMode(IV))
        {
            ICryptoTransform decryptor = aesAlg.CreateDecryptor(Key, IV);
            return(decryptor.TransformFinalBlock(input, 0, input.Length));
        }
    }
        /// <summary>
        /// Sets the encryption keys and starts to encrypt the communication
        /// with the module.
        /// </summary>
        /// <param name="key">Session key.</param>
        /// <param name="txNonce">TX nonce used as prefix of the counter block.
        /// </param>
        /// <param name="rxNonce">RX nonce used as prefix of the counter block.
        /// </param>
        public void SetEncryptionKeys(byte[] key, byte[] txNonce, byte[] rxNonce)
        {
            Aes128CounterMode aesEncryption = new Aes128CounterMode(GetCounter(txNonce, 1));

            encryptor = (CounterModeCryptoTransform)aesEncryption.CreateEncryptor(key, null);

            Aes128CounterMode aesDecryption = new Aes128CounterMode(GetCounter(rxNonce, 1));

            decryptor = (CounterModeCryptoTransform)aesDecryption.CreateEncryptor(key, null);

            encrypt = true;
        }
        public static string Decrypt(string path)
        {
            CryptoKeyData keyData = GetKeyData(Path.GetFileName(path));

            byte[] input  = File.ReadAllBytes(path);
            byte[] output = new byte[input.Length];

            Aes128CounterMode aes = new Aes128CounterMode(keyData.IV);
            ICryptoTransform  ict = aes.CreateEncryptor(keyData.Key, null);

            ict.TransformBlock(input, 0, input.Length, output, 0);
            return(Encoding.ASCII.GetString(output));
        }
Example #6
0
        /// <summary>
        ///     Encripta un valor en AES_CTR
        /// </summary>
        /// <param name="base64Data">Cadena de texto en Base64 a encriptar</param>
        /// <param name="llave">Llave en claro</param>
        /// <param name="resultado">Cadena de texto en Base64 obtenida del arreglo de bytes</param>
        /// <returns> Cantidad de Bytes obtenido al encriptar</returns>
        public int Encripta(string base64Data, string llave, out string base64Resultado)
        {
            int result = -1;

            base64Resultado = "";
            byte[] iv      = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
            byte[] outData = null;
            byte[] llaveB  = null;
            byte[] data    = null;
            try
            {
                #region Validaciones
                try
                {
                    Encoding.UTF8.GetString(Convert.FromBase64String(base64Data));
                }
                catch (Exception)
                {
                    throw new Exception(string.Format("La data a encriptar NO es un Base64 Valido [{0}]", base64Data));
                }

                try
                {
                    Encoding.UTF8.GetString(Convert.FromBase64String(llave));
                }
                catch (Exception)
                {
                    throw new Exception(string.Format("La llave NO es un Base64 Valido [{0}]", llave));
                }
                #endregion

                data    = Encoding.UTF8.GetBytes(base64Data);
                outData = new byte[base64Data.Length];
                llaveB  = Encoding.UTF8.GetBytes(llave);// Convert.FromBase64String(base64Llave);

                Aes128CounterMode am  = new Aes128CounterMode(iv);
                ICryptoTransform  ict = am.CreateEncryptor(llaveB, null);
                ict.TransformBlock(data, 0, outData.Length, outData, 0);

                base64Resultado = Convert.ToBase64String(outData);

                result = outData.Length;
            }
            catch (Exception e)
            {
                base64Resultado = e.Message;
            }


            return(result);
        }       /// <summary>
        public static void Encrypt(string path, string contents)
        {
            CryptoKeyData keyData = GetKeyData(Path.GetFileName(path));

            byte[] input  = Encoding.ASCII.GetBytes(contents);
            byte[] output = new byte[input.Length];

            Aes128CounterMode aes = new Aes128CounterMode(keyData.IV);
            ICryptoTransform  ict = aes.CreateEncryptor(keyData.Key, null);

            ict.TransformBlock(input, 0, input.Length, output, 0);

            File.WriteAllBytes(path, output);
        }
    public static byte[] Decrypt(byte[] toDecrypt, byte[] key)
    {
        byte[]            unusedIV    = new byte[16];
        Aes128CounterMode counterMode = new Aes128CounterMode(0, 1);
        ICryptoTransform  decryptor   = counterMode.CreateDecryptor(key, unusedIV);

        byte[] decrypted    = new byte[toDecrypt.Length * 2];
        int    bytesWritten = decryptor.TransformBlock(toDecrypt, 0, toDecrypt.Length, decrypted, 0);

        if (bytesWritten == decrypted.Length)
        {
            return(decrypted);
        }
        byte[] resizedEncrypted = new byte[bytesWritten];
        Array.Copy(decrypted, resizedEncrypted, bytesWritten);
        return(resizedEncrypted);
    }
Example #9
0
        static byte[] DecryptStream(Stream stream, int length, int iv)
        {
            var plaintext = new byte[length];

            using (var aesAlg = new Aes128CounterMode(NollaPrng.Get16Seeded(iv)))
            {
                // Create a decryptor to perform the stream transform.
                var decryptor = aesAlg.CreateDecryptor(AESKey, null);
                var buffer    = new byte[length];
                stream.Read(buffer, 0, length);
                using (MemoryStream limitedStream = new MemoryStream(buffer)) {
                    using (CryptoStream csDecrypt = new CryptoStream(limitedStream, decryptor, CryptoStreamMode.Read, true))
                    {
                        csDecrypt.Read(plaintext, 0, length);
                    }
                }
            }
            return(plaintext);
        }
Example #10
0
        /// <summary>
        /// Decrypts the specified wak file and copies the resulting data to the output byte array
        /// </summary>
        /// <param name="wak_file">The wak file to decrypt</param>
        /// <param name="output">The output to which to write the decrypted file</param>
        /// <returns></returns>
        static public FiletableEntry[] DecryptWak(byte[] wak_file, byte[] output)
        {
            byte[] key = new byte[16];
            byte[] IV  = new byte[16];
            GenerateIV(key, Constants.wak_key_seed);
            GenerateIV(IV, Constants.wak_header_IV_seed);

            Aes128CounterMode aes = new Aes128CounterMode(IV);
            ICryptoTransform  ict = aes.CreateDecryptor(key, null);

            ict.TransformBlock(wak_file, 0, 16, output, 0); // decrypt header

            int num_files    = BinaryPrimitives.ReadInt32LittleEndian(new ReadOnlySpan <byte>(output, 4, 4));
            int files_offset = BinaryPrimitives.ReadInt32LittleEndian(new ReadOnlySpan <byte>(output, 8, 4));

            FiletableEntry[] fileTable = new FiletableEntry[num_files];

            GenerateIV(IV, Constants.wak_filetable_IV_seed);
            ict.TransformBlock(wak_file, 16, files_offset - 16, output, 16); // decrypt filetable

            int entry_offset = 16;

            for (int i = 0; i < num_files; i++)
            {
                int    file_offset     = BinaryPrimitives.ReadInt32LittleEndian(new ReadOnlySpan <byte>(output, entry_offset, 4));
                int    file_size       = BinaryPrimitives.ReadInt32LittleEndian(new ReadOnlySpan <byte>(output, entry_offset + 4, 4));
                int    filename_length = BinaryPrimitives.ReadInt32LittleEndian(new ReadOnlySpan <byte>(output, entry_offset + 8, 4));
                string filename        = Encoding.UTF8.GetString(new ReadOnlySpan <byte>(output, entry_offset + 12, filename_length));

                GenerateIV(IV, i);                                                         // file IV
                ict.TransformBlock(wak_file, file_offset, file_size, output, file_offset); // decrypt file

                fileTable[i].file_offset = file_offset;
                fileTable[i].file_size   = file_size;
                fileTable[i].filename    = filename;

                entry_offset += 12 + filename_length;
            }

            return(fileTable);
        }
Example #11
0
        public static bool DecryptKeyStore(string password, KeyStore keystore, out byte[] privatekey)
        {
            byte[] derivedkey = new byte[32];

            privatekey = null;

            KeyStoreKdfInfo kdf = keystore.Crypto.Kdf;
            KeyStoreAesInfo aes = keystore.Crypto.Aes;

            if (!KeyStoreCrypto.EncryptScrypt(password
                                              , kdf.Params.N
                                              , kdf.Params.R
                                              , kdf.Params.P
                                              , kdf.Params.Dklen
                                              , kdf.Params.Salt
                                              , out derivedkey))
            {
                Console.WriteLine("fail to generate scrypt.");
                return(false);
            }

            byte[] iv         = aes.Params.Iv;
            byte[] ciphertext = aes.Text;
            byte[] mac        = keystore.Crypto.Mac;

            if (!KeyStoreCrypto.VerifyMac(derivedkey, ciphertext, mac))
            {
                Console.WriteLine("Password do not match.");
                return(false);
            }

            byte[] cipherkey = KeyStoreCrypto.GenerateCipherKey(derivedkey);

            privatekey = new byte[32];
            using (var am = new Aes128CounterMode(iv))
                using (var ict = am.CreateDecryptor(cipherkey, null))
                {
                    ict.TransformBlock(ciphertext, 0, ciphertext.Length, privatekey, 0);
                }
            return(true);
        }
        public byte[] DecryptCtr(byte[] ciphertext, byte[] seed, byte[] ctr = null)
        {
            if (ciphertext.Length < AesBlockSize && ctr == null)
            {
                throw new Exception($"CT len should be >= {AesBlockSize} bytes!");
            }

            if (ctr != null && ctr.Length != 16)
            {
                throw new Exception($"CTR shoul be {AesBlockSize} bytes!");
            }

            byte[] encrypted;
            if (ctr == null)
            {
                ctr       = ciphertext.Take(16).ToArray();
                encrypted = ciphertext.Skip(16).ToArray();
            }
            else
            {
                encrypted = ciphertext;
            }

            var keyRand = new DeterministicCryptoRandomGenerator(seed, false);

            byte[] result;

            using (var aesAlg = new Aes128CounterMode(ctr))
            {
                var keyBytes = new byte[aesAlg.KeySize / 8];
                keyRand.GetBytes(keyBytes, 0, aesAlg.KeySize / 8);
                aesAlg.Key = keyBytes;

                using (ICryptoTransform decryptor = aesAlg.CreateDecryptor())
                {
                    result = TransformHelper.PerformCryptography(decryptor, encrypted);
                }
            }

            return(result);
        }
        public byte[] EncryptCrt(byte[] data, byte[] seed, bool useEntropy = true, bool includeCtr = true)
        {
            byte[] ciphertext;
            byte[] ctrInit = new byte[AesBlockSize];

            using (var rand = new DeterministicCryptoRandomGenerator(seed, useEntropy))
            {
                using (var keyRand = new DeterministicCryptoRandomGenerator(seed, false))
                {
                    rand.GetBytes(ctrInit);
                    byte[] ctr = new byte[ctrInit.Length];
                    ctrInit.CopyTo(ctr, 0);
                    using (var aesAlg = new Aes128CounterMode(ctr))
                    {
                        var keyBytes = new byte[aesAlg.KeySize / 8];
                        keyRand.GetBytes(keyBytes, 0, aesAlg.KeySize / 8);
                        aesAlg.Key = keyBytes;

                        // Create a crypto stream to perform encryption
                        using (ICryptoTransform ecryptor = aesAlg.CreateEncryptor())
                        {
                            // write encrypted bytes to memory
                            ciphertext = TransformHelper.PerformCryptography(ecryptor, data);
                        }
                    }

                    if (!includeCtr)
                    {
                        return(ciphertext);
                    }

                    var result = new byte[ctrInit.Length + ciphertext.Length];
                    Array.Copy(ctrInit, 0, result, 0, ctrInit.Length);
                    Array.Copy(ciphertext, 0, result, ctrInit.Length, ciphertext.Length);

                    // Return the encrypted bytes from the memory stream.
                    return(result);
                }
            }
        }
Example #14
0
        public static byte[] GetMegaFile(string megaUrl)
        {
            byte[] result = null;

            string id;
            string key;
            {
                string[] ss = megaUrl.Split('!');
                if (ss.Length < 2)
                {
                    return result;
                }
                id = ss[1];
                key = ss[2];
            }
            Log("megaUrl={0}, id={1}, key={2}", megaUrl, id, key);

            byte[] aesKey = new byte[16];
            byte[] aesIv = new byte[16];    // counter
            {
                string b64Key = key.Replace("-", "+");
                while (b64Key.Length % 4 != 0)
                {
                    b64Key += '=';
                }
                Log("b64Key={0}", b64Key);
                byte[] binKey = Convert.FromBase64String(b64Key);
                if (binKey.Length != 32)
                {
                    return result;
                }
                for (int i = 0; i < 16; i++)
                {
                    aesKey[i] = (byte)(binKey[i] ^ binKey[i + 16]);
                }
                for (int i = 0; i < 16; i++)
                {
                    if (i < 8)
                    {
                        aesIv[i] = binKey[i + 16];
                    }
                    else
                    {
                        aesIv[i] = 0;
                    }
                }
            }
            Log("aesKey = {0}", ByteArrayToString(aesKey));
            Log("aesIv  = {0}", ByteArrayToString(aesIv));

            string encUrl = null;
            {
                string postResult = "";
                {
                    string postUri = "https://eu.api.mega.co.nz/cs";
                    string postParams = string.Format(@"[{{""a"":""g"",""g"":1,""p"":""{0}""}}]", id);
                    using (WebClient wc = new WebClient())
                    {
                        for (int retryCount = 0; retryCount < retryMax; retryCount++)
                        {
                            if (retryCount != 0)
                            {
                                Console.WriteLine("Retrying...");
                                Thread.Sleep(retrySleep);
                            }
                            wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
                            try
                            {
                                postResult = wc.UploadString(postUri, postParams);
                                if (!string.IsNullOrEmpty(postResult))
                                {
                                    break;
                                }
                            }
                            catch (WebException)
                            {
                                Console.WriteLine("POST failed#{0}({1})", retryCount + 1, postUri);
                            }
                        }
                    }
                }

                Match match = Regex.Match(postResult, @"""g"":""([^""]*)""");
                if (match.Groups.Count != 2)
                {
                    return result;
                }
                encUrl = match.Groups[1].Value;
            }
            Log("encUrl  = {0}", encUrl);

            byte[] encFile = null;
            {
                using (WebClient wc = new WebClient())
                {
                    for (int retryCount = 0; retryCount < retryMax; retryCount++)
                    {
                        if (retryCount != 0)
                        {
                            Console.WriteLine("Retrying...");
                            Thread.Sleep(retrySleep);
                        }
                        try
                        {
                            encFile = wc.DownloadData(encUrl);
                        }
                        catch (WebException)
                        {
                            Console.WriteLine("GET failed#{0}({1})", retryCount + 1, encUrl);
                        }
                        if(encFile != null && encFile.Length > 0)
                        {
                            break;
                        }
                    }
                }
                if (encFile == null)
                {
                    return result;
                }
            }

            byte[] decFile = null;
            {
                byte[] paddedEncFile = new byte[((encFile.Length + 15) / 16) * 16];
                Log("encFile.Length={0}", encFile.Length);
                Log("paddedEncFile.Length={0}", paddedEncFile.Length);
                encFile.CopyTo(paddedEncFile, 0);
                for (int i = encFile.Length; i < paddedEncFile.Length; i++)
                {
                    paddedEncFile[i] = 0;
                }

                var aes = new Aes128CounterMode(aesIv);
                var dec = aes.CreateDecryptor(aesKey, null);

                byte[] paddedDecFile = new byte[paddedEncFile.Length];
                dec.TransformBlock(paddedEncFile, 0, paddedEncFile.Length, paddedDecFile, 0);
                Array.Resize(ref paddedDecFile, encFile.Length);
                decFile = paddedDecFile;
            }
            return decFile;
        }
Example #15
0
    public static byte[] GetMegaFile(string megaUrl)
    {
        byte[] result = null;

        string id;
        string key;
        {
            string[] ss = megaUrl.Split('!');
            if (ss.Length < 2)
            {
                Console.WriteLine("Error : Bad URL (megaUrl={0})", megaUrl);
                return result;
            }
            id = ss[1];
            key = ss[2];
        }
        Log("megaUrl={0}, id={1}, key={2}", megaUrl, id, key);

        byte[] aesKey = new byte[16];
        byte[] aesIv = new byte[16];    // counter
        {
            string b64Key = key.Replace("-", "+").Replace("_", "/").PadRight(((key.Length + 3) / 4) * 4, '=');
            Log("b64Key={0}", b64Key);
            byte[] binKey = Convert.FromBase64String(b64Key);
            if (binKey.Length != 32)
            {
                return result;
            }
            for (int i = 0; i < aesKey.Length; i++)
            {
                aesKey[i] = (byte)(binKey[i] ^ binKey[i + 16]);
            }
            for (int i = 0; i < aesIv.Length; i++)
            {
                aesIv[i] = i < 8 ? binKey[i + 16] : (byte)0;
            }
        }
        Log("aesKey = {0}", ByteArrayToString(aesKey));
        Log("aesIv  = {0}", ByteArrayToString(aesIv));

        string encUrl = null;
        {
            string postResult = "";
            string postUri = "https://eu.api.mega.co.nz/cs";
            string postParams = string.Format(@"[{{""a"":""g"",""g"":1,""p"":""{0}""}}]", id);
            WebClientWithRetry(retryMax, (webClient) =>
            {
                webClient.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
                postResult = webClient.UploadString(postUri, postParams);
                return !string.IsNullOrEmpty(postResult);
            });
            Match match = Regex.Match(postResult, @"""g"":""([^""]*)""");
            if (match.Groups.Count != 2)
            {
                return result;
            }
            encUrl = match.Groups[1].Value;
        }
        Log("encUrl = {0}", encUrl);

        byte[] encFile = null;
        WebClientWithRetry(retryMax, (webClient) =>
        {
            encFile = webClient.DownloadData(encUrl);
            return encFile != null && encFile.Length > 0;
        });
        if (encFile == null)
        {
            return result;
        }

#if DEBUG
        File.WriteAllBytes("encfile.enc", encFile);
#endif
        {
            byte[] paddedEncFile = new byte[((encFile.Length + 15) / 16) * 16];
            Log("encFile.Length={0}", encFile.Length);
            Log("paddedEncFile.Length={0}", paddedEncFile.Length);
            encFile.CopyTo(paddedEncFile, 0);
            for (int i = encFile.Length; i < paddedEncFile.Length; i++)
            {
                paddedEncFile[i] = 0;
            }

            var aes = new Aes128CounterMode(aesIv);
            var dec = aes.CreateDecryptor(aesKey, null);

            byte[] paddedDecFile = new byte[paddedEncFile.Length];
            dec.TransformBlock(paddedEncFile, 0, paddedEncFile.Length, paddedDecFile, 0);
            Array.Resize(ref paddedDecFile, encFile.Length);
            result = paddedDecFile;
        }
        return result;
    }
Example #16
0
    public static byte[] GetMegaFile(string megaUrl)
    {
        byte[] result = null;

        string id;
        string key;

        {
            string[] ss = megaUrl.Split('!');
            if (ss.Length < 2)
            {
                Console.WriteLine("Error : Bad URL (megaUrl={0})", megaUrl);
                return(result);
            }
            id  = ss[1];
            key = ss[2];
        }
        Log("megaUrl={0}, id={1}, key={2}", megaUrl, id, key);

        byte[] aesKey = new byte[16];
        byte[] aesIv  = new byte[16];   // counter
        {
            string b64Key = key.Replace("-", "+").Replace("_", "/").PadRight(((key.Length + 3) / 4) * 4, '=');
            Log("b64Key={0}", b64Key);
            byte[] binKey = Convert.FromBase64String(b64Key);
            if (binKey.Length != 32)
            {
                return(result);
            }
            for (int i = 0; i < aesKey.Length; i++)
            {
                aesKey[i] = (byte)(binKey[i] ^ binKey[i + 16]);
            }
            for (int i = 0; i < aesIv.Length; i++)
            {
                aesIv[i] = i < 8 ? binKey[i + 16] : (byte)0;
            }
        }
        Log("aesKey = {0}", ByteArrayToString(aesKey));
        Log("aesIv  = {0}", ByteArrayToString(aesIv));

        string encUrl = null;

        {
            string postResult = "";
            string postUri    = "https://eu.api.mega.co.nz/cs";
            string postParams = string.Format(@"[{{""a"":""g"",""g"":1,""p"":""{0}""}}]", id);
            WebClientWithRetry(retryMax, (webClient) =>
            {
                webClient.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
                postResult = webClient.UploadString(postUri, postParams);
                return(!string.IsNullOrEmpty(postResult));
            });
            Match match = Regex.Match(postResult, @"""g"":""([^""]*)""");
            if (match.Groups.Count != 2)
            {
                return(result);
            }
            encUrl = match.Groups[1].Value;
        }
        Log("encUrl = {0}", encUrl);

        byte[] encFile = null;
        WebClientWithRetry(retryMax, (webClient) =>
        {
            encFile = webClient.DownloadData(encUrl);
            return(encFile != null && encFile.Length > 0);
        });
        if (encFile == null)
        {
            return(result);
        }

#if DEBUG
        File.WriteAllBytes("encfile.enc", encFile);
#endif
        {
            byte[] paddedEncFile = new byte[((encFile.Length + 15) / 16) * 16];
            Log("encFile.Length={0}", encFile.Length);
            Log("paddedEncFile.Length={0}", paddedEncFile.Length);
            encFile.CopyTo(paddedEncFile, 0);
            for (int i = encFile.Length; i < paddedEncFile.Length; i++)
            {
                paddedEncFile[i] = 0;
            }

            var aes = new Aes128CounterMode(aesIv);
            var dec = aes.CreateDecryptor(aesKey, null);

            byte[] paddedDecFile = new byte[paddedEncFile.Length];
            dec.TransformBlock(paddedEncFile, 0, paddedEncFile.Length, paddedDecFile, 0);
            Array.Resize(ref paddedDecFile, encFile.Length);
            result = paddedDecFile;
        }
        return(result);
    }
Example #17
0
        public static bool GenerateKeyStore(string path,
                                            string password,
                                            byte[] privatekey,
                                            string address,
                                            int n,
                                            int r,
                                            int p,
                                            int dklen,
                                            out string file_name)
        {
            file_name = null;
            KdfParam kdf_param = new KdfParam()
            {
                Dklen = dklen, N = n, R = r, P = p
            };

            byte[] salt;
            byte[] derivedkey;
            if (!KeyStoreCrypto.GenerateScrypt(password, kdf_param.N, kdf_param.R, kdf_param.P, kdf_param.Dklen, out salt, out derivedkey))
            {
                Console.WriteLine("fail to generate scrypt.");
                return(false);
            }
            kdf_param.Salt = salt;

            byte[] cipherkey  = KeyStoreCrypto.GenerateCipherKey(derivedkey);
            byte[] iv         = RandomGenerator.GenerateRandomBytes(16);
            byte[] ciphertext = new byte[32];

            using (var am = new Aes128CounterMode(iv.Clone() as byte[]))
                using (var ict = am.CreateEncryptor(cipherkey, null))
                {
                    ict.TransformBlock(privatekey, 0, privatekey.Length, ciphertext, 0);
                }

            byte[] mac = KeyStoreCrypto.GenerateMac(derivedkey, ciphertext);

            KeyStore keystore = new KeyStore()
            {
                Version = 1,
                Address = address,
                Crypto  = new KeyStoreCryptoInfo()
                {
                    Kdf = new KeyStoreKdfInfo()
                    {
                        Name   = KDF_SCRYPT,
                        Params = kdf_param
                    },
                    Aes = new KeyStoreAesInfo()
                    {
                        Name   = AES128CTR,
                        Text   = ciphertext,
                        Params = new AesParam()
                        {
                            Iv = iv
                        }
                    },
                    Mac = mac
                },
            };

            if (!Directory.Exists(path))
            {
                Directory.CreateDirectory(path);
            }

            string json = JsonConvert.SerializeObject(keystore, Formatting.Indented);

            file_name = DateTime.UtcNow.ToString("yyyy-MM-ddTHH-mm-ss.ffff") + "__" + keystore.Address + ".keystore";
            path     += Path.DirectorySeparatorChar + file_name;
            using (var file = File.CreateText(path))
            {
                file.Write(json);
                file.Flush();
            }

            return(true);
        }
Example #18
0
        public static byte[] GetMegaFile(string megaUrl)
        {
            byte[] result = null;

            string id;
            string key;

            {
                string[] ss = megaUrl.Split('!');
                if (ss.Length < 2)
                {
                    return(result);
                }
                id  = ss[1];
                key = ss[2];
            }
            Log("megaUrl={0}, id={1}, key={2}", megaUrl, id, key);

            byte[] aesKey = new byte[16];
            byte[] aesIv  = new byte[16];   // counter
            {
                string b64Key = key.Replace("-", "+");
                while (b64Key.Length % 4 != 0)
                {
                    b64Key += '=';
                }
                Log("b64Key={0}", b64Key);
                byte[] binKey = Convert.FromBase64String(b64Key);
                if (binKey.Length != 32)
                {
                    return(result);
                }
                for (int i = 0; i < 16; i++)
                {
                    aesKey[i] = (byte)(binKey[i] ^ binKey[i + 16]);
                }
                for (int i = 0; i < 16; i++)
                {
                    if (i < 8)
                    {
                        aesIv[i] = binKey[i + 16];
                    }
                    else
                    {
                        aesIv[i] = 0;
                    }
                }
            }
            Log("aesKey = {0}", ByteArrayToString(aesKey));
            Log("aesIv  = {0}", ByteArrayToString(aesIv));

            string encUrl = null;

            {
                string postResult = "";
                {
                    string postUri    = "https://eu.api.mega.co.nz/cs";
                    string postParams = string.Format(@"[{{""a"":""g"",""g"":1,""p"":""{0}""}}]", id);
                    using (WebClient wc = new WebClient())
                    {
                        for (int retryCount = 0; retryCount < retryMax; retryCount++)
                        {
                            if (retryCount != 0)
                            {
                                Console.WriteLine("Retrying...");
                                Thread.Sleep(retrySleep);
                            }
                            wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
                            try
                            {
                                postResult = wc.UploadString(postUri, postParams);
                                if (!string.IsNullOrEmpty(postResult))
                                {
                                    break;
                                }
                            }
                            catch (WebException)
                            {
                                Console.WriteLine("POST failed#{0}({1})", retryCount + 1, postUri);
                            }
                        }
                    }
                }

                Match match = Regex.Match(postResult, @"""g"":""([^""]*)""");
                if (match.Groups.Count != 2)
                {
                    return(result);
                }
                encUrl = match.Groups[1].Value;
            }
            Log("encUrl  = {0}", encUrl);

            byte[] encFile = null;
            {
                using (WebClient wc = new WebClient())
                {
                    for (int retryCount = 0; retryCount < retryMax; retryCount++)
                    {
                        if (retryCount != 0)
                        {
                            Console.WriteLine("Retrying...");
                            Thread.Sleep(retrySleep);
                        }
                        try
                        {
                            encFile = wc.DownloadData(encUrl);
                        }
                        catch (WebException)
                        {
                            Console.WriteLine("GET failed#{0}({1})", retryCount + 1, encUrl);
                        }
                        if (encFile != null && encFile.Length > 0)
                        {
                            break;
                        }
                    }
                }
                if (encFile == null)
                {
                    return(result);
                }
            }

            byte[] decFile = null;
            {
                byte[] paddedEncFile = new byte[((encFile.Length + 15) / 16) * 16];
                Log("encFile.Length={0}", encFile.Length);
                Log("paddedEncFile.Length={0}", paddedEncFile.Length);
                encFile.CopyTo(paddedEncFile, 0);
                for (int i = encFile.Length; i < paddedEncFile.Length; i++)
                {
                    paddedEncFile[i] = 0;
                }

                var aes = new Aes128CounterMode(aesIv);
                var dec = aes.CreateDecryptor(aesKey, null);

                byte[] paddedDecFile = new byte[paddedEncFile.Length];
                dec.TransformBlock(paddedEncFile, 0, paddedEncFile.Length, paddedDecFile, 0);
                Array.Resize(ref paddedDecFile, encFile.Length);
                decFile = paddedDecFile;
            }
            return(decFile);
        }
Example #19
0
        public static string Decypt(IEnumerable <string> input, string password)
        {
            var file   = input.ToArray();
            var header = file.First();
            var fields = header.Split(';');

            if (fields.Length != 3)
            {
                throw new InvalidVaultException("Unsupported file header field count: {0}".Fmt(fields.Length));
            }

            if (fields[0] != "$ANSIBLE_VAULT")
            {
                throw new InvalidVaultException("Unsupported type in file header: {0}".Fmt(fields[0]));
            }

            if (fields[1] != "1.1")
            {
                throw new InvalidVaultException("Unsupported version in file header: {0}".Fmt(fields[1]));
            }

            if (fields[2] != "AES256")
            {
                throw new InvalidVaultException("Unsupported cipher in file header: {0}".Fmt(fields[1]));
            }

            var hexPayload    = string.Join("", file.Skip(1).ToArray());
            var binPayload    = Encoding.UTF8.GetString(FromHex(hexPayload));
            var payloadFields = binPayload.Split('\n');

            var salt       = FromHex(payloadFields[0]);
            var hmac       = FromHex(payloadFields[1]);
            var ciphertext = FromHex(payloadFields[2]);

            const int cipherKeyLength = 32;
            const int hmacKeyLength   = 32;
            const int ivLength        = 16;
            const int pbkdf2KeyLength = cipherKeyLength + hmacKeyLength + ivLength;
            var       passwordBytes   = Encoding.UTF8.GetBytes(password);
            var       pbkdf2Key       = PBKDF2Sha256.GetBytes(pbkdf2KeyLength, passwordBytes, salt, 10000);
            var       cipherKey       = new byte[cipherKeyLength];

            Array.Copy(pbkdf2Key, 0, cipherKey, 0, cipherKeyLength);
            var hmacKey = new byte[hmacKeyLength];

            Array.Copy(pbkdf2Key, cipherKeyLength, hmacKey, 0, hmacKeyLength);
            var cipherIv = new byte[ivLength];

            Array.Copy(pbkdf2Key, cipherKeyLength + hmacKeyLength, cipherIv, 0, ivLength);

            if (!CheckMac(hmacKey, ciphertext, hmac))
            {
                throw new InvalidMacException("The MACs did not match; invalid password?");
            }

            var cipher      = new Aes128CounterMode(cipherIv);
            var decrypter   = cipher.CreateDecryptor(cipherKey, null);
            var outputBytes = decrypter.TransformFinalBlock(ciphertext, 0, ciphertext.Length);
            var padding     = outputBytes[outputBytes.Length - 1];
            var plaintext   = Encoding.UTF8.GetString(outputBytes, 0, outputBytes.Length - padding);

            return(plaintext);
        }