He encontrado muchos ejemplos de cómo hacer el cifrado en C#, y un par para Android, pero estoy buscando especialmente una forma de manejar el cifrado (usando algo como AES, TripleDES, etc. .) de Android, y finalmente terminan siendo descifrados en C#. Encontré un example for encoding AES en Android y encoding/decoding AES en C# pero no estoy seguro si estos son compatibles (C# requiere un IV, no se especifica nada para esto en el ejemplo de Android). Además, una recomendación sobre una buena forma de codificar la cadena encriptada para la transmisión a través de HTTP (Base64?) Sería útil. Gracias.Cifrado compatible entre Android y C#
Respuesta
Recibí ayuda del http://oogifu.blogspot.com/2009/01/aes-in-java-and-c.html.
Aquí es mi clase Java:
package com.neocodenetworks.smsfwd;
import java.security.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import android.util.Log;
public class Crypto {
public static final String TAG = "smsfwd";
private static Cipher aesCipher;
private static SecretKey secretKey;
private static IvParameterSpec ivParameterSpec;
private static String CIPHER_TRANSFORMATION = "AES/CBC/PKCS5Padding";
private static String CIPHER_ALGORITHM = "AES";
// Replace me with a 16-byte key, share between Java and C#
private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
private static String MESSAGEDIGEST_ALGORITHM = "MD5";
public Crypto(String passphrase) {
byte[] passwordKey = encodeDigest(passphrase);
try {
aesCipher = Cipher.getInstance(CIPHER_TRANSFORMATION);
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "No such algorithm " + CIPHER_ALGORITHM, e);
} catch (NoSuchPaddingException e) {
Log.e(TAG, "No such padding PKCS5", e);
}
secretKey = new SecretKeySpec(passwordKey, CIPHER_ALGORITHM);
ivParameterSpec = new IvParameterSpec(rawSecretKey);
}
public String encryptAsBase64(byte[] clearData) {
byte[] encryptedData = encrypt(clearData);
return net.iharder.base64.Base64.encodeBytes(encryptedData);
}
public byte[] encrypt(byte[] clearData) {
try {
aesCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
} catch (InvalidKeyException e) {
Log.e(TAG, "Invalid key", e);
return null;
} catch (InvalidAlgorithmParameterException e) {
Log.e(TAG, "Invalid algorithm " + CIPHER_ALGORITHM, e);
return null;
}
byte[] encryptedData;
try {
encryptedData = aesCipher.doFinal(clearData);
} catch (IllegalBlockSizeException e) {
Log.e(TAG, "Illegal block size", e);
return null;
} catch (BadPaddingException e) {
Log.e(TAG, "Bad padding", e);
return null;
}
return encryptedData;
}
private byte[] encodeDigest(String text) {
MessageDigest digest;
try {
digest = MessageDigest.getInstance(MESSAGEDIGEST_ALGORITHM);
return digest.digest(text.getBytes());
} catch (NoSuchAlgorithmException e) {
Log.e(TAG, "No such algorithm " + MESSAGEDIGEST_ALGORITHM, e);
}
return null;
}
}
que utilizan http://iharder.sourceforge.net/current/java/base64/ para la codificación base64.
Aquí es mi clase C#:
using System;
using System.Text;
using System.Security.Cryptography;
namespace smsfwdClient
{
public class Crypto
{
private ICryptoTransform rijndaelDecryptor;
// Replace me with a 16-byte key, share between Java and C#
private static byte[] rawSecretKey = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
public Crypto(string passphrase)
{
byte[] passwordKey = encodeDigest(passphrase);
RijndaelManaged rijndael = new RijndaelManaged();
rijndaelDecryptor = rijndael.CreateDecryptor(passwordKey, rawSecretKey);
}
public string Decrypt(byte[] encryptedData)
{
byte[] newClearData = rijndaelDecryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
return Encoding.ASCII.GetString(newClearData);
}
public string DecryptFromBase64(string encryptedBase64)
{
return Decrypt(Convert.FromBase64String(encryptedBase64));
}
private byte[] encodeDigest(string text)
{
MD5CryptoServiceProvider x = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] data = Encoding.ASCII.GetBytes(text);
return x.ComputeHash(data);
}
}
}
Realmente espero que esto ayude a alguien más!
Sí ... Me encanta cuando las personas responden mi pregunta técnica con un montón de "Oh, deberías hacer eso" o "Oh, deberías hacer esto". Gracias por ser práctico y por dejar la implementación de su clase. – kape123
He cifrado el contenido de mi archivo con su código Java y he guardado el contenido cifrado en encrypted.txt. Ahora me gustaría descifrarlo con la herramienta openssl usando este comando: openssl enc -d -a -p -aes-256-cbc -salt -in encrypted.txt -out descrypted.txt -pass pass: myPassword pero me da error: mal número mágico ¿Alguna idea de lo que está mal? Incluso si elimino el parámetro -salt del comando, sigo recibiendo el mismo error. – uerceg
@uerceg: Vas a querer comenzar una nueva pregunta para eso. Esta solución no usa OpenSSL, así que no espero que funcione. – Jess
Sí, debería estar bien, siempre que el tamaño de la clave sea el mismo: AES de 128 bits y el modo de cifrado de bloque correcto (CBC). Es posible que tenga problemas con el relleno, pero eso debería ser bastante fácil de resolver. Me encontré con estos problemas con Java y Python recientemente, pero al final todo funcionó. Base64 para la codificación debería estar bien sobre HTTP. ¡Buena suerte!
Si implementa correctamente el mismo cifrado (como AES) y el modo (como CTR, CFB, CCM, etc.) en ambos extremos, el texto cifrado de un extremo se puede descifrar por el otro extremo independientemente de la plataforma.
El ejemplo de Android al que ha vinculado parece utilizar el modo ECB, y por lo tanto no es seguro para sus propósitos. Es sumamente importante que comprenda las implicaciones del modo de bloque que selecciona. Es muy fácil equivocarse en este nivel, lo que da como resultado un sistema que no es tan seguro como crees.
EDITAR: Retiro esto, no está utilizando ECB, pero la forma en que genera la IV no es práctica. En cualquier caso, mi punto de entender las implicaciones de los modos de bloque se mantiene.
Puede comenzar con este wikipedia article. El libro de Bruce Schneier 'Practical Cryptography' también es muy valioso para cualquiera que implemente seguridad criptográfica.
En cuanto a la codificación de la cadena, si debe convertir la cadena en texto ASCII, Base64 es una buena manera, pero le sugiero que investigue el uso de HTTP PUT o POST para evitar este paso adicional.
En la muestra C# código fuente proporcionado, cuidado con esta línea:
Encoding.ASCII.GetString(newClearData);
UTF-8 es la codificación predeterminada para Android, cuerda de manera encriptada (especialmente los caracteres no ASCII como el chino) serán pasados a C# asumiendo UTF-8. El texto se convierte codificado si se decodifica de nuevo en cadena usando codificación ASCII. Aquí está uno mejor,
Encoding.UTF8.GetString(newClearData);
Gracias!
La mayoría de los ejemplos en Internet son una implementación débil de AES. Para que una implementación sea fuerte, se debe usar IV aleatoria todo el tiempo y la clave debe ser hash.
Para más segura (IV + aleatoria clave hash) multiplataforma (Android, iOS, C#) la implementación de AES ver mi respuesta aquí - https://stackoverflow.com/a/24561148/2480840
- 1. cifrado RSA: Diferencia entre Java y Android
- 2. Encriptación compatible entre C# y PHP, ColdFusion, Ruby, Python
- 3. Cifrado AES y C#
- 4. Diferencia entre codificación y cifrado
- 5. Diferencia entre cifrado .NET y PHP
- 6. Cómo conseguir la compatibilidad entre C# y cifrado AES SQL2k8?
- 7. Android 2.1: Cifrado Bluetooth
- 8. ¿Qt es compatible con el cifrado RSA?
- 9. Diferencia entre C7 Compatible y Program Database
- 10. ¿Cifrado y cifrado son diferentes?
- 11. Cifrado de Android
- 12. Cifrado básico en Android
- 13. Cifrado de Blowfish en android
- 14. cifrado sqlite para Android
- 15. cifrado y descifrado con RSAServiceProvider en C#
- 16. caché local Biblioteca C# (persistente y cifrado)
- 17. cifrado César en C++
- 18. C++ AES Cifrado clase
- 19. Cifrado César en C#
- 20. Android ICS dispositivo de cifrado
- 21. Compatible con Android JDBC
- 22. ¿Cuál es la diferencia entre el cifrado SHA y AES?
- 23. Relación entre entrada y longitud de texto cifrado en AES
- 24. ¿Cuál es la diferencia entre el cifrado GET y POST?
- 25. Diferencia en cifrado blowfish entre perl y ruby
- 26. Cifrado de cadenas en C# y Objectivo c
- 27. SQLite en C y compatible con REGEXP
- 28. C++ Vector Math y OpenGL compatible
- 29. ¿Es esta interfaz binaria compatible entre MSVC y mingw?
- 30. Cifrado SQL y ColdFusion
El enlace está muerto. ¿Puedes agregar el fragmento de código que usaste para Android? –