1

在java中使用加密库在速度上不稳定第一轮比其他轮花费很多时间,一段时间后执行加密所需的时间是稳定的为什么这是以及如何从一开始就达到稳定,如果需要一些intail code我可以做到,但我知道需要调用 encrypt 方法来花费大量时间,请查看代码和包含结果的最后一行。

此类包含加密/解密的静态方法

package karp.generalutil.common;

import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;


public class Encryptor {

/**
 * @param args
 */

static Cipher eCipher,dCipher;

public Encryptor()
{
    try {
        eCipher=Cipher.getInstance("AES");
        dCipher=Cipher.getInstance("AES");
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

/// for test
public static void main (String args[])
{
try {
    KeyGenerator aes;


    aes = KeyGenerator.getInstance("AES");

    aes.init(128);

    SecretKey key = aes.generateKey();






} catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

}


public static String encrypt(String clearText,String keyString) throws NoSuchAlgorithmException, 
                                                       NoSuchPaddingException, InvalidKeyException,
                                                        IllegalBlockSizeException, BadPaddingException
{


    SecretKey key=loadKey(keyString);
    String encryptedText;

    eCipher.init(Cipher.ENCRYPT_MODE,key );
    encryptedText=new String(eCipher.doFinal(clearText.getBytes()));





    return encryptedText;
}

public static String decrypt(String encryptedText,String keyString) throws NoSuchAlgorithmException, 
                                                           NoSuchPaddingException, InvalidKeyException,
                                                           IllegalBlockSizeException, BadPaddingException
{

    SecretKey key=loadKey(keyString);
    String clearText;
    Cipher dCipher=Cipher.getInstance("AES");
    dCipher.init(Cipher.DECRYPT_MODE,key);
    clearText=new String(dCipher.doFinal(encryptedText.getBytes()));





    return clearText;


}


public static byte[] encrypt(byte [] clearByteArray,String keyString)throws NoSuchAlgorithmException, 
                                                            NoSuchPaddingException, InvalidKeyException,
                                                            IllegalBlockSizeException, BadPaddingException
{

    SecretKey key=loadKey(keyString);
    byte[] encryptedByteArray;
    Cipher eCipher=Cipher.getInstance("AES");
    eCipher.init(Cipher.ENCRYPT_MODE,key );
    encryptedByteArray=eCipher.doFinal(clearByteArray);

    return encryptedByteArray;
}


public static byte[] decrypt(byte [] encryptedByteArray,String keyString)throws NoSuchAlgorithmException, 
                                                            NoSuchPaddingException, InvalidKeyException,
                                                            IllegalBlockSizeException, BadPaddingException
{
    SecretKey key=loadKey(keyString);
    byte[] clearByteArray;

    Cipher dCipher=Cipher.getInstance("AES");
    dCipher.init(Cipher.DECRYPT_MODE,key );
    clearByteArray=dCipher.doFinal(encryptedByteArray);
    return clearByteArray;
}

public static SecretKey loadKey(String  keyString)  {

        byte[] encoded = keyString.getBytes();

        SecretKey key = new SecretKeySpec(encoded, "AES");
        return key;
    }

}

这是测试类

import java.io.ByteArrayInputStream;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.sql.Timestamp;
import java.util.Date;





public class tesst {

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {


            long y1,y2;
            y1=System.nanoTime();
            Encryptor e=new Encryptor();
            String keyString="”{¶¹û¼«I?q-׫л•";
            e.encrypt(new byte[31], "”{¶¹û¼«I?q-׫л•");
             y2=System.nanoTime()-y1;
                System.out.println("ini:"+y2);

            for(int i=0;i<100000;i++)
            {   byte [] x=new byte [31];
                y1=System.nanoTime();

        byte [] y=e.encrypt(x, "”{¶¹û¼«I?q-׫л•");



        y2=System.nanoTime()-y1;
        System.out.println(y2);
            }



                    } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

第一个循环大约需要 193650106 ns 第二个循环大约需要 126150 ns 在 150 循环之后加密时间减少到 11546 ns

4

1 回答 1

5

要执行有意义的基准测试,请使用Java Microbenchmark Harness (JMH) 工具。

Java 虚拟机在针对底层硬件架构优化代码之前对运行代码进行分析。这会导致所有代码(不仅仅是 AES 加密)在一段时间后运行得更快。


关于您的加密代码本身,它有一些问题。(它们不会影响速度,但有缺陷的代码有多快并不重要。)

首先,您应该明确说明密码正在使用的模式和填充。"AES"通常,您应该使用类似的东西来代替"AES/CBC/PKCS5Padding". 这样,当您与另一个应用程序进行互操作时,您将能够告诉他们您使用了哪些算法。

其次,加密的结果看起来像随机字节。这些字节是字符串的有效编码的机会几乎为零。因此,当您简单地String从密文创建一个新对象时,您可能会丢失一些信息,因为字符解码器会将任何无法识别的字节替换为 � 字符。相反,使用 Base-64-encoding 之类的东西将二进制数据编码为 ASCII 字符。这同样适用于您的“密钥字符串”。

于 2013-06-15T16:45:12.197 回答