GetEncoded गुप्त कुंजी की एक प्रति लौटाता है (इसलिए गुप्त कुंजी डेटा पर कोई प्रभाव नहीं पड़ता है), और डिफ़ॉल्ट रूप से नष्ट हो जाता है DestroyFailedException जो बेकार से भी बदतर है। यह केवल 1.8+ में उपलब्ध है, इसलिए एंड्रॉइड भाग्य से बाहर है। यहां एक हैक है जो आत्मनिरीक्षण का उपयोग करता है (1) उपलब्ध होने पर विनाश का आह्वान करता है और अपवाद नहीं फेंकता है, अन्यथा (2) कुंजी डेटा शून्य और शून्य को संदर्भ सेट करें।
package kiss.cipher;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Arrays;
import javax.crypto.spec.SecretKeySpec;
/**
* Created by wmacevoy on 10/12/16.
*/
public class CloseableKey implements AutoCloseable {
// forward portable to JDK 1.8 to destroy keys
// but usable in older JDK's
static final Method DESTROY;
static final Field KEY;
static {
Method _destroy = null;
Field _key = null;
try {
Method destroy = SecretKeySpec.class.getMethod("destroy");
SecretKeySpec key = new SecretKeySpec(new byte[16], "AES");
destroy.invoke(key);
_destroy = destroy;
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
}
try {
_key = SecretKeySpec.class.getDeclaredField("key");
_key.setAccessible(true);
} catch (NoSuchFieldException | SecurityException ex) {
}
DESTROY = _destroy;
KEY = _key;
}
static void close(SecretKeySpec secretKeySpec) {
if (secretKeySpec != null) {
if (DESTROY != null) {
try {
DESTROY.invoke(secretKeySpec);
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new IllegalStateException("inconceivable: " + ex);
}
} else if (KEY != null) {
try {
byte[] key = (byte[]) KEY.get(secretKeySpec);
Arrays.fill(key, (byte) 0);
KEY.set(secretKeySpec, null);
} catch (IllegalAccessException | IllegalArgumentException ex) {
throw new IllegalStateException("inconceivable: " + ex);
}
}
}
}
public final SecretKeySpec secretKeySpec;
CloseableKey(SecretKeySpec _secretKeySpec) {
secretKeySpec = _secretKeySpec;
}
@Override
public void close() {
close(secretKeySpec);
}
}
तरीका यह उपयोग करने के लिए
तरह
try (CloseableKey key =
new CloseableKey(new SecretKeySpec(data, 0, 16, "AES"))) {
aesecb.init(Cipher.ENCRYPT_MODE, key.secretKeySpec);
}
मैं closeable इंटरफ़ेस का उपयोग क्योंकि destroyable केवल एक 1.8+ सुविधा है। यह संस्करण 1.7+ पर काम करता है और यह बहुत ही कुशल है (यह एक परीक्षण पर एक परीक्षण को नष्ट करता है ताकि इसे कभी भी इसका उपयोग करने का फैसला किया जा सके)।
स्रोत
2017-03-25 05:07:45
-1: * जावा में बाकी सब कुछ हमेशा संदर्भ द्वारा पारित किया जाता है * - Nooo, जावा * हमेशा * मूल्य से गुजरता है! कारण से आप * ऑब्जेक्ट * पास नहीं कर सकते हैं, क्योंकि कोई चर किसी ऑब्जेक्ट को पहले स्थान पर नहीं रख सकता है! – aioobe
@aioobe .. आप सुनिश्चित हैं कि हम एक ही जावा के बारे में बात कर रहे हैं? int मूल्य से गुजरता है, बूलियन मूल्य से गुजरता है, इंटीजर एक संदर्भ है, साथ ही किसी ऑब्जेक्ट, सरणी इत्यादि ... जावा "एक मान" पास करता है, जो वास्तव में किसी ऑब्जेक्ट के लिए "संदर्भ" है, इसलिए यह है संदर्भ। –
@ जोचिम .. मैं "दिए गए बाइट सरणी" का जिक्र कर रहा था, हालांकि आगे स्पष्ट किया कि एक और प्रतिलिपि हो सकती है। –