Cómo cifrar un archivo en .net y descifrar en android

He estado trabajando en el proyecto donde tenemos que mantener de forma segura un pdf en la tarjeta android sd. Queremos que este encriptado en .net porque su tiene que ser transferido a través de API. He implementado en .NET pero no puedo descifrar en android.

Código para cifrar un archivo

public static void EncryptFile(string inputFile, string outputFile) { try { string password = @"myKey123"; // Your Key Here UnicodeEncoding UE = new UnicodeEncoding(); byte[] key = UE.GetBytes(password); string cryptFile = outputFile; FileStream fsCrypt = new FileStream(cryptFile, FileMode.Create); RijndaelManaged RMCrypto = new RijndaelManaged(); RMCrypto.Mode = CipherMode.CBC; //remember this parameter RMCrypto.Padding = PaddingMode.PKCS7; //remember this parameter RMCrypto.KeySize = 0x80; RMCrypto.BlockSize = 0x80; CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateEncryptor(key, key), CryptoStreamMode.Write); FileStream fsIn = new FileStream(inputFile, FileMode.Open); int data; while ((data = fsIn.ReadByte()) != -1) { cs.WriteByte((byte)data); } fsIn.Close(); cs.Close(); fsCrypt.Close(); } catch { Console.WriteLine("Encryption failed!", "Error"); } } 

Código para descifrar el archivo

 public static void DecryptFile(string inputFile, string outputFile) { { string password = @"myKey123"; // Your Key Here UnicodeEncoding UE = new UnicodeEncoding(); byte[] key = UE.GetBytes(password); FileStream fsCrypt = new FileStream(inputFile, FileMode.Open); RijndaelManaged RMCrypto = new RijndaelManaged(); RMCrypto.Mode = CipherMode.CBC; //remember this parameter RMCrypto.Padding = PaddingMode.PKCS7; //remember this parameter RMCrypto.KeySize = 0x80; RMCrypto.BlockSize = 0x80; CryptoStream cs = new CryptoStream(fsCrypt, RMCrypto.CreateDecryptor(key, key), CryptoStreamMode.Read); FileStream fsOut = new FileStream(outputFile, FileMode.Create); int data; while ((data = cs.ReadByte()) != -1) fsOut.WriteByte((byte)data); fsOut.Close(); cs.Close(); fsCrypt.Close(); } } 

Lo intenté en Android usando código inferior

 public static byte[] decodeFile(String key, byte[] fileData) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); //this parameters should not be changed byte[] keyBytes = new byte[16]; byte[] b = key.getBytes("UTF-16"); System.out.println("RAM"+b); int len = b.length; if (len > keyBytes.length) len = keyBytes.length; System.arraycopy(b, 0, keyBytes, 0, len); SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(keyBytes); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); byte[] decrypted = cipher.doFinal(fileData); return decrypted; } 

Al ejecutar este código me sale error:

 error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt 

Así que encontré el problema con su código y la arquitectura que está utilizando. Cuando usted elige a los archivos de criptografía en diferentes programas de idiomas y en diferentes envrioment (Android ("unix") y Windows) es necesario recordar el concepto de pequeño y grande endian. – la wikipedia Endianness .

Perfectamente en Java la amenaza siempre con BIG endian por lo que el byte más significativo (MSB) es diferente del C # usando el byte menos significativo (LSB), este paso causa un problema difícil de rastrear.

Creé un código basado en el suyo pero usando Java y no androide y no podría hacer el trabajo del código porque siempre tenía el mismo mensaje de error BadPaddingException: Given final block not properly padded . El mensaje de error no dice mucho sobre el problema real que era el archivo key .
Cuando lees en Java es diferente de .NET porque cuando conviertes tu clave en byte las amenazas de la arquitectura Java con el MSB cuando tu verdadera clave está usando LSB.

Así que la verdadera respuesta es esto que you need to convert your key to array of bytes telling to use the Least significative byte so you always have the same array of bytes in .NET and in Java
Algo como esto:

 //the bKey it's the array of bytes and the key it's the String your are using. byte[] bKey = key.getBytes("UTF-16LE"); 

I found the issue with the LE because i read the array of bytes from .NET and from Java and they are different so this gave me the start to find this issue

¡Buena suerte con su sistema!

Ps .: He tenido un problema con la decodificación porque el problema que tiene cuando decodificar y decodificar una matriz de bytes. He encontrado un camino que debe utilizar Apache Commons Base64 para decodificar la cadena en Java.
Referencias

-Big / Little endian – Diferencia entre Big Endian y Little Endian Byte order
-Error con acolchado – BadPaddingException: Dado el bloque final no correctamente rellenado
-La extremidad el problema está en la llave – Dado el bloque final no acolchado correctamente
-Decode Base64 – Descodificación de una cadena Base64 en Java

El código que usé para probar.

  import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; public class HelloWorld { public static void main(String[] args) throws Exception { // TODO Auto-generated method stub Path p = Paths .get("C:\\Users\\casilva\\workspace\\StackOverflow\\src\\tst.enc"); byte[] a = Files.readAllBytes(p); byte[] result = decodeFile("myKey123", a); System.out.println("Result=" + new String(result, "UTF-8")); } public static byte[] decodeFile(String key, byte[] fileData) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] bKey = key.getBytes("UTF-16LE"); SecretKeySpec keySpec = new SecretKeySpec(bKey, "AES"); IvParameterSpec ivSpec = new IvParameterSpec(bKey); cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec); byte[] decrypted = cipher.doFinal(fileData); return decrypted; } } 
  • Xamarin "Aapt.exe" salió con el código -1073741819
  • La aplicación que implementa Parse Unity Plugin se bloquea en el dispositivo android pero funciona bien en el editor
  • Formatos Xamarin desajuste de tamaño de imagen
  • Bloquee la orientación de la pantalla a la vertical al escanear con la librería Zxing, la aplicación Xamarin.android.
  • Binding Library Mono para Android
  • Desarrollo de Android con c #
  • ¿Cómo se compara Xamarin para Android (Mono para Android) con el desarrollo nativo de Android?
  • Cómo acceder al enum en Unity AndroidJavaClass
  • Cómo preservar / volver a enlazar a los oyentes de eventos en MapFragment después de girar el dispositivo (retrato / paisaje)?
  • Formularios de Xamarin Android Aplicación no obtener DeviceToken Parse SDK
  • Escribir la implementación c # de la clase abstracta en línea?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.