2013-06-15 2 views
1

자바에서 암호화 라이브러리를 사용하는 속도가 안정적이지 않습니다. 첫 번째 라운드는 다른 것보다 많은 시간이 걸리고 잠시 후에 암호화를 수행하는 데 필요한 시간이 안정되어 있습니다. 일부 intail 코드가 필요한 경우 시작, 나는 그것을 할 수 있지만 시간이 그 시간을 amound 걸릴 암호화 메서드의 호출이 필요한 결과를 포함하는 코드와 최종 줄을 참조하십시오.자바에서 AES의 성능을 향상

이 클래스는 이것을 첫 번째 루프는 약 193,650,106 NS 에게 2 루프을

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(); 
     } 
    } 

} 

테스트 클래스 150 루프 후 약 126,150 NS에게 걸릴/

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; 
    } 

} 

해독 암호화 정적 메소드를 포함 암호화 시간이 11546 ns로 단축됩니다.

답변

4

Java 코드를 벤치마킹 할 때는 항상 측정을 시작하기 전에 벤치 마크 된 코드를 수천 번 반복하십시오. 서버 모드의 Oracle JVM의 경우 최소한 10000 회 반복 수행하십시오. 그런 다음 벤치 마크 코드를 몇 초 동안 실행하고 평균 실행 시간을 찾습니다.

대부분의 Java 가상 머신은 기본 하드웨어 아키텍처를 위해 최적화하기 전에 실행중인 코드의 프로필을 작성하는 "Just-In-Time"컴파일 전략을 사용합니다. 이로 인해 AES 암호화뿐만 아니라 모든 코드가 잠시 후에 훨씬 빠르게 실행됩니다.

JIT 컴파일은 JIT 컴파일이 시작될 때 일반적으로 임계 값을 일부 제어합니다. (See -XX:CompileThreshold.) 절충안이 있습니다. 임계 값을 너무 낮게 설정하면 JVM은 시간을 회수하기에 충분히 자주 실행되지 않는 시간 최적화 코드를 낭비합니다. 너무 높게 설정하면 코드가 최적화되지 않습니다.

응용 프로그램이 시작되는 Java 프로세스이고 단일 AES 작업을 수행 한 다음 종료하면 이러한 설정을 조정하여 성능을 향상시킬 수 있는지 (임계 값을 낮춤으로써) 확인할 가치가 있습니다.

응용 프로그램이 더 복잡하고 프로세스 수명주기 동안 암호화 작업이 여러 번 발생할 경우 초기 성능에 대해 걱정하지 않아도됩니다. 그것은 한동안 사라질 "가장자리 효과"입니다.


암호화 코드 자체와 관련하여 몇 가지 문제가 있습니다. (속도에는 영향을주지 않지만 버그 코드의 속도는 중요하지 않습니다.)

먼저 암호가 사용하는 모드와 패딩에 대해 명시해야합니다. 일반적으로 "AES" 대신 "AES/CBC/PKCS5Padding"과 같은 것을 사용해야합니다. 그렇게하면 다른 응용 프로그램과 상호 작용할 때 사용한 알고리즘을 그들에게 알릴 수 있습니다.

두 번째로 암호화 결과는 임의의 바이트처럼 보입니다. 문자 스트링의 유효한 인코딩 인 이들 바이트의 가능성은 거의 제로입니다. 따라서 암호문에서 새 String 개체를 간단하게 만들면 문자 디코더가 인식 할 수없는 바이트를 & # xFFFD로 바꾸기 때문에 정보가 손실 될 수 있습니다. 캐릭터. 대신 Base-64 – 인코딩을 사용하여 이진 데이터를 ASCII 문자로 인코딩하십시오. "키 문자열"에도 동일하게 적용됩니다.

+0

죄송합니다. 1 회 투표를 할 수 없으므로, 하드웨어 (Java가 아닌), 네트워크 카드 (예 : 네트워크 카드)가 11000 ns 인 경우 내 메소드에 필요한 시간을 말할 수 있습니다.나는 인증을 추가하고 새로운 프로토콜의 성능을 연구 할 필요가있는 ARP 개선을 연구 중이므로 최적화를 기다리는 동안 새로운 프로토콜에 많은 오버 헤드가 추가됩니다. 이 문지르기를 이클립스를 사용하여 낮추는 데 도움이 될 수 있도록 전체 문서를 읽을 필요가 없습니다. –

+0

이 임계 값을 낮춰야합니까? "-XX : CompileThreshold" –

+0

@MohammedFalha 내 대답의 시작 부분에있는 업데이트를 참조하십시오. 테스트에서 올바른 접근법을 취하는 것 같지 않습니다. – erickson

관련 문제