Search code examples
javaperformanceencryptionjcemessage-digest

Why SHA1 is slower than AES? JCE


I'm currently building applications, which uses crypto primitives. For encryption and hashing I use javax.crypto and java.security packages. I did some benchmarking and it turned out, that ECB-AES-128 is faster than SHA1. Code that I used for AES testing:

    byte[] key = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
    byte[] data = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

    SecretKeySpec encryptionKey = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, encryptionKey);

    long start = System.currentTimeMillis();
    for (int i=0; i<10000000; i++)
    {
        cipher.doFinal(data);
    }
    long end = System.currentTimeMillis();      

    System.out.println("took: "+ (end-start));

For hashing

    MessageDigest md = MessageDigest.getInstance("SHA-1");
    byte[] data = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};


    long start = System.currentTimeMillis();
    for (int i=0; i<10000000; i++)
    {
        md.digest(data);
    }
    long end = System.currentTimeMillis();

    System.out.println("took:" + (end-start));

Encryption time takes : ~4sec. Hashing time takes: ~10sec. Config: Core i5 3570-3.4Ghz, 8Gb RAM (not sure , whether it matters)

Why encryption takes less time than hashing? Hash functions should be way faster. Am I doing something wrong? Thank you


Solution

  • Please find the results for openssl speed sha1 aes-128-cbc below:

    The 'numbers' are in 1000s of bytes per second processed.
    type             16 bytes     64 bytes    256 bytes   1024 bytes   8192 bytes
    sha1             27821.86k    81142.78k   181461.85k   272193.19k   312980.82k
    aes-128 cbc      55984.60k    63748.01k    64728.23k   104889.11k   107399.85k
    

    As you can see AES is faster for smaller amounts, and slower for large amounts. Why does this happen? Well, simple. AES uses a block size of 128 bits while SHA-1 uses a block size of 512 bits. So for small amounts of data, SHA-1 has to do much more work. Note that for 64 bytes, SHA-1 has to use 2 full blocks, so it is still rather at a disadvantage. Because of the bigger state size, I expect it will also optimize less easily.

    AES is usually also heavily optimized. I'm not sure that SHA-1 in Java has seen the same amount of interest. Nowadays, you would rather look at SHA-2.