Bu soruna genel olarak alıntı yapılan birkaç çözüm var. Ne yazık ki bunların hiçbiri tamamen tatmin edici değil:
- Sınırsız güç ilkesi dosyalarını yükleyin . Bu muhtemelen geliştirme iş istasyonunuz için doğru çözüm olsa da, teknik olmayan kullanıcıların dosyaları her bilgisayara yüklemesi hızlı bir şekilde büyük bir güçlük haline gelir (birlikte gösterim değilse). Orada hiçbir şekilde sizin programla dosyaları dağıtmak; bunların JRE dizinine yüklenmesi gerekir (bu izinler nedeniyle salt okunur olabilir).
- JCE API'sini atlayın ve Bouncy Castle gibi başka bir şifreleme kütüphanesi kullanın . Bu yaklaşım, uygulamaya bağlı olarak önemli bir yük olabilecek fazladan 1 MB'lık bir kütüphane gerektirir. Ayrıca standart kitaplıklarda bulunan yinelenen işlevsellik de saçma geliyor. Açıkçası, API aynı zamanda normal JCE arayüzünden tamamen farklıdır. (BC bir JCE sağlayıcısı uygular, ancak uygulamaya geçmeden önce temel güç kısıtlamaları uygulandığından bu yardımcı olmaz .) Bu çözüm ayrıca 256 bit TLS (SSL) şifreleme paketleri kullanmanıza izin vermez. standart TLS kütüphaneleri, JCE'yi dahili olarak çağırır ve herhangi bir kısıtlama belirler.
Ama sonra yansıma var. Yansımayı kullanarak yapamayacağınız bir şey var mı?
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()
Herhangi bir şifreleme işlemi gerçekleştirmeden önce statik bir başlatıcıdan veya benzeri bir şeyden çağrı yapmanız yeterlidir .
JceSecurity.isRestricted = false
Bölümü doğrudan 256 bit şifrelere kullanmak için gerekli olan tüm olduğu; ancak, diğer iki işlem yapılmadan Cipher.getMaxAllowedKeyLength()
128 bildirmeye devam eder ve 256 bit TLS şifre paketleri çalışmaz.
Bu kod Oracle Java 7 ve 8'de çalışır ve Java 9 ve OpenJDK'daki işlemi otomatik olarak atlar. Sonuçta çirkin bir hack olmak, diğer satıcıların sanal makinelerinde çalışmaz.
Özel Java JCE sınıfları burada gizlenmiş olduğu için Oracle Java 6'da da çalışmaz. Gizleme sürümden sürüme değişmez, bu nedenle Java 6'yı desteklemek hala teknik olarak mümkündür.