Skip to content

Commit 4008d96

Browse files
authored
RANGER-5388: Actual calculated salt size should be updated into the DB (#721)
1 parent d529cc3 commit 4008d96

File tree

2 files changed

+62
-34
lines changed

2 files changed

+62
-34
lines changed

kms/src/main/java/org/apache/hadoop/crypto/key/RangerMasterKey.java

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -94,22 +94,23 @@ public static void getPasswordParam(String paddedEncryptedPwd) {
9494
if (encryptedPwd != null && encryptedPwd.length >= 7) {
9595
int index = 0;
9696

97-
mkCipher = encryptedPwd[index];
98-
mkKeySize = Integer.parseInt(encryptedPwd[++index]);
99-
saltSize = Integer.parseInt(encryptedPwd[++index]);
100-
pbeAlgo = encryptedPwd[++index];
101-
mdAlgo = encryptedPwd[++index];
102-
iterationCount = Integer.parseInt(encryptedPwd[++index]);
103-
salt = encryptedPwd[++index];
104-
password = encryptedPwd[++index];
97+
mkCipher = encryptedPwd[index];
98+
mkKeySize = Integer.parseInt(encryptedPwd[++index]);
99+
int tempSaltSize = Integer.parseInt(encryptedPwd[++index]);
100+
pbeAlgo = encryptedPwd[++index];
101+
saltSize = calculateCompliantSaltSize(tempSaltSize, SupportedPBECryptoAlgo.valueOf(pbeAlgo));
102+
mdAlgo = encryptedPwd[++index];
103+
iterationCount = Integer.parseInt(encryptedPwd[++index]);
104+
salt = encryptedPwd[++index];
105+
password = encryptedPwd[++index];
105106
} else {
106-
mkCipher = DEFAULT_MK_CIPHER;
107-
mkKeySize = DEFAULT_MK_KeySize;
108-
saltSize = DEFAULT_SALT_SIZE;
109-
pbeAlgo = isFipsEnabled ? SupportedPBECryptoAlgo.PBEWithMD5AndTripleDES.getAlgoName() : defaultCryptAlgo.getAlgoName();
110-
mdAlgo = defaultMdAlgo;
111-
password = paddedEncryptedPwd;
112-
salt = password;
107+
mkCipher = DEFAULT_MK_CIPHER;
108+
mkKeySize = DEFAULT_MK_KeySize;
109+
pbeAlgo = isFipsEnabled ? SupportedPBECryptoAlgo.PBEWithMD5AndTripleDES.getAlgoName() : defaultCryptAlgo.getAlgoName();
110+
saltSize = calculateCompliantSaltSize(DEFAULT_SALT_SIZE, SupportedPBECryptoAlgo.valueOf(pbeAlgo));
111+
mdAlgo = defaultMdAlgo;
112+
password = paddedEncryptedPwd;
113+
salt = password;
113114

114115
if (password != null) {
115116
iterationCount = password.toCharArray().length + 1;
@@ -181,17 +182,16 @@ public void init() {
181182
defaultCryptAlgo = isFipsEnabled ? SupportedPBECryptoAlgo.PBKDF2WithHmacSHA256 : defaultCryptAlgo;
182183
mkCipher = getConfig("ranger.kms.service.masterkey.password.cipher", DEFAULT_MK_CIPHER);
183184
mkKeySize = getIntConfig("ranger.kms.service.masterkey.password.size", DEFAULT_MK_KeySize);
184-
saltSize = getIntConfig("ranger.kms.service.masterkey.password.salt.size", DEFAULT_SALT_SIZE);
185-
salt = getConfig("ranger.kms.service.masterkey.password.salt", DEFAULT_SALT);
186185
pbeAlgo = getConfig("ranger.kms.service.masterkey.password.encryption.algorithm", defaultCryptAlgo.getAlgoName());
187186
encrCryptoAlgo = SupportedPBECryptoAlgo.valueOf(pbeAlgo);
187+
saltSize = calculateCompliantSaltSize(getIntConfig("ranger.kms.service.masterkey.password.salt.size", DEFAULT_SALT_SIZE), encrCryptoAlgo);
188+
salt = getConfig("ranger.kms.service.masterkey.password.salt", DEFAULT_SALT);
188189
mdAlgo = getConfig("ranger.kms.service.masterkey.password.md.algorithm", defaultMdAlgo);
189190
iterationCount = getIntConfig("ranger.kms.service.masterkey.password.iteration.count", DEFAULT_ITERATION_COUNT);
190191
paddingString = Joiner.on(",").skipNulls().join(mkCipher, mkKeySize, saltSize, pbeAlgo, mdAlgo, iterationCount, salt);
191192

192193
logger.info("Selected DEFAULT_CRYPT_ALGO={}", defaultCryptAlgo);
193-
logger.info("Selected MD_ALGO={}", mdAlgo);
194-
logger.info("Selected ENCR_CRYPTO_ALGO={}", encrCryptoAlgo);
194+
logger.info("MK metadata={}", paddingString);
195195
logger.debug("<== RangerMasterKey.init()");
196196
}
197197

@@ -541,15 +541,12 @@ private PBEKeySpec getPBEParameterSpec(String password, SupportedPBECryptoAlgo e
541541
logger.debug("==> RangerMasterKey.getPBEParameterSpec()");
542542

543543
PBEKeySpec pbeKeySpec;
544+
char[] compliantPwd = getCompliantPassword(password, encrAlgo).toCharArray();
545+
544546
if (SupportedPBECryptoAlgo.isFIPSCompliantAlgorithm(encrAlgo)) {
545-
// For FIPS, salt size must be at least 128 bits, that is, at least 16 in length.
546-
int saltSize = RangerMasterKey.saltSize;
547-
while (saltSize < 16) {
548-
saltSize = saltSize * 2;
549-
}
550-
pbeKeySpec = new PBEKeySpec(getFIPSCompliantPassword(password).toCharArray(), generateSalt(saltSize), iterationCount, encrAlgo.getKeyLength());
547+
pbeKeySpec = new PBEKeySpec(compliantPwd, generateSalt(saltSize), iterationCount, encrAlgo.getKeyLength());
551548
} else {
552-
pbeKeySpec = new PBEKeySpec(password.toCharArray(), generateSalt(RangerMasterKey.saltSize), iterationCount);
549+
pbeKeySpec = new PBEKeySpec(compliantPwd, generateSalt(saltSize), iterationCount);
553550
}
554551
return pbeKeySpec;
555552
}
@@ -570,14 +567,32 @@ private byte[] generateSalt(int saltSize) throws Throwable {
570567
If provided password is less than 14, this method appends the same password till it reaches the minimum length of 14.
571568
And it is for FIPS only.
572569
*/
573-
private String getFIPSCompliantPassword(String password) {
570+
private String getCompliantPassword(String password, SupportedPBECryptoAlgo encrAlgo) {
574571
String newPwd = password;
575-
while (newPwd.length() < 14) {
576-
newPwd = newPwd.concat(password);
572+
573+
if (encrAlgo.getMinPwdLength().isPresent()) {
574+
int requiredPwdLength = encrAlgo.getMinPwdLength().get();
575+
while (newPwd.length() < requiredPwdLength) {
576+
newPwd = newPwd.concat(password);
577+
}
577578
}
579+
578580
return newPwd;
579581
}
580582

583+
// For FIPS, salt size must be at least 128 bits, that is, at least 16 in length.
584+
private static int calculateCompliantSaltSize(int saltSize, SupportedPBECryptoAlgo encrAlgo) {
585+
int compliantSaltSize = saltSize;
586+
if (encrAlgo.getMinSaltSize().isPresent()) {
587+
int minSaltSize = encrAlgo.getMinSaltSize().get();
588+
while (compliantSaltSize < minSaltSize) {
589+
compliantSaltSize = compliantSaltSize * 2;
590+
}
591+
}
592+
593+
return compliantSaltSize;
594+
}
595+
581596
private byte[] encryptKey(byte[] data, PBEKeySpec keyspec) throws Throwable {
582597
logger.debug("==> RangerMasterKey.encryptKey()");
583598

kms/src/main/java/org/apache/hadoop/crypto/key/SupportedPBECryptoAlgo.java

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,34 @@
2222
import javax.crypto.spec.PBEParameterSpec;
2323

2424
import java.security.spec.AlgorithmParameterSpec;
25+
import java.util.Optional;
2526
import java.util.function.Function;
2627

2728
public enum SupportedPBECryptoAlgo {
2829
@Deprecated
2930
PBEWithMD5AndTripleDES("PBEWithMD5AndTripleDES",
3031
"PBEWithMD5AndTripleDES",
31-
0, keySpec -> new PBEParameterSpec(keySpec.getSalt(), keySpec.getIterationCount())),
32+
0, Optional.empty(), Optional.empty(), keySpec -> new PBEParameterSpec(keySpec.getSalt(), keySpec.getIterationCount())),
3233
@Deprecated
3334
PBEWithMD5AndDES("PBEWithMD5AndDES",
3435
"PBEWithMD5AndDES",
35-
0, keySpec -> new PBEParameterSpec(keySpec.getSalt(), keySpec.getIterationCount())),
36+
0, Optional.empty(), Optional.empty(), keySpec -> new PBEParameterSpec(keySpec.getSalt(), keySpec.getIterationCount())),
3637
PBKDF2WithHmacSHA256("PBKDF2WithHmacSHA256",
3738
"AES/CBC/PKCS7Padding",
38-
64 * 4, keySpec -> new IvParameterSpec(keySpec.getSalt()));
39+
64 * 4, Optional.of(16), Optional.of(14), keySpec -> new IvParameterSpec(keySpec.getSalt()));
3940
private final String encrAlgoName;
4041
private final String cipherTransformation;
41-
private final int keyLength;
42+
private final int keyLength;
43+
private final Optional<Integer> minSaltSize;
44+
private final Optional<Integer> minPwdLength;
4245
private final Function<PBEKeySpec, AlgorithmParameterSpec> algoParamSpecFunc;
4346

44-
SupportedPBECryptoAlgo(String encrAlgoName, String cipherTransformation, int keyLength, Function<PBEKeySpec, AlgorithmParameterSpec> algoParamSpecFunc) {
47+
SupportedPBECryptoAlgo(String encrAlgoName, String cipherTransformation, int keyLength, Optional<Integer> minSaltSize, Optional<Integer> minPwdLength, Function<PBEKeySpec, AlgorithmParameterSpec> algoParamSpecFunc) {
4548
this.encrAlgoName = encrAlgoName;
4649
this.cipherTransformation = cipherTransformation;
4750
this.keyLength = keyLength;
51+
this.minSaltSize = minSaltSize;
52+
this.minPwdLength = minPwdLength;
4853
this.algoParamSpecFunc = algoParamSpecFunc;
4954
}
5055

@@ -60,6 +65,14 @@ public String getCipherTransformation() {
6065
return this.cipherTransformation;
6166
}
6267

68+
public Optional<Integer> getMinSaltSize() {
69+
return this.minSaltSize;
70+
}
71+
72+
public Optional<Integer> getMinPwdLength() {
73+
return this.minPwdLength;
74+
}
75+
6376
public AlgorithmParameterSpec getAlgoParamSpec(PBEKeySpec keySpec) {
6477
return this.algoParamSpecFunc.apply(keySpec);
6578
}

0 commit comments

Comments
 (0)