के साथ धीमी एईएस जीसीएम एन्क्रिप्शन और डिक्रिप्शन मैं एईएस/जीसीएम/नोपैडिंग का उपयोग कर डेटा एन्क्रिप्ट और डिक्रिप्ट करने की कोशिश कर रहा हूं। मैंने जेसीई असीमित शक्ति नीति फ़ाइलों को स्थापित किया और नीचे (सरल दिमागी) बेंचमार्क चलाया। मैंने ओपनएसएसएल का उपयोग करके ऐसा ही किया है और 1 जीबी/एस मेरे पीसी पर एन्क्रिप्शन और डिक्रिप्शन प्राप्त करने में सक्षम था।जावा 8u20
नीचे दिए गए बेंचमार्क के साथ मैं केवल उसी पीसी पर जावा 8 का उपयोग करके 3 एमबी/एस एन्क्रिप्शन और डिक्रिप्शन प्राप्त करने में सक्षम हूं। कोई आइडिया है कि मैं क्या गलत कर रहा हूँ?
public static void main(String[] args) throws Exception {
final byte[] data = new byte[64 * 1024];
final byte[] encrypted = new byte[64 * 1024];
final byte[] key = new byte[32];
final byte[] iv = new byte[12];
final Random random = new Random(1);
random.nextBytes(data);
random.nextBytes(key);
random.nextBytes(iv);
System.out.println("Benchmarking AES-256 GCM encryption for 10 seconds");
long javaEncryptInputBytes = 0;
long javaEncryptStartTime = System.currentTimeMillis();
final Cipher javaAES256 = Cipher.getInstance("AES/GCM/NoPadding");
byte[] tag = new byte[16];
long encryptInitTime = 0L;
long encryptUpdate1Time = 0L;
long encryptDoFinalTime = 0L;
while (System.currentTimeMillis() - javaEncryptStartTime < 10000) {
random.nextBytes(iv);
long n1 = System.nanoTime();
javaAES256.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new GCMParameterSpec(16 * Byte.SIZE, iv));
long n2 = System.nanoTime();
javaAES256.update(data, 0, data.length, encrypted, 0);
long n3 = System.nanoTime();
javaAES256.doFinal(tag, 0);
long n4 = System.nanoTime();
javaEncryptInputBytes += data.length;
encryptInitTime = n2 - n1;
encryptUpdate1Time = n3 - n2;
encryptDoFinalTime = n4 - n3;
}
long javaEncryptEndTime = System.currentTimeMillis();
System.out.println("Time init (ns): " + encryptInitTime);
System.out.println("Time update (ns): " + encryptUpdate1Time);
System.out.println("Time do final (ns): " + encryptDoFinalTime);
System.out.println("Java calculated at " + (javaEncryptInputBytes/1024/1024/((javaEncryptEndTime - javaEncryptStartTime)/1000)) + " MB/s");
System.out.println("Benchmarking AES-256 GCM decryption for 10 seconds");
long javaDecryptInputBytes = 0;
long javaDecryptStartTime = System.currentTimeMillis();
final GCMParameterSpec gcmParameterSpec = new GCMParameterSpec(16 * Byte.SIZE, iv);
final SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
long decryptInitTime = 0L;
long decryptUpdate1Time = 0L;
long decryptUpdate2Time = 0L;
long decryptDoFinalTime = 0L;
while (System.currentTimeMillis() - javaDecryptStartTime < 10000) {
long n1 = System.nanoTime();
javaAES256.init(Cipher.DECRYPT_MODE, keySpec, gcmParameterSpec);
long n2 = System.nanoTime();
int offset = javaAES256.update(encrypted, 0, encrypted.length, data, 0);
long n3 = System.nanoTime();
javaAES256.update(tag, 0, tag.length, data, offset);
long n4 = System.nanoTime();
javaAES256.doFinal(data, offset);
long n5 = System.nanoTime();
javaDecryptInputBytes += data.length;
decryptInitTime += n2 - n1;
decryptUpdate1Time += n3 - n2;
decryptUpdate2Time += n4 - n3;
decryptDoFinalTime += n5 - n4;
}
long javaDecryptEndTime = System.currentTimeMillis();
System.out.println("Time init (ns): " + decryptInitTime);
System.out.println("Time update 1 (ns): " + decryptUpdate1Time);
System.out.println("Time update 2 (ns): " + decryptUpdate2Time);
System.out.println("Time do final (ns): " + decryptDoFinalTime);
System.out.println("Total bytes processed: " + javaDecryptInputBytes);
System.out.println("Java calculated at " + (javaDecryptInputBytes/1024/1024/((javaDecryptEndTime - javaDecryptStartTime)/1000)) + " MB/s");
}
संपादित करें: मैं इस सरल दिमाग बेंचमार्क सुधार करने के लिए एक मजेदार व्यायाम के रूप में छोड़।
मैं कुछ और अधिक ServerVM का उपयोग कर परीक्षण किया है, हटाया nanoTime कॉल करता है और शुरू की वार्मअप, लेकिन जैसा कि मैंने उम्मीद इस में से कोई भी बेंचमार्क परिणामों पर किसी भी सुधार किया था। यह 3 मेगाबाइट प्रति सेकंड पर फ्लैट-रेखांकित है।
सबसे पहले, बेंचमार्किंग गलत है: कोई गर्मजोशी, एकल पुनरावृत्ति, अत्यधिक नैनो टाइम कॉल। एईएस-एनआई के लिए हॉटस्पॉट के इंट्रिनिक्स का उपयोग केवल एक अनुकूलित जेआईटी कंपाइलर के साथ किया जाता है, आपको प्रदर्शन का आकलन करने से पहले वहां पहुंचना होगा। दूसरा, एईएस/सीबीसी आज़माएं। क्या आप वास्तव में ओपनएसएसएल के साथ एईएस-जीसीएम मापते हैं, और यह आपको 1 जीबी/एस देता है? –
यह भी ध्यान दें कि एईएस-एनआई इंट्रिनिक्स का उपयोग करने के लिए इसे सर्वर वीएम, समर्थन के साथ एक आधुनिक इंटेल सीपीयू का उपयोग करने की आवश्यकता है, * और * एक गर्मजोशी अनुक्रम है। ध्यान दें कि OpenSSL वहां सबसे तेज़ libs में से एक है, बाइट कोड व्यवसाय तर्क के लिए अपेक्षाकृत तेज़ हो सकता है, लेकिन क्रिप्टोग्राफ़ी के लिए * * अच्छी तरह से लागू सी/सी ++ पुस्तकालयों के साथ अंतर दिखाई देगा। –
हां, मुझे पता है कि यह सबसे मजबूत बेंचमार्क नहीं है, लेकिन 3 एमबी/एस बनाम 1 जीबी/एस अभी भी बहुत महत्वपूर्ण है और मुझे लगता है कि यह सरल बेंचमार्क बिंदु को लाने के लिए पर्याप्त है। मैंने एईएस/सीबीसी की कोशिश की है और मैं एन्क्रिप्शन के लिए 400 एमबी/एस और जावा के सिफर का उपयोग करके डिक्रिप्शन के लिए 1 जीबी/एस से अधिक प्राप्त करने में सक्षम हूं। – Christo