Java tutorial
package com.orange.clara.cloud.servicedbdumper.task.boot.sequences; import com.google.common.base.Charsets; import com.google.common.io.Files; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Permission; import java.security.PermissionCollection; import java.util.Map; /** * Copyright (C) 2015 Orange * <p> * This software is distributed under the terms and conditions of the 'Apache-2.0' * license which can be found in the file 'LICENSE' in this package distribution * or at 'https://opensource.org/licenses/Apache-2.0'. * <p> * Author: Arthur Halet * Date: 09/12/2015 */ @Component @Order(1) public class BootSequenceSecurity implements BootSequence { @Value("${encryption.key:MySuperSecretKey}") protected String encryptionKey; @Value("classpath:properties/encryption_key.txt") protected File encryptionKeyFile; private Logger logger = LoggerFactory.getLogger(BootSequenceSecurity.class); 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")); } public void fillEncryptionKeyFile() throws IOException, NoSuchAlgorithmException { //force to have always a 32 bytes key (to use AES encryption with 256 bits key length) MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(encryptionKey.getBytes(Charsets.UTF_8)); byte[] key = md.digest(); Files.write(key, encryptionKeyFile); } public void removeEncryptionRestriction() { if (!isRestrictedCryptography()) { logger.info("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.info("Successfully removed cryptography restrictions"); } catch (final Exception e) { logger.warn("Failed to remove cryptography restrictions", e); } } @Override public void runSequence() { this.removeEncryptionRestriction(); try { this.fillEncryptionKeyFile(); } catch (Exception e) { throw new RuntimeException(e); } } }