Leí esta documentación, y escribí algo para cifrar y descifrar una cuerda. Pero no sé cuántos tipos de algoritmos soporta Android.
Con respecto a DES y AES (como documentación de la wiki) hay muchos tipos de ambos, así que, ¿cuál será mejor?
En DES y AES: use AES.
DES y AES son cifrados de bloque: cifran datos por "bloques", donde un bloque es una cantidad de 64 bits (para DES) o de 128 bits (para AES). Para cifrar un "mensaje" que no es un solo bloque, debe usar un "modo de encadenamiento" y posiblemente un "relleno": el modo de encadenamiento define cómo se dividen los datos en bloques y se ensamblan nuevamente, y el relleno consiste en bytes adicionales se agrega al final del mensaje para que la longitud total sea adecuada para cualquier división que utilice el modo de encadenamiento. El relleno debe ser tal que, una vez descifrado, pueda eliminarse sin ambigüedades.
El modo de encadenamiento y el relleno "estándar" se denominan, respectivamente, CBC y PKCS # 5 . El relleno PKCS # 5 agrega entre 1 y n bytes, donde n es la longitud del bloque (por lo tanto, 8 para DES, 16 para AES), por lo que la longitud total rellenada es un múltiplo de n . CBC enlaza los bloques y requiere un Vector de inicialización (IV) que debería ser una secuencia de n bytes aleatorios; es muy importante que los bytes IV se generen con un generador de números aleatorios criptográficamente sólido (es decir, java.security.SecureRandom
) y que genere un nuevo IV para cada mensaje. El IV también debe enviarse (sin cifrar) con el mensaje cifrado, porque el receptor lo necesitará para descifrar los datos.
Para el propio cifrado de bloque: DES viene en dos versiones, el DES "original" y el "Triple-DES", también llamado "3DES" o, a veces, simplemente "DES". El DES original usa una clave de 64 bits, de los cuales se ignoran 8 bits, por lo que la longitud efectiva de la clave es de 56 bits, y eso es demasiado corto para la seguridad. 3DES utiliza una clave de 192 bits (se ignoran 24 bits, por lo que la longitud efectiva de clave de 168 bits) y se considera robusta; también es tres veces más lento que el DES, que ya no es tan rápido.
AES fue diseñado para reemplazar a DES, y en general se piensa que es mejor en todos los aspectos. AES tiene tres sabores, denominados AES-128, AES-192 y AES-256, que difieren en la longitud de la clave (de 128, 192 y 256 bits, respectivamente). 128 bits son más que suficientes para la seguridad, y las claves más largas implican una sobrecarga computacional ligera, por lo que se prefiere una clave de 128 bits.
Para obtener una lista de algoritmos admitidos por una máquina virtual Java, intente esto:
import java.security.Provider;
import java.security.Security;
import java.util.Map;
import java.util.TreeSet;
public class ListAlgo {
public static void main(String[] args)
{
TreeSet<String> algos = new TreeSet<String>();
for (Provider p : Security.getProviders()) {
for (Map.Entry<Object, Object> e : p.entrySet()) {
String s = e.getKey().toString()
+ " -> " + e.getValue().toString();
if (s.startsWith("Alg.Alias.")) {
s = s.substring(10);
}
algos.add(s);
}
}
for (String a : algos) {
System.out.println(a);
}
}
}
(Esto es para Java "normal"; para Android probablemente necesitarás cambiar un poco las cosas con respecto a la salida final).
Los algoritmos de cifrado serán aquellos en los que la cadena comience por " Cipher.
". De todos modos, si desea la combinación de algoritmos más ampliamente admitida, será " AES/CBC/PKCS5Padding
" con una clave de 128 bits: si un Android dado admite un solo cifrado, lo admitirá.
Si se encuentra en una situación en la que se justifica el cifrado, entonces es probable que también necesite una verificación de integridad; ver javax.crypto.Mac
. Para una MAC, en caso de duda, utilice HMAC con SHA-256 (si no se admite SHA-256, retroceda a HMAC con SHA-1).
Encontré que estas configuraciones funcionan en Android 1.5:
SYMMETRIC_ALGORITHM = "AES/CBC/PKCS5Padding";
SECRET_KEY_ALGORITHM = "AES";
SECRET_KEY_SIZE_BYTES = 16; // 128 bit
MAC_ALGORITHM = "HmacSHA1";
MAC_OUTPUT_SIZE_BYTES = 20; // 160 bit SHA-1
PRIVATE_PUBLIC_ALGORITHM = "RSA/NONE/PKCS1Padding";
Conté con que BouncyCastle estaba en Android y puse BouncyCastle en mi proyecto del lado del servidor, solo un frasco (bcprov-jdk16-145.jar). No hay plug-in de eclipse, por lo que tuve que colocarlo en el directorio lib / ext del JRE que estaba usando el proyecto de eclipse.
Sin embargo, publicaciones como this me hacen sospechar que aún podría funcionar con dispositivos que no tienen los algoritmos que necesito.
Android podría admitir cualquiera a través de las librerías java de bouncy castle. Estoy buscando un puerto openssl para android usando el NDK para hacerlo más rápido, pero ya veremos.
Lea otras preguntas en las etiquetas cryptography encryption android mobile