इस समस्या के लिए आमतौर पर उद्धृत समाधान के एक जोड़े हैं। दुर्भाग्य से इनमें से कोई भी पूरी तरह से संतोषजनक नहीं हैं:
- असीमित ताकत नीति फ़ाइलों को स्थापित करें । हालांकि यह संभवतः आपके विकास कार्य केंद्र के लिए सही समाधान है, यह जल्दी से एक बड़ी परेशानी बन जाती है (यदि कोई अवरोध नहीं है) गैर-तकनीकी उपयोगकर्ताओं को हर कंप्यूटर पर फ़ाइलों को स्थापित करने के लिए। आपके प्रोग्राम के साथ फ़ाइलों को वितरित करने का कोई तरीका नहीं है ; उन्हें JRE निर्देशिका में स्थापित किया जाना चाहिए (जो कि केवल अनुमतियों के कारण भी पढ़ा जा सकता है)।
- जेसीई एपीआई को छोड़ें और एक अन्य क्रिप्टोग्राफी लाइब्रेरी जैसे बाउंसी कैसल का उपयोग करें । इस दृष्टिकोण के लिए अतिरिक्त 1MB पुस्तकालय की आवश्यकता होती है, जो कि आवेदन के आधार पर एक महत्वपूर्ण बोझ हो सकता है। यह मानक पुस्तकालयों में शामिल कार्यक्षमता की नकल करने के लिए मूर्खतापूर्ण लगता है। जाहिर है, एपीआई भी सामान्य जेसीई इंटरफेस से पूरी तरह से अलग है। (बीसी एक जेसीई प्रदाता को लागू करता है, लेकिन इससे मदद नहीं मिलती है क्योंकि कार्यान्वयन को सौंपने से पहले प्रमुख ताकत प्रतिबंध लागू होते हैं ।) यह समाधान आपको 256-बिट टीएलएस (एसएसएल) सिफर सुइट्स का उपयोग करने की अनुमति नहीं देगा, क्योंकि मानक टीएलएस पुस्तकालय किसी भी प्रतिबंध को निर्धारित करने के लिए आंतरिक रूप से जेसीई को बुलाते हैं।
लेकिन फिर प्रतिबिंब है। वहाँ कुछ भी आप प्रतिबिंब का उपयोग नहीं कर सकते है?
private static void removeCryptographyRestrictions() {
if (!isRestrictedCryptography()) {
logger.fine("Cryptography restrictions removal not needed");
return;
}
try {
/*
* Do the following, but with reflection to bypass access checks:
*
* JceSecurity.isRestricted = false;
* JceSecurity.defaultPolicy.perms.clear();
* JceSecurity.defaultPolicy.add(CryptoAllPermission.INSTANCE);
*/
final Class<?> jceSecurity = Class.forName("javax.crypto.JceSecurity");
final Class<?> cryptoPermissions = Class.forName("javax.crypto.CryptoPermissions");
final Class<?> cryptoAllPermission = Class.forName("javax.crypto.CryptoAllPermission");
final Field isRestrictedField = jceSecurity.getDeclaredField("isRestricted");
isRestrictedField.setAccessible(true);
final Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(isRestrictedField, isRestrictedField.getModifiers() & ~Modifier.FINAL);
isRestrictedField.set(null, false);
final Field defaultPolicyField = jceSecurity.getDeclaredField("defaultPolicy");
defaultPolicyField.setAccessible(true);
final PermissionCollection defaultPolicy = (PermissionCollection) defaultPolicyField.get(null);
final Field perms = cryptoPermissions.getDeclaredField("perms");
perms.setAccessible(true);
((Map<?, ?>) perms.get(defaultPolicy)).clear();
final Field instance = cryptoAllPermission.getDeclaredField("INSTANCE");
instance.setAccessible(true);
defaultPolicy.add((Permission) instance.get(null));
logger.fine("Successfully removed cryptography restrictions");
} catch (final Exception e) {
logger.log(Level.WARNING, "Failed to remove cryptography restrictions", e);
}
}
private static boolean isRestrictedCryptography() {
// This matches Oracle Java 7 and 8, but not Java 9 or OpenJDK.
final String name = System.getProperty("java.runtime.name");
final String ver = System.getProperty("java.version");
return name != null && name.equals("Java(TM) SE Runtime Environment")
&& ver != null && (ver.startsWith("1.7") || ver.startsWith("1.8"));
}
removeCryptographyRestrictions()
किसी भी क्रिप्टोग्राफ़िक ऑपरेशन को करने से पहले एक स्टैटिक इनिशियलाइज़र या जैसे कॉल करें ।
JceSecurity.isRestricted = false
भाग सब कि सीधे 256-बिट सिफर का उपयोग करने के लिए आवश्यक है; हालांकि, दो अन्य ऑपरेशनों के बिना, Cipher.getMaxAllowedKeyLength()
अभी भी 128 की रिपोर्टिंग करते रहेंगे, और 256-बिट टीएलएस सिफर सूट काम नहीं करेंगे।
यह कोड ओरेकल जावा 7 और 8 पर काम करता है, और स्वचालित रूप से जावा 9 और ओपनजेडके पर प्रक्रिया को रोक देता है जहां इसकी आवश्यकता नहीं है। आखिरकार एक बदसूरत हैक होने के नाते, यह अन्य विक्रेताओं के वीएम पर काम नहीं करता है।
यह ओरेकल जावा 6 पर भी काम नहीं करता है, क्योंकि निजी जेसीई कक्षाएं वहां बाधित होती हैं। हालाँकि, संस्करण से संस्करण में आपस में परिवर्तन नहीं होता है, इसलिए जावा 6 का समर्थन करना अभी भी तकनीकी रूप से संभव है।