keith-turner closed pull request #319: ACCUMULO-4737 Clean up cipher algorithm 
configuration
URL: https://github.com/apache/accumulo/pull/319
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git 
a/core/src/main/java/org/apache/accumulo/core/conf/ConfigSanityCheck.java 
b/core/src/main/java/org/apache/accumulo/core/conf/ConfigSanityCheck.java
index 130863c961..bf84c650e9 100644
--- a/core/src/main/java/org/apache/accumulo/core/conf/ConfigSanityCheck.java
+++ b/core/src/main/java/org/apache/accumulo/core/conf/ConfigSanityCheck.java
@@ -17,6 +17,7 @@
 package org.apache.accumulo.core.conf;
 
 import java.util.Map.Entry;
+import java.util.Objects;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,6 +47,8 @@
   public static void validate(Iterable<Entry<String,String>> entries) {
     String instanceZkTimeoutValue = null;
     boolean usingVolumes = false;
+    String cipherSuite = null;
+    String keyAlgorithm = null;
     for (Entry<String,String> entry : entries) {
       String key = entry.getKey();
       String value = entry.getValue();
@@ -66,6 +69,14 @@ else if (!prop.getType().isValidFormat(value))
       if (key.equals(Property.INSTANCE_VOLUMES.getKey())) {
         usingVolumes = value != null && !value.isEmpty();
       }
+
+      if (key.equals(Property.CRYPTO_CIPHER_SUITE.getKey())) {
+        cipherSuite = Objects.requireNonNull(value);
+      }
+
+      if (key.equals(Property.CRYPTO_CIPHER_KEY_ALGORITHM_NAME.getKey())) {
+        keyAlgorithm = Objects.requireNonNull(value);
+      }
     }
 
     if (instanceZkTimeoutValue != null) {
@@ -75,6 +86,14 @@ else if (!prop.getType().isValidFormat(value))
     if (!usingVolumes) {
       log.warn("Use of {} and {} are deprecated. Consider using {} instead.", 
INSTANCE_DFS_URI, INSTANCE_DFS_DIR, Property.INSTANCE_VOLUMES);
     }
+
+    if (cipherSuite.equals("NullCipher") && 
!keyAlgorithm.equals("NullCipher")) {
+      fatal(Property.CRYPTO_CIPHER_SUITE.getKey() + " should be configured 
when " + Property.CRYPTO_CIPHER_KEY_ALGORITHM_NAME.getKey() + " is set.");
+    }
+
+    if (!cipherSuite.equals("NullCipher") && 
keyAlgorithm.equals("NullCipher")) {
+      fatal(Property.CRYPTO_CIPHER_KEY_ALGORITHM_NAME.getKey() + " should be 
configured when " + Property.CRYPTO_CIPHER_SUITE.getKey() + " is set.");
+    }
   }
 
   private interface CheckTimeDuration {
diff --git a/core/src/main/java/org/apache/accumulo/core/conf/Property.java 
b/core/src/main/java/org/apache/accumulo/core/conf/Property.java
index e08df9e363..f0e233894f 100644
--- a/core/src/main/java/org/apache/accumulo/core/conf/Property.java
+++ b/core/src/main/java/org/apache/accumulo/core/conf/Property.java
@@ -48,10 +48,18 @@
       "Fully qualified class name of the class that implements the 
CryptoModule interface, to be used in setting up encryption at rest for the WAL 
and "
           + "(future) other parts of the code."),
   @Experimental
-  CRYPTO_CIPHER_SUITE("crypto.cipher.suite", "NullCipher", 
PropertyType.STRING, "Describes the cipher suite to use for the write-ahead 
log"),
+  CRYPTO_CIPHER_SUITE("crypto.cipher.suite", "NullCipher", PropertyType.STRING,
+      "Describes the cipher suite to use for rfile encryption. If a WAL cipher 
suite is not set, it will default to this value. The suite should be in the "
+          + "form of algorithm/mode/padding, e.g. AES/CBC/NoPadding"),
   @Experimental
-  CRYPTO_CIPHER_ALGORITHM_NAME("crypto.cipher.algorithm.name", "NullCipher", 
PropertyType.STRING,
-      "States the name of the algorithm used in the corresponding cipher 
suite. Do not make these different, unless you enjoy mysterious exceptions and 
bugs."),
+  CRYPTO_WAL_CIPHER_SUITE(
+      "crypto.wal.cipher.suite",
+      "NullCipher",
+      PropertyType.STRING,
+      "Describes the cipher suite to use for the write-ahead log. Defaults to 
'cyrpto.cipher.suite' and will use that value for WAL encryption unless 
otherwise specified."),
+  @Experimental
+  CRYPTO_CIPHER_KEY_ALGORITHM_NAME("crypto.cipher.key.algorithm.name", 
"NullCipher", PropertyType.STRING,
+      "States the name of the algorithm used for the key for the corresponding 
cipher suite. The key type must be compatible with the cipher suite."),
   @Experimental
   CRYPTO_BLOCK_STREAM_SIZE("crypto.block.stream.size", "1K", 
PropertyType.BYTES,
       "The size of the buffer above the cipher stream. Used for reading files 
and padding walog entries."),
diff --git 
a/core/src/main/java/org/apache/accumulo/core/file/rfile/bcfile/BCFile.java 
b/core/src/main/java/org/apache/accumulo/core/file/rfile/bcfile/BCFile.java
index 5cfe8242ea..212e1f671d 100644
--- a/core/src/main/java/org/apache/accumulo/core/file/rfile/bcfile/BCFile.java
+++ b/core/src/main/java/org/apache/accumulo/core/file/rfile/bcfile/BCFile.java
@@ -394,7 +394,7 @@ public void close() throws IOException {
           long offsetIndexMeta = out.position();
           metaIndex.write(out);
 
-          if (cryptoParams.getAlgorithmName() == null || 
cryptoParams.getAlgorithmName().equals(Property.CRYPTO_CIPHER_SUITE.getDefaultValue()))
 {
+          if (cryptoParams.getCipherSuite() == null || 
cryptoParams.getCipherSuite().equals(Property.CRYPTO_CIPHER_SUITE.getDefaultValue()))
 {
             out.writeLong(offsetIndexMeta);
             API_VERSION_1.write(out);
           } else {
diff --git 
a/core/src/main/java/org/apache/accumulo/core/security/crypto/CachingHDFSSecretKeyEncryptionStrategy.java
 
b/core/src/main/java/org/apache/accumulo/core/security/crypto/CachingHDFSSecretKeyEncryptionStrategy.java
index 7b79d99ec4..ed6d6a5a1b 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/security/crypto/CachingHDFSSecretKeyEncryptionStrategy.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/security/crypto/CachingHDFSSecretKeyEncryptionStrategy.java
@@ -72,7 +72,7 @@ private void doKeyEncryptionOperation(int encryptionMode, 
CryptoModuleParameters
     Cipher cipher = 
DefaultCryptoModuleUtils.getCipher(params.getAllOptions().get(Property.CRYPTO_DEFAULT_KEY_STRATEGY_CIPHER_SUITE.getKey()));
 
     try {
-      cipher.init(encryptionMode, new 
SecretKeySpec(secretKeyCache.getKeyEncryptionKey(), params.getAlgorithmName()));
+      cipher.init(encryptionMode, new 
SecretKeySpec(secretKeyCache.getKeyEncryptionKey(), 
params.getKeyAlgorithmName()));
     } catch (InvalidKeyException e) {
       log.error("{}", e.getMessage(), e);
       throw new RuntimeException(e);
@@ -80,7 +80,7 @@ private void doKeyEncryptionOperation(int encryptionMode, 
CryptoModuleParameters
 
     if (Cipher.UNWRAP_MODE == encryptionMode) {
       try {
-        Key plaintextKey = cipher.unwrap(params.getEncryptedKey(), 
params.getAlgorithmName(), Cipher.SECRET_KEY);
+        Key plaintextKey = cipher.unwrap(params.getEncryptedKey(), 
params.getKeyAlgorithmName(), Cipher.SECRET_KEY);
         params.setPlaintextKey(plaintextKey.getEncoded());
       } catch (InvalidKeyException e) {
         log.error("{}", e.getMessage(), e);
@@ -90,7 +90,7 @@ private void doKeyEncryptionOperation(int encryptionMode, 
CryptoModuleParameters
         throw new RuntimeException(e);
       }
     } else {
-      Key plaintextKey = new SecretKeySpec(params.getPlaintextKey(), 
params.getAlgorithmName());
+      Key plaintextKey = new SecretKeySpec(params.getPlaintextKey(), 
params.getKeyAlgorithmName());
       try {
         byte[] encryptedSecretKey = cipher.wrap(plaintextKey);
         params.setEncryptedKey(encryptedSecretKey);
diff --git 
a/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleFactory.java
 
b/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleFactory.java
index 6a295adbce..e56ee92385 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleFactory.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleFactory.java
@@ -239,14 +239,6 @@ public CryptoModuleParameters 
initializeCipher(CryptoModuleParameters params) {
 
   }
 
-  public static String[] parseCipherTransform(String cipherTransform) {
-    if (cipherTransform == null) {
-      return new String[3];
-    }
-
-    return cipherTransform.split("/");
-  }
-
   public static CryptoModuleParameters 
createParamsObjectFromAccumuloConfiguration(AccumuloConfiguration conf) {
     CryptoModuleParameters params = new CryptoModuleParameters();
 
@@ -264,26 +256,21 @@ public static CryptoModuleParameters 
fillParamsObjectFromConfiguration(CryptoMod
   }
 
   public static CryptoModuleParameters 
fillParamsObjectFromStringMap(CryptoModuleParameters params, Map<String,String> 
cryptoOpts) {
-
-    // Parse the cipher suite for the mode and padding options
-    String[] cipherTransformParts = 
parseCipherTransform(cryptoOpts.get(Property.CRYPTO_CIPHER_SUITE.getKey()));
-
+    
params.setCipherSuite(cryptoOpts.get(Property.CRYPTO_CIPHER_SUITE.getKey()));
     // If no encryption has been specified, then we abort here.
-    if (cipherTransformParts[0] == null || 
cipherTransformParts[0].equals("NullCipher")) {
+    if (params.getCipherSuite() == null || 
params.getCipherSuite().equals("NullCipher")) {
       params.setAllOptions(cryptoOpts);
-      params.setAlgorithmName("NullCipher");
+
       return params;
     }
 
     params.setAllOptions(cryptoOpts);
 
-    
params.setAlgorithmName(cryptoOpts.get(Property.CRYPTO_CIPHER_ALGORITHM_NAME.getKey()));
-    params.setEncryptionMode(cipherTransformParts[1]);
+    
params.setKeyAlgorithmName(cryptoOpts.get(Property.CRYPTO_CIPHER_KEY_ALGORITHM_NAME.getKey()));
     
params.setKeyEncryptionStrategyClass(cryptoOpts.get(Property.CRYPTO_SECRET_KEY_ENCRYPTION_STRATEGY_CLASS.getKey()));
     
params.setKeyLength(Integer.parseInt(cryptoOpts.get(Property.CRYPTO_CIPHER_KEY_LENGTH.getKey())));
     
params.setOverrideStreamsSecretKeyEncryptionStrategy(Boolean.parseBoolean(cryptoOpts.get(Property.CRYPTO_OVERRIDE_KEY_STRATEGY_WITH_CONFIGURED_STRATEGY
         .getKey())));
-    params.setPadding(cipherTransformParts[2]);
     
params.setRandomNumberGenerator(cryptoOpts.get(Property.CRYPTO_SECURE_RNG.getKey()));
     
params.setRandomNumberGeneratorProvider(cryptoOpts.get(Property.CRYPTO_SECURE_RNG_PROVIDER.getKey()));
     String blockStreamSize = 
cryptoOpts.get(Property.CRYPTO_BLOCK_STREAM_SIZE.getKey());
diff --git 
a/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleParameters.java
 
b/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleParameters.java
index a7bb93dfdd..b5a1ae4de7 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleParameters.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/security/crypto/CryptoModuleParameters.java
@@ -37,17 +37,17 @@
 public class CryptoModuleParameters {
 
   /**
-   * Gets the name of the symmetric algorithm to use for encryption.
+   * Gets the name of the symmetric algorithm to use for the creation of 
encryption keys.
    *
-   * @see CryptoModuleParameters#setAlgorithmName(String)
+   * @see CryptoModuleParameters#setKeyAlgorithmName(String)
    */
 
-  public String getAlgorithmName() {
-    return algorithmName;
+  public String getKeyAlgorithmName() {
+    return keyAlgorithmName;
   }
 
   /**
-   * Sets the name of the symmetric algorithm to use for an encryption stream.
+   * Sets the name of the symmetric algorithm to use for the creation of 
encryption keys.
    * <p>
    * Valid names are names recognized by your cryptographic engine provider. 
For the default Java provider, valid names would include things like "AES", 
"RC4",
    * "DESede", etc.
@@ -56,73 +56,45 @@ public String getAlgorithmName() {
    * decryption. <br>
    * For <b>decryption</b>, this value is often disregarded in favor of the 
value encoded with the ciphertext.
    *
-   * @param algorithmName
+   * @param keyAlgorithmName
    *          the name of the cryptographic algorithm to use.
    * @see <a 
href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#AppA";>Standard
 Algorithm Names in JCE</a>
    *
    */
 
-  public void setAlgorithmName(String algorithmName) {
-    this.algorithmName = algorithmName;
+  public void setKeyAlgorithmName(String keyAlgorithmName) {
+    this.keyAlgorithmName = keyAlgorithmName;
   }
 
   /**
-   * Gets the name of the encryption mode to use for encryption.
+   * Gets the name of the cipher suite used for encryption
    *
-   * @see CryptoModuleParameters#setEncryptionMode(String)
+   * @see CryptoModuleParameters#setCipherSuite(String)
    */
 
-  public String getEncryptionMode() {
-    return encryptionMode;
+  public String getCipherSuite() {
+    return cipherSuite;
   }
 
   /**
-   * Sets the name of the encryption mode to use for an encryption stream.
+   * Sets the name of the crypto suite to use for an encryption stream.
    * <p>
-   * Valid names are names recognized by your cryptographic engine provider. 
For the default Java provider, valid names would include things like "EBC", 
"CBC",
-   * "CFB", etc.
-   * <p>
-   * For <b>encryption</b>, this value is <b>required</b> and is always used. 
Its value should be prepended or otherwise included with the ciphertext for 
future
-   * decryption. <br>
-   * For <b>decryption</b>, this value is often disregarded in favor of the 
value encoded with the ciphertext.
+   * Valid names are names recognized by your cryptographic engine provider.
    *
-   * @param encryptionMode
-   *          the name of the encryption mode to use.
-   * @see <a 
href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#AppA";>Standard
 Mode Names in JCE</a>
-   *
-   */
-
-  public void setEncryptionMode(String encryptionMode) {
-    this.encryptionMode = encryptionMode;
-  }
-
-  /**
-   * Gets the name of the padding type to use for encryption.
+   * The format for input should be: algorithm/mode/padding
    *
-   * @see CryptoModuleParameters#setPadding(String)
-   */
-
-  public String getPadding() {
-    return padding;
-  }
-
-  /**
-   * Sets the name of the padding type to use for an encryption stream.
-   * <p>
-   * Valid names are names recognized by your cryptographic engine provider. 
For the default Java provider, valid names would include things like 
"NoPadding",
-   * "None", etc.
+   * For the default Java provider, valid names would include things like 
"AES/CBC/NoPadding".
    * <p>
    * For <b>encryption</b>, this value is <b>required</b> and is always used. 
Its value should be prepended or otherwise included with the ciphertext for 
future
    * decryption. <br>
    * For <b>decryption</b>, this value is often disregarded in favor of the 
value encoded with the ciphertext.
    *
-   * @param padding
-   *          the name of the padding type to use.
-   * @see <a 
href="http://docs.oracle.com/javase/1.5.0/docs/guide/security/jce/JCERefGuide.html#AppA";>Standard
 Padding Names in JCE</a>
+   * @param cipherSuite
+   *          the cipher suite to use.
    *
    */
-  public void setPadding(String padding) {
-    this.padding = padding;
+  public void setCipherSuite(String cipherSuite) {
+    this.cipherSuite = cipherSuite;
   }
 
   /**
@@ -602,9 +574,8 @@ public void setAllOptions(Map<String,String> allOptions) {
     this.allOptions = allOptions;
   }
 
-  private String algorithmName = null;
-  private String encryptionMode = null;
-  private String padding = null;
+  private String cipherSuite = null;
+  private String keyAlgorithmName = null;
   private byte[] plaintextKey;
   private int keyLength = 0;
   private String randomNumberGenerator = null;
diff --git 
a/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModule.java
 
b/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModule.java
index 7609bb0f63..1b9968e2a7 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModule.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/security/crypto/DefaultCryptoModule.java
@@ -57,10 +57,9 @@ public DefaultCryptoModule() {}
 
   @Override
   public CryptoModuleParameters initializeCipher(CryptoModuleParameters 
params) {
-    String cipherTransformation = getCipherTransformation(params);
 
     log.trace(String.format("Using cipher suite \"%s\" with key length %d with 
RNG \"%s\" and RNG provider \"%s\" and key encryption strategy \"%s\"",
-        cipherTransformation, params.getKeyLength(), 
params.getRandomNumberGenerator(), params.getRandomNumberGeneratorProvider(),
+        params.getCipherSuite(), params.getKeyLength(), 
params.getRandomNumberGenerator(), params.getRandomNumberGeneratorProvider(),
         params.getKeyEncryptionStrategyClass()));
 
     if (params.getSecureRandom() == null) {
@@ -68,11 +67,11 @@ public CryptoModuleParameters 
initializeCipher(CryptoModuleParameters params) {
       params.setSecureRandom(secureRandom);
     }
 
-    Cipher cipher = DefaultCryptoModuleUtils.getCipher(cipherTransformation);
+    Cipher cipher = 
DefaultCryptoModuleUtils.getCipher(params.getCipherSuite());
 
     if (params.getInitializationVector() == null) {
       try {
-        cipher.init(Cipher.ENCRYPT_MODE, new 
SecretKeySpec(params.getPlaintextKey(), params.getAlgorithmName()), 
params.getSecureRandom());
+        cipher.init(Cipher.ENCRYPT_MODE, new 
SecretKeySpec(params.getPlaintextKey(), params.getKeyAlgorithmName()), 
params.getSecureRandom());
       } catch (InvalidKeyException e) {
         log.error("Accumulo encountered an unknown error in generating the 
secret key object (SecretKeySpec) for an encrypted stream");
         throw new RuntimeException(e);
@@ -82,7 +81,7 @@ public CryptoModuleParameters 
initializeCipher(CryptoModuleParameters params) {
 
     } else {
       try {
-        cipher.init(Cipher.ENCRYPT_MODE, new 
SecretKeySpec(params.getPlaintextKey(), params.getAlgorithmName()),
+        cipher.init(Cipher.ENCRYPT_MODE, new 
SecretKeySpec(params.getPlaintextKey(), params.getKeyAlgorithmName()),
             new IvParameterSpec(params.getInitializationVector()));
       } catch (InvalidKeyException e) {
         log.error("Accumulo encountered an unknown error in generating the 
secret key object (SecretKeySpec) for an encrypted stream");
@@ -99,15 +98,6 @@ public CryptoModuleParameters 
initializeCipher(CryptoModuleParameters params) {
 
   }
 
-  private String getCipherTransformation(CryptoModuleParameters params) {
-    String cipherSuite = params.getAlgorithmName() + "/" + 
params.getEncryptionMode() + "/" + params.getPadding();
-    return cipherSuite;
-  }
-
-  private String[] parseCipherSuite(String cipherSuite) {
-    return cipherSuite.split("/");
-  }
-
   private boolean validateNotEmpty(String givenValue, boolean allIsWell, 
StringBuilder buf, String errorMessage) {
     if (givenValue == null || givenValue.equals("")) {
       buf.append(errorMessage);
@@ -146,15 +136,14 @@ private boolean 
validateParamsObject(CryptoModuleParameters params, int cipherMo
           "The following problems were found with the CryptoModuleParameters 
object you provided for an encrypt operation:\n");
       boolean allIsWell = true;
 
-      allIsWell = validateNotEmpty(params.getAlgorithmName(), allIsWell, 
errorBuf, "No algorithm name was specified.");
+      allIsWell = validateNotEmpty(params.getCipherSuite(), allIsWell, 
errorBuf, "No cipher suite was specified.");
 
-      if (allIsWell && params.getAlgorithmName().equals("NullCipher")) {
+      if (allIsWell && params.getCipherSuite().equals("NullCipher")) {
         return true;
       }
 
-      allIsWell = validateNotEmpty(params.getPadding(), allIsWell, errorBuf, 
"No padding was specified.");
       allIsWell = validateNotZero(params.getKeyLength(), allIsWell, errorBuf, 
"No key length was specified.");
-      allIsWell = validateNotEmpty(params.getEncryptionMode(), allIsWell, 
errorBuf, "No encryption mode was specified.");
+      allIsWell = validateNotEmpty(params.getKeyAlgorithmName(), allIsWell, 
errorBuf, "No key algorithm name was specified.");
       allIsWell = validateNotEmpty(params.getRandomNumberGenerator(), 
allIsWell, errorBuf, "No random number generator was specified.");
       allIsWell = validateNotEmpty(params.getRandomNumberGeneratorProvider(), 
allIsWell, errorBuf, "No random number generate provider was specified.");
       allIsWell = validateNotNull(params.getPlaintextOutputStream(), 
allIsWell, errorBuf, "No plaintext output stream was specified.");
@@ -172,9 +161,7 @@ private boolean validateParamsObject(CryptoModuleParameters 
params, int cipherMo
           "The following problems were found with the CryptoModuleParameters 
object you provided for a decrypt operation:\n");
       boolean allIsWell = true;
 
-      allIsWell = validateNotEmpty(params.getPadding(), allIsWell, errorBuf, 
"No padding was specified.");
       allIsWell = validateNotZero(params.getKeyLength(), allIsWell, errorBuf, 
"No key length was specified.");
-      allIsWell = validateNotEmpty(params.getEncryptionMode(), allIsWell, 
errorBuf, "No encryption mode was specified.");
       allIsWell = validateNotEmpty(params.getRandomNumberGenerator(), 
allIsWell, errorBuf, "No random number generator was specified.");
       allIsWell = validateNotEmpty(params.getRandomNumberGeneratorProvider(), 
allIsWell, errorBuf, "No random number generate provider was specified.");
       allIsWell = validateNotNull(params.getEncryptedInputStream(), allIsWell, 
errorBuf, "No encrypted input stream was specified.");
@@ -212,7 +199,7 @@ public CryptoModuleParameters 
getEncryptingOutputStream(CryptoModuleParameters p
     }
 
     // If they want a null output stream, just return their plaintext stream 
as the encrypted stream
-    if (params.getAlgorithmName().equals("NullCipher")) {
+    if (params.getCipherSuite().equals("NullCipher")) {
       params.setEncryptedOutputStream(params.getPlaintextOutputStream());
       return params;
     }
@@ -272,8 +259,8 @@ public CryptoModuleParameters 
getEncryptingOutputStream(CryptoModuleParameters p
 
       // Write out the cipher suite and algorithm used to encrypt this file. 
In case the admin changes, we want to still
       // decode the old format.
-      dataOut.writeUTF(getCipherTransformation(params));
-      dataOut.writeUTF(params.getAlgorithmName());
+      dataOut.writeUTF(params.getCipherSuite());
+      dataOut.writeUTF(params.getKeyAlgorithmName());
 
       // Write the init vector to the log file
       dataOut.writeInt(params.getInitializationVector().length);
@@ -314,10 +301,8 @@ public CryptoModuleParameters 
getDecryptingInputStream(CryptoModuleParameters pa
         // Set the cipher parameters
         String cipherSuiteFromFile = dataIn.readUTF();
         String algorithmNameFromFile = dataIn.readUTF();
-        String[] cipherSuiteParts = parseCipherSuite(cipherSuiteFromFile);
-        params.setAlgorithmName(algorithmNameFromFile);
-        params.setEncryptionMode(cipherSuiteParts[1]);
-        params.setPadding(cipherSuiteParts[2]);
+        params.setCipherSuite(cipherSuiteFromFile);
+        params.setKeyAlgorithmName(algorithmNameFromFile);
 
         // Read the secret key and initialization vector from the file
         int initVectorLength = dataIn.readInt();
@@ -383,10 +368,10 @@ public CryptoModuleParameters 
getDecryptingInputStream(CryptoModuleParameters pa
       throw new RuntimeException("CryptoModuleParameters object failed 
validation for decrypt");
     }
 
-    Cipher cipher = 
DefaultCryptoModuleUtils.getCipher(getCipherTransformation(params));
+    Cipher cipher = 
DefaultCryptoModuleUtils.getCipher(params.getCipherSuite());
 
     try {
-      cipher.init(Cipher.DECRYPT_MODE, new 
SecretKeySpec(params.getPlaintextKey(), params.getAlgorithmName()),
+      cipher.init(Cipher.DECRYPT_MODE, new 
SecretKeySpec(params.getPlaintextKey(), params.getKeyAlgorithmName()),
           new IvParameterSpec(params.getInitializationVector()));
     } catch (InvalidKeyException e) {
       log.error("Error when trying to initialize cipher with secret key");
@@ -401,7 +386,7 @@ public CryptoModuleParameters 
getDecryptingInputStream(CryptoModuleParameters pa
     if (params.getBlockStreamSize() > 0)
       blockedDecryptingInputStream = new 
BlockedInputStream(blockedDecryptingInputStream, cipher.getBlockSize(), 
params.getBlockStreamSize());
 
-    log.trace("Initialized cipher input stream with transformation [{}]", 
getCipherTransformation(params));
+    log.trace("Initialized cipher input stream with transformation [{}]", 
params.getCipherSuite());
 
     params.setPlaintextInputStream(blockedDecryptingInputStream);
 
@@ -421,5 +406,4 @@ public CryptoModuleParameters 
generateNewRandomSessionKey(CryptoModuleParameters
 
     return params;
   }
-
 }
diff --git 
a/core/src/main/java/org/apache/accumulo/core/security/crypto/NonCachingSecretKeyEncryptionStrategy.java
 
b/core/src/main/java/org/apache/accumulo/core/security/crypto/NonCachingSecretKeyEncryptionStrategy.java
index 5c9ca8cdce..2d2d2f7bf3 100644
--- 
a/core/src/main/java/org/apache/accumulo/core/security/crypto/NonCachingSecretKeyEncryptionStrategy.java
+++ 
b/core/src/main/java/org/apache/accumulo/core/security/crypto/NonCachingSecretKeyEncryptionStrategy.java
@@ -83,7 +83,7 @@ private void doKeyEncryptionOperation(int encryptionMode, 
CryptoModuleParameters
       // check if the number of bytes read into the array is the same as the 
value of the length field,
       if (bytesRead == keyEncryptionKeyLength) {
         try {
-          cipher.init(encryptionMode, new SecretKeySpec(keyEncryptionKey, 
params.getAlgorithmName()));
+          cipher.init(encryptionMode, new SecretKeySpec(keyEncryptionKey, 
params.getKeyAlgorithmName()));
         } catch (InvalidKeyException e) {
           log.error("{}", e.getMessage(), e);
           throw new RuntimeException(e);
@@ -91,7 +91,7 @@ private void doKeyEncryptionOperation(int encryptionMode, 
CryptoModuleParameters
 
         if (Cipher.UNWRAP_MODE == encryptionMode) {
           try {
-            Key plaintextKey = cipher.unwrap(params.getEncryptedKey(), 
params.getAlgorithmName(), Cipher.SECRET_KEY);
+            Key plaintextKey = cipher.unwrap(params.getEncryptedKey(), 
params.getKeyAlgorithmName(), Cipher.SECRET_KEY);
             params.setPlaintextKey(plaintextKey.getEncoded());
           } catch (InvalidKeyException e) {
             log.error("{}", e.getMessage(), e);
@@ -101,7 +101,7 @@ private void doKeyEncryptionOperation(int encryptionMode, 
CryptoModuleParameters
             throw new RuntimeException(e);
           }
         } else {
-          Key plaintextKey = new SecretKeySpec(params.getPlaintextKey(), 
params.getAlgorithmName());
+          Key plaintextKey = new SecretKeySpec(params.getPlaintextKey(), 
params.getKeyAlgorithmName());
           try {
             byte[] encryptedSecretKey = cipher.wrap(plaintextKey);
             params.setEncryptedKey(encryptedSecretKey);
diff --git 
a/core/src/test/java/org/apache/accumulo/core/conf/ConfigSanityCheckTest.java 
b/core/src/test/java/org/apache/accumulo/core/conf/ConfigSanityCheckTest.java
index 7ac2113c05..9f2ff8efce 100644
--- 
a/core/src/test/java/org/apache/accumulo/core/conf/ConfigSanityCheckTest.java
+++ 
b/core/src/test/java/org/apache/accumulo/core/conf/ConfigSanityCheckTest.java
@@ -28,6 +28,8 @@
   @Before
   public void setUp() {
     m = new java.util.HashMap<>();
+    m.put(Property.CRYPTO_CIPHER_SUITE.getKey(), "NullCipher");
+    m.put(Property.CRYPTO_CIPHER_KEY_ALGORITHM_NAME.getKey(), "NullCipher");
   }
 
   @Test
@@ -77,4 +79,18 @@ public void testFail_InstanceZkTimeoutOutOfRange() {
     m.put(Property.INSTANCE_ZK_TIMEOUT.getKey(), "10ms");
     ConfigSanityCheck.validate(m.entrySet());
   }
+
+  @Test(expected = SanityCheckException.class)
+  public void testFail_cipherSuiteSetKeyAlgorithmNotSet() {
+    m.put(Property.CRYPTO_CIPHER_SUITE.getKey(), "AES/CBC/NoPadding");
+    m.put(Property.CRYPTO_CIPHER_KEY_ALGORITHM_NAME.getKey(), "NullCipher");
+    ConfigSanityCheck.validate(m.entrySet());
+  }
+
+  @Test(expected = SanityCheckException.class)
+  public void testFail_cipherSuiteNotSetKeyAlgorithmSet() {
+    m.put(Property.CRYPTO_CIPHER_SUITE.getKey(), "NullCipher");
+    m.put(Property.CRYPTO_CIPHER_KEY_ALGORITHM_NAME.getKey(), "AES");
+    ConfigSanityCheck.validate(m.entrySet());
+  }
 }
diff --git 
a/core/src/test/java/org/apache/accumulo/core/security/crypto/CryptoTest.java 
b/core/src/test/java/org/apache/accumulo/core/security/crypto/CryptoTest.java
index a32a465dee..4467828ebe 100644
--- 
a/core/src/test/java/org/apache/accumulo/core/security/crypto/CryptoTest.java
+++ 
b/core/src/test/java/org/apache/accumulo/core/security/crypto/CryptoTest.java
@@ -19,7 +19,6 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.ByteArrayInputStream;
@@ -71,9 +70,7 @@ public void testNoCryptoStream() throws IOException {
     CryptoModuleParameters params = 
CryptoModuleFactory.createParamsObjectFromAccumuloConfiguration(conf);
 
     assertNotNull(params);
-    assertEquals("NullCipher", params.getAlgorithmName());
-    assertNull(params.getEncryptionMode());
-    assertNull(params.getPadding());
+    assertEquals("NullCipher", params.getCipherSuite());
 
     CryptoModule cryptoModule = CryptoModuleFactory.getCryptoModule(conf);
     assertNotNull(cryptoModule);
@@ -95,9 +92,9 @@ public void testCryptoModuleParamsParsing() {
     CryptoModuleParameters params = 
CryptoModuleFactory.createParamsObjectFromAccumuloConfiguration(conf);
 
     assertNotNull(params);
-    assertEquals("AES", params.getAlgorithmName());
-    assertEquals("CFB", params.getEncryptionMode());
-    assertEquals("NoPadding", params.getPadding());
+    assertEquals("AES/CFB/NoPadding", params.getCipherSuite());
+    assertEquals("AES/CBC/NoPadding", 
params.getAllOptions().get(Property.CRYPTO_WAL_CIPHER_SUITE.getKey()));
+    assertEquals("AES", params.getKeyAlgorithmName());
     assertEquals(128, params.getKeyLength());
     assertEquals("SHA1PRNG", params.getRandomNumberGenerator());
     assertEquals("SUN", params.getRandomNumberGeneratorProvider());
@@ -314,7 +311,7 @@ public void 
testChangingCryptoParamsAndCanStillDecryptPreviouslyEncryptedFiles()
     // from those configured within the site configuration. After doing this, 
we should
     // still be able to read the file that was created with a different set of 
parameters.
     params = 
CryptoModuleFactory.createParamsObjectFromAccumuloConfiguration(conf);
-    params.setAlgorithmName("DESede");
+    params.setKeyAlgorithmName("DESede");
     params.setKeyLength(24 * 8);
 
     ByteArrayInputStream in = new ByteArrayInputStream(resultingBytes);
diff --git a/core/src/test/resources/crypto-on-accumulo-site.xml 
b/core/src/test/resources/crypto-on-accumulo-site.xml
index ebfc9ae4c0..f5824c40d6 100644
--- a/core/src/test/resources/crypto-on-accumulo-site.xml
+++ b/core/src/test/resources/crypto-on-accumulo-site.xml
@@ -80,7 +80,11 @@
       <value>AES/CFB/NoPadding</value>
     </property>
     <property>
-      <name>crypto.cipher.algorithm.name</name>
+      <name>crypto.wal.cipher.suite</name>
+      <value>AES/CBC/NoPadding</value>
+    </property>
+    <property>
+      <name>crypto.cipher.key.algorithm.name</name>
       <value>AES</value>
     </property>
     <property>
diff --git 
a/core/src/test/resources/crypto-on-no-key-encryption-accumulo-site.xml 
b/core/src/test/resources/crypto-on-no-key-encryption-accumulo-site.xml
index d980783900..a82f9f9d73 100644
--- a/core/src/test/resources/crypto-on-no-key-encryption-accumulo-site.xml
+++ b/core/src/test/resources/crypto-on-no-key-encryption-accumulo-site.xml
@@ -80,7 +80,7 @@
       <value>AES/CFB/NoPadding</value>
     </property>
     <property>
-      <name>crypto.cipher.algorithm.name</name>
+      <name>crypto.cipher.key.algorithm.name</name>
       <value>AES</value>
     </property>
     <property>
diff --git 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/log/DfsLogger.java 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/log/DfsLogger.java
index d336c3c8f8..d48907f7e6 100644
--- 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/log/DfsLogger.java
+++ 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/log/DfsLogger.java
@@ -467,6 +467,10 @@ public synchronized void open(String address) throws 
IOException {
       logFile.write(LOG_FILE_HEADER_V3.getBytes(UTF_8));
 
       CryptoModuleParameters params = 
CryptoModuleFactory.createParamsObjectFromAccumuloConfiguration(conf.getConfiguration());
+      // Immediately update to the correct cipher. Doing this here keeps the 
CryptoModule independent of the writers using it
+      if 
(params.getAllOptions().get(Property.CRYPTO_WAL_CIPHER_SUITE.getKey()) != null) 
{
+        
params.setCipherSuite(params.getAllOptions().get(Property.CRYPTO_WAL_CIPHER_SUITE.getKey()));
+      }
 
       NoFlushOutputStream nfos = new NoFlushOutputStream(logFile);
       params.setPlaintextOutputStream(nfos);
diff --git a/test/src/main/java/org/apache/accumulo/test/ShellConfigIT.java 
b/test/src/main/java/org/apache/accumulo/test/ShellConfigIT.java
index 977cc36bbb..f90435dd06 100644
--- a/test/src/main/java/org/apache/accumulo/test/ShellConfigIT.java
+++ b/test/src/main/java/org/apache/accumulo/test/ShellConfigIT.java
@@ -93,11 +93,11 @@ public void experimentalPropTest() throws Exception {
       Assert.fail("Unknown token type");
     }
 
-    assertTrue(Property.CRYPTO_CIPHER_ALGORITHM_NAME.isExperimental());
+    assertTrue(Property.CRYPTO_CIPHER_KEY_ALGORITHM_NAME.isExperimental());
 
     String configOutput = ts.exec("config");
 
     
assertTrue(configOutput.contains(PerTableVolumeChooser.TABLE_VOLUME_CHOOSER));
-    
assertFalse(configOutput.contains(Property.CRYPTO_CIPHER_ALGORITHM_NAME.getKey()));
+    
assertFalse(configOutput.contains(Property.CRYPTO_CIPHER_KEY_ALGORITHM_NAME.getKey()));
   }
 }


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to