¿Es AES (Rijndael) más rápido que Blowfish?

3

Sé que teórico que el pez globo es mucho más rápido que aes. Pero comparé varios algoritmos, incluidos aes y blowfish, para archivos de 1MB, 5MB, 10MB, etc. en la plataforma java 8 y la biblioteca del castillo hinchable. En todos los escenarios de prueba, aes es más rápido que el pez globo.

Me pregunto si me equivoco en alguna parte?

Aquí está el código:

private static final int WARMUP_COUNT = 5;
private static final int FILE_LENGTH = 1024*512;
private static final int ITERATOR_COUNT = 1000;
private static final double BOLME = 1_000_000.0 * (ITERATOR_COUNT-WARMUP_COUNT);
static final private byte[] ivBytes = new byte[] { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
private static final IvParameterSpec ivSpec16bytes = new IvParameterSpec(ivBytes);
private static final IvParameterSpec ivSpec8bytes = new IvParameterSpec(Arrays.copyOfRange(ivBytes,0,8));

static String[] algosWithMode = {"AES/CBC/PKCS7Padding","Blowfish/CBC/PKCS7Padding","CAST5/CBC/PKCS7Padding","DES/CBC/PKCS7Padding","DESede/CBC/PKCS7Padding",  "IDEA/CBC/PKCS7Padding","ARC4", };
static String[] algos = {   "AES","Blowfish","CAST5","DES", "DESede","IDEA","ARC4"  };
static int[] keylenngth = {128,128,128,56,  168,128,128 };


@SuppressWarnings("unused")
public static void main(String[] args) throws Exception {

    if(ITERATOR_COUNT <= WARMUP_COUNT )
        throw new Exception("iterator count must be greater than warm up count iterator: "+ITERATOR_COUNT
                +" warmup count :" + WARMUP_COUNT);

    Security.addProvider(new BouncyCastleProvider());
    Key key = null;
    byte[] plainText=null;
    byte[] cipherText=null;
    byte[] decryptedText=null;
    long startTime;
    DecimalFormat df = new DecimalFormat("0.000"); 


    for (int k = 0; k < 7; k++) {

        long timeDec = 0,timeEnc = 0,timekey = 0;
        long maxtimeDec = 0,maxtimeEnc = 0,maxtimekey = 0;
        long mintimeDec = Long.MAX_VALUE,mintimeEnc = Long.MAX_VALUE,mintimekey = Long.MAX_VALUE;
        long topDec = 0,topEnc = 0,topkey = 0;



        for (int i = 0; i < ITERATOR_COUNT; i++) {



            SecureRandom random= new SecureRandom();
            plainText = random.generateSeed(FILE_LENGTH);


            startTime=System.nanoTime();
            KeyGenerator keyGen = KeyGenerator.getInstance(algos[k]);
            keyGen.init(keylenngth[k],random);
            key=keyGen.generateKey();
            timekey=System.nanoTime()-startTime;


            Cipher cipher=null;
            if(k == 0){
                 cipher = Cipher.getInstance(algosWithMode[k]);   
                 cipher.init(Cipher.ENCRYPT_MODE, key,ivSpec16bytes); 
            }else if(k == 6){
                cipher = Cipher.getInstance(algosWithMode[k]);   
                cipher.init(Cipher.ENCRYPT_MODE, key); 
            }else{
                cipher = Cipher.getInstance(algosWithMode[k]);   
                cipher.init(Cipher.ENCRYPT_MODE, key,ivSpec8bytes);
            }

            startTime=System.nanoTime();
            cipherText = cipher.doFinal(plainText);
            timeEnc=System.nanoTime()-startTime;


            if(k == 0){
                 cipher = Cipher.getInstance(algosWithMode[k]);   
                 cipher.init(Cipher.DECRYPT_MODE, key,ivSpec16bytes); 
            }else if(k== 6){
                cipher = Cipher.getInstance(algosWithMode[k]);   
                cipher.init(Cipher.DECRYPT_MODE, key); 
            }else {
                cipher = Cipher.getInstance(algosWithMode[k]);   
                cipher.init(Cipher.DECRYPT_MODE, key,ivSpec8bytes);
            }

            startTime=System.nanoTime();
            cipher.doFinal(cipherText);
            timeDec=System.nanoTime()-startTime;

            if (i >= WARMUP_COUNT) {
                if (maxtimeEnc < timeEnc)
                    maxtimeEnc = timeEnc;
                if (maxtimeDec < timeDec)
                    maxtimeDec = timeDec;
                if (maxtimekey < timekey)
                    maxtimekey = timekey;
                if (mintimeEnc > timeEnc)
                    mintimeEnc = timeEnc;
                if (mintimeDec > timeDec)
                    mintimeDec = timeDec;
                if (mintimekey > timekey)
                    mintimekey = timekey;
                topEnc += timeEnc;
                topDec += timeDec;
                topkey += timekey;
            }



        }
        double avgEnc=topEnc/BOLME;
        double avgDec=topDec/BOLME;
        double avgKey=topkey/BOLME;
        System.out.println("********************************************************"+algos[k]+"*****************************************************************");
        System.out.println("Avg Enc :"+df.format(avgEnc)+" - "+" Avg Dec :"+df.format(avgDec)+"-"+" Avg Key :"+ df.format(avgKey));
        System.out.println("Max Enc :"+df.format(maxtimeEnc/1_000_000.0)+" - "+" Max Dec :"+df.format(maxtimeDec/1_000_000.0)+"-"+" Max Key :"+ df.format(maxtimekey/1_000_000.0));
        System.out.println("Min Enc :"+df.format(mintimeEnc/1_000_000.0)+" - "+" Min Dec :"+df.format(mintimeDec/1_000_000.0)+"-"+" Min Key :"+ df.format(mintimekey/1_000_000.0));
        System.out.println();
        //System.out.println();

    }


}
    
pregunta ersan 26.05.2014 - 16:48
fuente

2 respuestas

6

En teoría, se supone que Blowfish es más rápido que AES, pero no mucho más rápido. Consulte esta pregunta para obtener más información.

Luego hay optimización . Para un algoritmo dado, puede definir de alguna manera su "velocidad máxima" como el rendimiento alcanzado con un código óptimo; pero las implementaciones reales nunca son completamente óptimas, y cuán cerca (o lejos) de la optimalidad depende de los esfuerzos invertidos en ellas. AES es grande y se usa mucho; para que las personas que escriben implementaciones de AES se encarguen de ajustar su código para que sea rápido en la mayoría de las arquitecturas, incluso en las más nuevas. Blowfish, por otro lado, tiene una base de uso decreciente, por buenas razones (tiene bloques de 64 bits, que no son lo suficientemente grandes para garantizar la seguridad cuando se cifran gigabytes de datos con una clave determinada). Por lo tanto, se puede suponer que en una biblioteca criptográfica determinada, es más probable que las implementaciones de AES se hayan optimizado y mantenido que las implementaciones de Blowfish.

Otros puntos:

  • Aunque el cifrado de Blowfish es rápido, el key schedule (que transforma la clave en tablas internas listas para procesar una gran cantidad de datos) es muy lento en Blowfish. En su código, parece que intenta medir la velocidad de cifrado "en su conjunto". Si desea medir la velocidad de cifrado sin formato, primero debe cifrar, digamos, un megabyte (para asegurarse de que se haya producido la programación de claves y de que se hayan completado todos los cachés); luego mida la velocidad de cifrado de 10 o 100 megabytes más.

  • Blowfish es rápido porque funciona en muchas búsquedas en una caja S dependiente de la clave (una tabla de 4 kB). En Java, se verifican los accesos a la matriz (el índice debe caer dentro de la longitud de la matriz), lo que los hace relativamente más lentos que otras operaciones. Los algoritmos de encriptación que son pesados en los accesos de matrices incurren en un factor de desaceleración en comparación con los algoritmos que se expresan como operaciones aritméticas (un caso típico es RC4). Esto puede explicar por qué un Blowfish basado en Java no parece tan eficiente (comparado con un AES basado en Java) como un Blowfish basado en C (comparado con un AES basado en C).

  • Las CPU modernas tienen opcodes AES especializados , lo que implica un cifrado AES muy rápido. Una biblioteca Java pura no puede usar estos códigos de operación, pero Java puede llamar código nativo. Si su biblioteca usa código nativo para invocar los códigos de operación AES-NI, entonces el cifrado AES será necesariamente un gritón y Blowfish no podrá competir.

respondido por el Tom Leek 26.05.2014 - 17:30
fuente
0

Las modernas CPU x86 proporcionan aceleración de hardware para el cifrado / descifrado AES, que es habilitado en la JVM . Aunque Blowfish podría ser más rápido en AES en implementaciones de software, la aceleración de hardware lo hace mucho más rápido.

Por cierto, esta pregunta debería estar en Desbordamiento de pila, no aquí.

    
respondido por el DCKing 26.05.2014 - 17:14
fuente

Lea otras preguntas en las etiquetas