How to avoid installing “Unlimited Strength” JCE policy files when deploying an application?

前端 未结 11 2027
鱼传尺愫
鱼传尺愫 2020-11-22 07:43

I have an app that uses 256-bit AES encryption which is not supported by Java out of the box. I know to get this to function correctly I install the JCE unlimited strength j

11条回答
  •  北海茫月
    2020-11-22 08:29

    Here's a updated version of ntoskrnl answer. It additionally contains a function to remove the final modifier like Arjan mentioned in the comments.

    This version works with JRE 8u111 or newer.

    private static void removeCryptographyRestrictions() {
        if (!isRestrictedCryptography()) {
            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");
    
            Field isRestrictedField = jceSecurity.getDeclaredField("isRestricted");
            isRestrictedField.setAccessible(true);
            setFinalStatic(isRestrictedField, true);
            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));
        }
        catch (final Exception e) {
            e.printStackTrace();
        }
    }
    
    static void setFinalStatic(Field field, Object newValue) throws Exception {
          field.setAccessible(true);
    
          Field modifiersField = Field.class.getDeclaredField("modifiers");
          modifiersField.setAccessible(true);
          modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    
          field.set(null, newValue);
       }
    
    private static boolean isRestrictedCryptography() {
        // This simply matches the Oracle JRE, but not OpenJDK.
        return "Java(TM) SE Runtime Environment".equals(System.getProperty("java.runtime.name"));
    }
    

提交回复
热议问题