/// <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); }
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)); }
/// <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); }
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); }
/// <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); }
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); } } }
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; }
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; }
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); }
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); }
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); }
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); }