Encriptación AES en iOS y Android, y descifrado en C # .NET
Primero lo primero. Hace algún tiempo necesitaba un simple cifrado AES en Android para cifrar una contraseña y enviarla como un parámetro para un servicio web .net donde se descifró la contraseña.
El siguiente es mi cifrado de Android:
- Onsen-UI usando el menú deslizante con el navegador
- GIT: Dos repositorios diferentes con una carpeta compartida
- Integre Unity3D con Vuforia en la aplicación Cordova
- ¿Cómo navegar desde una página web a una página local en mi aplicación de teléfono?
- ¿Hay algún marco único para escribir iOS, Android (e incluso Windows Phone)?
private static String Encrypt(String text, String key) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); byte[] keyBytes= new byte[16]; byte[] b= key.getBytes("UTF-8"); 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.ENCRYPT_MODE,keySpec,ivSpec); byte[] results = cipher.doFinal(text.getBytes("UTF-8")); String result = Base64.encodeBytes(results); return result; }
Y luego lo descifré en C # con:
public static string Decrypt(string textToDecrypt, string key) { System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); RijndaelManaged rijndaelCipher = new RijndaelManaged(); rijndaelCipher.Mode = CipherMode.CBC; rijndaelCipher.Padding = PaddingMode.PKCS7; rijndaelCipher.KeySize = 0x80; rijndaelCipher.BlockSize = 0x80; string decodedUrl = HttpUtility.UrlDecode(textToDecrypt); byte[] encryptedData = Convert.FromBase64String(decodedUrl); byte[] pwdBytes = Encoding.UTF8.GetBytes(key); byte[] keyBytes = new byte[0x10]; int len = pwdBytes.Length; if (len > keyBytes.Length) { len = keyBytes.Length; } Array.Copy(pwdBytes, keyBytes, len); rijndaelCipher.Key = keyBytes; rijndaelCipher.IV = keyBytes; byte[] plainText = rijndaelCipher.CreateDecryptor().TransformFinalBlock(encryptedData, 0, encryptedData.Length); return encoding.GetString(plainText); }
Esto funcionó como un encanto, pero los problemas vinieron cuando traté de hacer lo mismo en iOS. Estoy bastante nuevas aplicaciones en desarrollo para el iphone / ipad, por lo que ofcause lo googled, y casi cada muestra de código proporcionado fue el siguiente:
- (NSData *)AESEncryptionWithKey:(NSString *)key { char keyPtr[kCCKeySizeAES128]; // room for terminator (unused) bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) // fetch key data [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; NSUInteger dataLength = [self length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, keyPtr, kCCKeySizeAES128, NULL /* initialization vector (optional) */, [self bytes], [self length], /* input */ buffer, bufferSize, /* output */ &numBytesEncrypted); if (cryptStatus == kCCSuccess) { //the returned NSData takes ownership of the buffer and will free it on deallocation return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; } free(buffer); //free the buffer; return nil;
}
Tal vez yo era un poco demasiado optimista, cuando esperaba una transición suave aquí, porque cuando el Android me está lanzando algo así como:
"EgQVKvCLS4VKLoR0xEGexA=="
Entonces el iOS me da:
"yP42c9gajUra7n0zSEuVJQ=="
Espero que sea algo que me olvidé, o algunos de los ajustes son malos?
[UPDATE] Los resultados se muestran ahora después de la codificación base64.
- Comunicación punto a punto entre la aplicación móvil y el navegador de PC
- ¿Cómo se configura la dirección IP de la aplicación Phonegap Developer?
- ¿Cómo puedo decirle a mi jefe de trabajo con Xamarin no lo hará más rápido
- ¿Podemos conectarnos al iPhone desde un dispositivo Android aunque no esté en la misma red?
- Autenticación de una aplicación de Android o iPhone en un backend de Django
- La Guía Completa de Cocos2d-x Tutorial & Guía
- Parse Enviar notificación push a un usuario específico desde el código de Cloud
- Xamarin.Forms ListView: establece el color de resaltado de un elemento seleccionado
La primera nota es que tiene importantes problemas de seguridad en este código. Estás tomando una contraseña de cadena y simplemente dejarla en una clave. Si esa cadena es de tipo humano, entonces usted ha reducido dramáticamente su espacio de claves (convirtiendo AES-128 en algo más como AES-40 o AES-50, quizás incluso peor). Usted necesita salar y estirar la llave usando PBKDF2. Consulte Cifrado correcto con AES con CommonCrypto para una discusión más completa.
También tiene un problema importante de seguridad porque está usando su llave como su IV (vea más abajo, esto es realmente la causa de su síntoma). Esta no es la manera correcta de escoger una IV y hace que su texto cifrado sea predecible. Idéntico texto encriptado cifrado con la misma clave dará el mismo resultado. Esto es similar a no tener IV en absoluto. El IV debe ser aleatorio. Vea el enlace anterior para más información.
Ahora a su síntoma real. El problema es que estás usando la clave como el IV en Java y C #, pero estás usando 0 (NULL) como el IV en iOS (el IV no es opcional, estás pasando 0). Es necesario utilizar el mismo IV en todos los casos.
- ClickListener en PagerAdapter se activa en la posición incorrecta
- Escala de un dibujable dentro de un botón?