首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >AES(Rijndael)比龙虾快吗?

AES(Rijndael)比龙虾快吗?
EN

Security用户
提问于 2014-05-26 14:48:39
回答 2查看 2.9K关注 0票数 3

我知道理论上河豚比aes快得多。但是,我在java 8平台和弹跳城堡库中对一些算法进行了测试,包括aes和用于1MB、5MB、10MB等文件的河豚。在每一种测试场景中,aes都比河豚快。

我想知道我在哪里犯了错误?

以下是代码:

代码语言:javascript
运行
复制
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();

    }


}
EN

回答 2

Security用户

发布于 2014-05-26 15:30:38

理论上,Blowfish应该比AES更快,但不会更快。有关详细信息,请参阅这个问题

然后是优化。对于给定的算法,您可以以某种方式将其“最高速度”定义为使用最优代码实现的性能;但是实际的实现从来都不是完全最优的,它们离最优性有多近(或多远)取决于它们所投入的努力。AES很大,而且使用很多;所以编写AES实现的人要小心地调优他们的代码,以便在大多数体系结构(包括最新的架构)上快速运行。另一方面,河豚有一个越来越少的使用基础,有很好的理由(它有64位块,不足以确保安全时,当千兆字节的数据是用一个给定的密钥加密)。因此,可以假设在给定的密码库中,AES实现比Blowfish实现更有可能得到优化和维护。

其他要点:

  • 虽然Blowfish加密速度快,但是密钥调度(将密钥转换为内部表以便于处理大量数据)在Blowfish中非常慢。在您的代码中,您似乎试图测量加密的速度“作为一个整体”。如果要测量原始加密速度,应该首先加密1 of (以确保密钥调度已经发生并填充了所有缓存);然后测量10或100 of的加密速度。
  • 河豚速度很快,因为它可以在依赖密钥的S盒(4 kB表)中进行大量查找。在Java中,数组访问被检查(索引必须在数组长度之内),这使得它们比其他操作慢一些。因此,与用算术运算表示的算法(典型的例子是RC4)相比,加密算法在数组访问方面会产生一个减速因素。这可能解释了为什么基于Java的Blowfish不像基于C的Blowfish (与基于C的AES相比)那么高效(与基于Java的AES相比)。
  • 现代CPU有专用AES操作码,这意味着非常快的AES加密。纯Java库不能使用这些操作码,但是Java可以调用本机代码。如果您的库使用本地代码调用AES-NI操作码,那么AES加密必然是一个尖叫器,而Blowfish将无法与之竞争。
票数 6
EN

Security用户

发布于 2014-05-26 15:14:26

现代的x86 CPU为AES加密/解密提供了硬件加速,即在JVM中启用。虽然在软件实现中,Blowfish在AES中可能更快,但是硬件加速使它更快。

顺便说一下,这个问题应该是堆栈溢出的,而不是这里。

票数 0
EN
页面原文内容由Security提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://security.stackexchange.com/questions/58756

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档