mirror of https://github.com/apache/nifi.git
NIFI-13525 Removed unused classes from nifi-security-crypto-key
This closes #9057 - Removed Derived Key Parameter Reader and implementations - Removed bcrypt and scrypt Derived Key Providers - Removed unused dependency from nifi-cipher-processors Signed-off-by: Joseph Witt <joewitt@apache.org>
This commit is contained in:
parent
b2840bd851
commit
62c66a12d1
|
@ -1,30 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key;
|
||||
|
||||
/**
|
||||
* Abstraction for reading Derived Key Parameter Specifications from serialized parameters
|
||||
*/
|
||||
public interface DerivedKeyParameterSpecReader<T extends DerivedKeyParameterSpec> {
|
||||
/**
|
||||
* Read serialized parameters and return Derived Key Parameter Specification
|
||||
*
|
||||
* @param serializedParameters Serialized parameters
|
||||
* @return Derived Key Parameter Specification
|
||||
*/
|
||||
T read(byte[] serializedParameters);
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.argon2;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyParameterSpecReader;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Argon2 implementation reads a US-ASCII string of bytes using the Password-Hashing-Competition String Format specification
|
||||
*/
|
||||
public class Argon2DerivedKeyParameterSpecReader implements DerivedKeyParameterSpecReader<Argon2DerivedKeyParameterSpec> {
|
||||
/** Argon2id hybrid with version 1.3 and 22 character Base64 encoded salt with optional trailing hash parameter */
|
||||
private static final Pattern PHC_STRING_FORMAT = Pattern.compile("^\\$argon2id\\$v=19\\$m=(\\d+),t=(\\d+),p=(\\d+)\\$([\\w/+]{22})(\\$[\\w/+]+)?$");
|
||||
|
||||
private static final int MEMORY_GROUP = 1;
|
||||
|
||||
private static final int ITERATIONS_GROUP = 2;
|
||||
|
||||
private static final int PARALLELISM_GROUP = 3;
|
||||
|
||||
private static final int SALT_GROUP = 4;
|
||||
|
||||
private static final Charset PARAMETERS_CHARACTER_SET = StandardCharsets.US_ASCII;
|
||||
|
||||
private static final Base64.Decoder decoder = Base64.getDecoder();
|
||||
|
||||
/**
|
||||
* Read serialized parameters parsed from US-ASCII string of bytes
|
||||
*
|
||||
* @param serializedParameters Serialized parameters
|
||||
* @return Argon2 Parameter Specification
|
||||
*/
|
||||
@Override
|
||||
public Argon2DerivedKeyParameterSpec read(final byte[] serializedParameters) {
|
||||
Objects.requireNonNull(serializedParameters, "Parameters required");
|
||||
final String parameters = new String(serializedParameters, PARAMETERS_CHARACTER_SET);
|
||||
|
||||
final Matcher matcher = PHC_STRING_FORMAT.matcher(parameters);
|
||||
if (matcher.matches()) {
|
||||
final String memoryGroup = matcher.group(MEMORY_GROUP);
|
||||
final String iterationsGroup = matcher.group(ITERATIONS_GROUP);
|
||||
final String parallelismGroup = matcher.group(PARALLELISM_GROUP);
|
||||
final String saltGroup = matcher.group(SALT_GROUP);
|
||||
|
||||
final int memory = Integer.parseInt(memoryGroup);
|
||||
final int iterations = Integer.parseInt(iterationsGroup);
|
||||
final int parallelism = Integer.parseInt(parallelismGroup);
|
||||
final byte[] salt = decoder.decode(saltGroup);
|
||||
return new Argon2DerivedKeyParameterSpec(
|
||||
memory,
|
||||
iterations,
|
||||
parallelism,
|
||||
salt
|
||||
);
|
||||
} else {
|
||||
final String message = String.format("Argon2 serialized parameters [%s] format not matched", parameters);
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.bcrypt;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Base64 Decoder translates from bcrypt Base64 characters to RFC 4648 characters
|
||||
*/
|
||||
class BcryptBase64Decoder {
|
||||
/** Alphabet of shared characters following common ordering */
|
||||
private static final String SHARED_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
|
||||
/** bcrypt alphabet defined according to the OpenBSD bcrypt function beginning with control characters */
|
||||
private static final String BCRYPT_ALPHABET = String.format("./%s", SHARED_ALPHABET);
|
||||
|
||||
/** Standard alphabet defined according to RFC 4648 ending with control characters */
|
||||
private static final String STANDARD_ALPHABET = String.format("%s+/", SHARED_ALPHABET);
|
||||
|
||||
private static final Map<Character, Character> BCRYPT_STANDARD_CHARACTERS = new LinkedHashMap<>();
|
||||
|
||||
private static final Base64.Decoder decoder = Base64.getDecoder();
|
||||
|
||||
static {
|
||||
final char[] bcryptCharacters = BCRYPT_ALPHABET.toCharArray();
|
||||
final char[] standardCharacters = STANDARD_ALPHABET.toCharArray();
|
||||
|
||||
for (int i = 0; i < bcryptCharacters.length; i++) {
|
||||
final char bcryptCharacter = bcryptCharacters[i];
|
||||
final char standardCharacter = standardCharacters[i];
|
||||
BCRYPT_STANDARD_CHARACTERS.put(bcryptCharacter, standardCharacter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode bcrypt Base64 encoded ASCII characters to support reading salt and hash strings
|
||||
*
|
||||
* @param encoded ASCII string of characters encoded using bcrypt Base64 characters
|
||||
* @return Decoded bytes
|
||||
*/
|
||||
static byte[] decode(final String encoded) {
|
||||
final int encodedLength = encoded.length();
|
||||
final byte[] converted = new byte[encodedLength];
|
||||
for (int i = 0; i < encodedLength; i++) {
|
||||
final char encodedCharacter = encoded.charAt(i);
|
||||
final char standardCharacter = getStandardCharacter(encodedCharacter);
|
||||
converted[i] = (byte) standardCharacter;
|
||||
}
|
||||
return decoder.decode(converted);
|
||||
}
|
||||
|
||||
private static char getStandardCharacter(final char encodedCharacter) {
|
||||
final Character standardCharacter = BCRYPT_STANDARD_CHARACTERS.get(encodedCharacter);
|
||||
if (standardCharacter == null) {
|
||||
final String message = String.format("Encoded character [%c] not supported for bcrypt Base64 decoding", encodedCharacter);
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
return standardCharacter;
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.bcrypt;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyParameterSpec;
|
||||
|
||||
/**
|
||||
* bcrypt key derivation function parameter specification
|
||||
*/
|
||||
public class BcryptDerivedKeyParameterSpec implements DerivedKeyParameterSpec {
|
||||
private final int cost;
|
||||
|
||||
private final byte[] salt;
|
||||
|
||||
/**
|
||||
* bcrypt Parameter Specification constructor with required properties
|
||||
*
|
||||
* @param cost Cost parameter
|
||||
* @param salt Array of random salt bytes
|
||||
*/
|
||||
public BcryptDerivedKeyParameterSpec(
|
||||
final int cost,
|
||||
final byte[] salt
|
||||
) {
|
||||
this.cost = cost;
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public int getCost() {
|
||||
return cost;
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.bcrypt;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyParameterSpecReader;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* bcrypt implementation reads a US-ASCII string of bytes using the Modular Crypt Format specification as added in NiFi 0.5.0
|
||||
*/
|
||||
public class BcryptDerivedKeyParameterSpecReader implements DerivedKeyParameterSpecReader<BcryptDerivedKeyParameterSpec> {
|
||||
/** Modular Crypt Format containing the cost as a zero-padded number with a trailing bcrypt-Base64 encoded 16 byte salt and optional hash */
|
||||
private static final Pattern MODULAR_CRYPT_FORMAT = Pattern.compile("^\\$2[abxy]\\$(\\d{2})\\$([\\w/.]{22})([\\w/.]{31})?$");
|
||||
|
||||
private static final int COST_GROUP = 1;
|
||||
|
||||
private static final int SALT_GROUP = 2;
|
||||
|
||||
private static final Charset PARAMETERS_CHARACTER_SET = StandardCharsets.US_ASCII;
|
||||
|
||||
/**
|
||||
* Read serialized parameters parsed from US-ASCII string of bytes
|
||||
*
|
||||
* @param serializedParameters Serialized parameters
|
||||
* @return bcrypt Parameter Specification
|
||||
*/
|
||||
@Override
|
||||
public BcryptDerivedKeyParameterSpec read(final byte[] serializedParameters) {
|
||||
Objects.requireNonNull(serializedParameters, "Parameters required");
|
||||
final String parameters = new String(serializedParameters, PARAMETERS_CHARACTER_SET);
|
||||
|
||||
final Matcher matcher = MODULAR_CRYPT_FORMAT.matcher(parameters);
|
||||
if (matcher.matches()) {
|
||||
final String costGroup = matcher.group(COST_GROUP);
|
||||
final String saltGroup = matcher.group(SALT_GROUP);
|
||||
|
||||
final int cost = Integer.parseInt(costGroup);
|
||||
final byte[] salt = BcryptBase64Decoder.decode(saltGroup);
|
||||
|
||||
return new BcryptDerivedKeyParameterSpec(cost, salt);
|
||||
} else {
|
||||
final String message = String.format("bcrypt serialized parameters [%s] format not matched", parameters);
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,83 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.bcrypt;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKey;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyProvider;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeySpec;
|
||||
import org.apache.nifi.security.crypto.key.DerivedSecretKey;
|
||||
import org.bouncycastle.crypto.generators.OpenBSDBCrypt;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* bcrypt implementation of Derived Key Provider based on Bouncy Castle bcrypt components with SHA-512 digest for derived key
|
||||
*/
|
||||
public class BcryptDerivedKeyProvider implements DerivedKeyProvider<BcryptDerivedKeyParameterSpec> {
|
||||
private static final Charset SERIALIZED_CHARACTER_SET = StandardCharsets.US_ASCII;
|
||||
|
||||
private static final int SERIALIZED_HASH_START_INDEX = 29;
|
||||
|
||||
private static final String DIGEST_ALGORITHM = "SHA-512";
|
||||
|
||||
private static final String BCRYPT_VERSION = "2a";
|
||||
|
||||
/**
|
||||
* Get Derived Key using bcrypt version 2a and provided specification with SHA-512 digest of encoded raw hash bytes
|
||||
*
|
||||
* @param derivedKeySpec Derived Key Specification
|
||||
* @return Derived Secret Key
|
||||
*/
|
||||
@Override
|
||||
public DerivedKey getDerivedKey(final DerivedKeySpec<BcryptDerivedKeyParameterSpec> derivedKeySpec) {
|
||||
final String serialized = getHashMessage(derivedKeySpec);
|
||||
final byte[] hashMessage = serialized.getBytes(SERIALIZED_CHARACTER_SET);
|
||||
|
||||
final byte[] encodedRawHash = Arrays.copyOfRange(hashMessage, SERIALIZED_HASH_START_INDEX, hashMessage.length);
|
||||
final byte[] derivedKeyBytes = getDerivedKeyBytes(encodedRawHash, derivedKeySpec.getDerivedKeyLength());
|
||||
return new DerivedSecretKey(derivedKeyBytes, derivedKeySpec.getAlgorithm(), serialized);
|
||||
}
|
||||
|
||||
private String getHashMessage(final DerivedKeySpec<BcryptDerivedKeyParameterSpec> derivedKeySpec) {
|
||||
final BcryptDerivedKeyParameterSpec parameterSpec = derivedKeySpec.getParameterSpec();
|
||||
|
||||
final int cost = parameterSpec.getCost();
|
||||
final byte[] salt = parameterSpec.getSalt();
|
||||
|
||||
final char[] password = derivedKeySpec.getPassword();
|
||||
|
||||
return OpenBSDBCrypt.generate(BCRYPT_VERSION, password, salt, cost);
|
||||
}
|
||||
|
||||
private byte[] getDerivedKeyBytes(final byte[] hash, final int derivedKeyLength) {
|
||||
final MessageDigest messageDigest = getMessageDigest();
|
||||
final byte[] digested = messageDigest.digest(hash);
|
||||
return Arrays.copyOf(digested, derivedKeyLength);
|
||||
}
|
||||
|
||||
private MessageDigest getMessageDigest() {
|
||||
try {
|
||||
return MessageDigest.getInstance(DIGEST_ALGORITHM);
|
||||
} catch (final NoSuchAlgorithmException e) {
|
||||
throw new UnsupportedOperationException(DIGEST_ALGORITHM, e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.detection;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyParameterSpecReader;
|
||||
import org.apache.nifi.security.crypto.key.argon2.Argon2DerivedKeyParameterSpecReader;
|
||||
import org.apache.nifi.security.crypto.key.bcrypt.BcryptDerivedKeyParameterSpecReader;
|
||||
import org.apache.nifi.security.crypto.key.io.ByteBufferSearch;
|
||||
import org.apache.nifi.security.crypto.key.pbkdf2.Pbkdf2DerivedKeyParameterSpecReader;
|
||||
import org.apache.nifi.security.crypto.key.scrypt.ScryptDerivedKeyParameterSpecReader;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Delegating implementation capable of selecting a reader based on detected header bytes of serialized parameters
|
||||
*/
|
||||
public class DetectedDerivedKeyParameterSpecReader implements DerivedKeyParameterSpecReader<DerivedKeyParameterSpec> {
|
||||
/** Argon2id header as implemented in NiFi 1.12.0 */
|
||||
private static final byte[] ARGON2_ID_DELIMITER = {'$', 'a', 'r', 'g', 'o', 'n', '2', 'i', 'd', '$'};
|
||||
|
||||
/** bcrypt 2a header as implemented in NiFi 0.5.0 */
|
||||
private static final byte[] BCRYPT_2A_DELIMITER = {'$', '2', 'a', '$'};
|
||||
|
||||
/** scrypt header as implemented in NiFi 0.5.0 */
|
||||
private static final byte[] SCRYPT_DELIMITER = {'$', 's', '0', '$'};
|
||||
|
||||
private static final Argon2DerivedKeyParameterSpecReader argon2Reader = new Argon2DerivedKeyParameterSpecReader();
|
||||
|
||||
private static final BcryptDerivedKeyParameterSpecReader bcryptReader = new BcryptDerivedKeyParameterSpecReader();
|
||||
|
||||
private static final ScryptDerivedKeyParameterSpecReader scryptReader = new ScryptDerivedKeyParameterSpecReader();
|
||||
|
||||
private static final Pbkdf2DerivedKeyParameterSpecReader pbkdf2Reader = new Pbkdf2DerivedKeyParameterSpecReader();
|
||||
|
||||
/**
|
||||
* Read Parameter Specification selects a Reader based on header bytes defaulting to PBKDF2 in absence of a matched pattern
|
||||
*
|
||||
* @param serializedParameters Serialized parameters
|
||||
* @return Derived Key Parameter Specification read from serialized parameters
|
||||
*/
|
||||
@Override
|
||||
public DerivedKeyParameterSpec read(final byte[] serializedParameters) {
|
||||
final ByteBuffer buffer = ByteBuffer.wrap(serializedParameters);
|
||||
final DerivedKeyParameterSpecReader<? extends DerivedKeyParameterSpec> reader = getReader(buffer);
|
||||
return reader.read(serializedParameters);
|
||||
}
|
||||
|
||||
private DerivedKeyParameterSpecReader<? extends DerivedKeyParameterSpec> getReader(final ByteBuffer buffer) {
|
||||
final DerivedKeyParameterSpecReader<? extends DerivedKeyParameterSpec> reader;
|
||||
if (ByteBufferSearch.indexOf(buffer, ARGON2_ID_DELIMITER) == 0) {
|
||||
reader = argon2Reader;
|
||||
} else if (ByteBufferSearch.indexOf(buffer, BCRYPT_2A_DELIMITER) == 0) {
|
||||
reader = bcryptReader;
|
||||
} else if (ByteBufferSearch.indexOf(buffer, SCRYPT_DELIMITER) == 0) {
|
||||
reader = scryptReader;
|
||||
} else {
|
||||
reader = pbkdf2Reader;
|
||||
}
|
||||
return reader;
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.detection;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKey;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyProvider;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeySpec;
|
||||
import org.apache.nifi.security.crypto.key.argon2.Argon2DerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.argon2.Argon2DerivedKeyProvider;
|
||||
import org.apache.nifi.security.crypto.key.bcrypt.BcryptDerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.bcrypt.BcryptDerivedKeyProvider;
|
||||
import org.apache.nifi.security.crypto.key.pbkdf2.Pbkdf2DerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.pbkdf2.Pbkdf2DerivedKeyProvider;
|
||||
import org.apache.nifi.security.crypto.key.scrypt.ScryptDerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.scrypt.ScryptDerivedKeyProvider;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Provider delegating to configured implementations based on Parameter Specification class
|
||||
*/
|
||||
public class DetectedDerivedKeyProvider implements DerivedKeyProvider<DerivedKeyParameterSpec> {
|
||||
private static final Map<Class<? extends DerivedKeyParameterSpec>, DerivedKeyProvider<? extends DerivedKeyParameterSpec>> providers = new LinkedHashMap<>();
|
||||
|
||||
static {
|
||||
providers.put(Argon2DerivedKeyParameterSpec.class, new Argon2DerivedKeyProvider());
|
||||
providers.put(BcryptDerivedKeyParameterSpec.class, new BcryptDerivedKeyProvider());
|
||||
providers.put(ScryptDerivedKeyParameterSpec.class, new ScryptDerivedKeyProvider());
|
||||
providers.put(Pbkdf2DerivedKeyParameterSpec.class, new Pbkdf2DerivedKeyProvider());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Derived Key using implementation selected based on assignable Parameter Specification class mapped to Provider
|
||||
*
|
||||
* @param derivedKeySpec Derived Key Specification
|
||||
* @return Derived Key
|
||||
*/
|
||||
@Override
|
||||
public DerivedKey getDerivedKey(final DerivedKeySpec<DerivedKeyParameterSpec> derivedKeySpec) {
|
||||
Objects.requireNonNull(derivedKeySpec, "Specification required");
|
||||
|
||||
final Class<? extends DerivedKeyParameterSpec> parameterSpecClass = derivedKeySpec.getParameterSpec().getClass();
|
||||
final DerivedKeyProvider<DerivedKeyParameterSpec> derivedKeyProvider = findProvider(parameterSpecClass);
|
||||
|
||||
return derivedKeyProvider.getDerivedKey(derivedKeySpec);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private DerivedKeyProvider<DerivedKeyParameterSpec> findProvider(final Class<? extends DerivedKeyParameterSpec> parameterSpecClass) {
|
||||
final Class<? extends DerivedKeyParameterSpec> foundSpecClass = providers.keySet()
|
||||
.stream()
|
||||
.filter(specClass -> specClass.isAssignableFrom(parameterSpecClass))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new UnsupportedOperationException(String.format("Parameter Specification [%s] not supported", parameterSpecClass)));
|
||||
|
||||
final DerivedKeyProvider<? extends DerivedKeyParameterSpec> derivedKeyProvider = providers.get(foundSpecClass);
|
||||
return (DerivedKeyProvider<DerivedKeyParameterSpec>) derivedKeyProvider;
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.io;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
* Byte Buffer Search utilities
|
||||
*/
|
||||
public class ByteBufferSearch {
|
||||
|
||||
private static final int END_OF_FILE = -1;
|
||||
|
||||
/**
|
||||
* Get starting index of delimiter in buffer
|
||||
*
|
||||
* @param buffer Byte Buffer to be searched
|
||||
* @param delimiter Delimiter
|
||||
* @return Starting index of delimiter or -1 when not found
|
||||
*/
|
||||
public static int indexOf(final ByteBuffer buffer, final byte[] delimiter) {
|
||||
final int bufferSearchLength = buffer.limit() - delimiter.length + 1;
|
||||
bufferSearch:
|
||||
for (int i = 0; i < bufferSearchLength; i++) {
|
||||
for (int j = 0; j < delimiter.length; j++) {
|
||||
final int bufferIndex = i + j;
|
||||
final byte indexByte = buffer.get(bufferIndex);
|
||||
final byte delimiterByte = delimiter[j];
|
||||
if (indexByte != delimiterByte) {
|
||||
continue bufferSearch;
|
||||
}
|
||||
}
|
||||
return i;
|
||||
}
|
||||
return END_OF_FILE;
|
||||
}
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.pbkdf2;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyParameterSpecReader;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* PBKDF2 implementation uses the serialized parameters as the salt with a hard-coded number of iterations as defined in NiFi 0.5.0
|
||||
*/
|
||||
public class Pbkdf2DerivedKeyParameterSpecReader implements DerivedKeyParameterSpecReader<Pbkdf2DerivedKeyParameterSpec> {
|
||||
protected static final int VERSION_0_5_0_ITERATIONS = 160000;
|
||||
|
||||
/**
|
||||
* Read serialized parameters and return as salt bytes with 160,000 iterations as defined in NiFi 0.5.0
|
||||
*
|
||||
* @param serializedParameters Serialized parameters
|
||||
* @return PBKDF2 Parameter Specification
|
||||
*/
|
||||
@Override
|
||||
public Pbkdf2DerivedKeyParameterSpec read(final byte[] serializedParameters) {
|
||||
Objects.requireNonNull(serializedParameters, "Parameters required");
|
||||
return new Pbkdf2DerivedKeyParameterSpec(VERSION_0_5_0_ITERATIONS, serializedParameters);
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.scrypt;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyParameterSpec;
|
||||
|
||||
/**
|
||||
* scrypt key derivation function parameter specification
|
||||
*/
|
||||
public class ScryptDerivedKeyParameterSpec implements DerivedKeyParameterSpec {
|
||||
private final int cost;
|
||||
|
||||
private final int blockSize;
|
||||
|
||||
private final int parallelization;
|
||||
|
||||
private final byte[] salt;
|
||||
|
||||
/**
|
||||
* scrypt Parameter Specification constructor with required properties
|
||||
*
|
||||
* @param cost CPU and memory cost parameter
|
||||
* @param blockSize Block size parameter
|
||||
* @param parallelization Parallelization parameter
|
||||
* @param salt Array of random salt bytes
|
||||
*/
|
||||
public ScryptDerivedKeyParameterSpec(
|
||||
final int cost,
|
||||
final int blockSize,
|
||||
final int parallelization,
|
||||
final byte[] salt
|
||||
) {
|
||||
this.cost = cost;
|
||||
this.blockSize = blockSize;
|
||||
this.parallelization = parallelization;
|
||||
this.salt = salt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getSalt() {
|
||||
return salt;
|
||||
}
|
||||
|
||||
public int getCost() {
|
||||
return cost;
|
||||
}
|
||||
|
||||
public int getBlockSize() {
|
||||
return blockSize;
|
||||
}
|
||||
|
||||
public int getParallelization() {
|
||||
return parallelization;
|
||||
}
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.scrypt;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyParameterSpecReader;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
import java.util.Objects;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* scrypt implementation reads a US-ASCII string of bytes using a Modular Crypt Format defined according to the com.lambdaworks:scrypt library
|
||||
*/
|
||||
public class ScryptDerivedKeyParameterSpecReader implements DerivedKeyParameterSpecReader<ScryptDerivedKeyParameterSpec> {
|
||||
/** Modular Crypt Format containing the parameters encoded as a 32-bit hexadecimal number with a trailing Base64 encoded salt and optional hash */
|
||||
private static final Pattern MODULAR_CRYPT_FORMAT = Pattern.compile("^\\$s0\\$([a-f0-9]{5,})\\$([\\w/=+]{11,64})\\$?([\\w/=+]{1,256})?$");
|
||||
|
||||
private static final int PARAMETERS_GROUP = 1;
|
||||
|
||||
private static final int SALT_GROUP = 2;
|
||||
|
||||
private static final Charset PARAMETERS_CHARACTER_SET = StandardCharsets.US_ASCII;
|
||||
|
||||
private static final int HEXADECIMAL_RADIX = 16;
|
||||
|
||||
private static final int LOG_BASE_2 = 2;
|
||||
|
||||
private static final int COST_BITS = 16;
|
||||
|
||||
private static final int SIZE_BITS = 8;
|
||||
|
||||
private static final int SIXTEEN_BIT_SHIFT = 0xffff;
|
||||
|
||||
private static final int EIGHT_BIT_SHIFT = 0xff;
|
||||
|
||||
private static final Base64.Decoder decoder = Base64.getDecoder();
|
||||
|
||||
@Override
|
||||
public ScryptDerivedKeyParameterSpec read(final byte[] serializedParameters) {
|
||||
Objects.requireNonNull(serializedParameters, "Parameters required");
|
||||
final String parameters = new String(serializedParameters, PARAMETERS_CHARACTER_SET);
|
||||
|
||||
final Matcher matcher = MODULAR_CRYPT_FORMAT.matcher(parameters);
|
||||
if (matcher.matches()) {
|
||||
final String parametersGroup = matcher.group(PARAMETERS_GROUP);
|
||||
final String saltGroup = matcher.group(SALT_GROUP);
|
||||
return readParameters(parametersGroup, saltGroup);
|
||||
} else {
|
||||
final String message = String.format("scrypt serialized parameters [%s] format not matched", parameters);
|
||||
throw new IllegalArgumentException(message);
|
||||
}
|
||||
}
|
||||
|
||||
private ScryptDerivedKeyParameterSpec readParameters(final String parametersEncoded, final String saltEncoded) {
|
||||
final long parameters = Long.parseLong(parametersEncoded, HEXADECIMAL_RADIX);
|
||||
final long costExponent = parameters >> COST_BITS & SIXTEEN_BIT_SHIFT;
|
||||
|
||||
final int cost = (int) Math.pow(LOG_BASE_2, costExponent);
|
||||
final int blockSize = (int) parameters >> SIZE_BITS & EIGHT_BIT_SHIFT;
|
||||
final int parallelization = (int) parameters & EIGHT_BIT_SHIFT;
|
||||
|
||||
final byte[] salt = decoder.decode(saltEncoded);
|
||||
return new ScryptDerivedKeyParameterSpec(cost, blockSize, parallelization, salt);
|
||||
}
|
||||
}
|
|
@ -1,96 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.scrypt;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKey;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyProvider;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeySpec;
|
||||
import org.apache.nifi.security.crypto.key.DerivedSecretKey;
|
||||
import org.bouncycastle.crypto.generators.SCrypt;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
/**
|
||||
* scrypt implementation of Derived Key Provider based on Bouncy Castle scrypt components described in RFC 7914
|
||||
*/
|
||||
public class ScryptDerivedKeyProvider implements DerivedKeyProvider<ScryptDerivedKeyParameterSpec> {
|
||||
private static final String SERIALIZED_FORMAT = "$s0$%s$%s$%s";
|
||||
|
||||
private static final int HEXADECIMAL_RADIX = 16;
|
||||
|
||||
private static final int LOG_BASE_2 = 2;
|
||||
|
||||
private static final int COST_BITS = 16;
|
||||
|
||||
private static final int SIZE_BITS = 8;
|
||||
|
||||
private static final Charset PASSWORD_CHARACTER_SET = StandardCharsets.UTF_8;
|
||||
|
||||
private static final Base64.Encoder encoder = Base64.getEncoder().withoutPadding();
|
||||
|
||||
/**
|
||||
* Get Derived Key using scrypt and provided specification
|
||||
*
|
||||
* @param derivedKeySpec Derived Key Specification
|
||||
* @return Derived Secret Key
|
||||
*/
|
||||
@Override
|
||||
public DerivedKey getDerivedKey(final DerivedKeySpec<ScryptDerivedKeyParameterSpec> derivedKeySpec) {
|
||||
final byte[] password = new String(derivedKeySpec.getPassword()).getBytes(PASSWORD_CHARACTER_SET);
|
||||
|
||||
final ScryptDerivedKeyParameterSpec parameterSpec = derivedKeySpec.getParameterSpec();
|
||||
final byte[] salt = parameterSpec.getSalt();
|
||||
final int cost = parameterSpec.getCost();
|
||||
final int blockSize = parameterSpec.getBlockSize();
|
||||
final int parallelization = parameterSpec.getParallelization();
|
||||
final int derivedKeyLength = derivedKeySpec.getDerivedKeyLength();
|
||||
|
||||
final byte[] derivedKeyBytes = SCrypt.generate(password, salt, cost, blockSize, parallelization, derivedKeyLength);
|
||||
|
||||
final String serialized = getSerialized(derivedKeyBytes, parameterSpec);
|
||||
return new DerivedSecretKey(derivedKeyBytes, derivedKeySpec.getAlgorithm(), serialized);
|
||||
}
|
||||
|
||||
private String getSerialized(final byte[] derivedKeyBytes, final ScryptDerivedKeyParameterSpec parameterSpec) {
|
||||
final String parametersEncoded = getParametersEncoded(parameterSpec);
|
||||
final String derivedKeyEncoded = encoder.encodeToString(derivedKeyBytes);
|
||||
final String saltEncoded = encoder.encodeToString(parameterSpec.getSalt());
|
||||
return String.format(
|
||||
SERIALIZED_FORMAT,
|
||||
parametersEncoded,
|
||||
saltEncoded,
|
||||
derivedKeyEncoded
|
||||
);
|
||||
}
|
||||
|
||||
private String getParametersEncoded(final ScryptDerivedKeyParameterSpec parameterSpec) {
|
||||
final long cost = log2(parameterSpec.getCost()) << COST_BITS;
|
||||
final long blockSize = parameterSpec.getBlockSize() << SIZE_BITS;
|
||||
final long parallelization = parameterSpec.getParallelization();
|
||||
final long parameters = cost | blockSize | parallelization;
|
||||
return Long.toString(parameters, HEXADECIMAL_RADIX);
|
||||
}
|
||||
|
||||
private long log2(final int number) {
|
||||
final double log = Math.log(number);
|
||||
final double logBase2 = Math.log(LOG_BASE_2);
|
||||
final double log2 = log / logBase2;
|
||||
return Math.round(log2);
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.argon2;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class Argon2DerivedKeyParameterSpecReaderTest {
|
||||
private static final byte[] STRING_PARAMETERS = String.class.getSimpleName().getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
private static final int MEMORY = 65536;
|
||||
|
||||
private static final int ITERATIONS = 2;
|
||||
|
||||
private static final int PARALLELISM = 1;
|
||||
|
||||
private static final String ARGON2_SALT_STRING = "QXJnb24yU2FsdFN0cmluZw";
|
||||
|
||||
private static final String PARAMETERS = String.format("$argon2id$v=19$m=%d,t=%d,p=%d$%s", MEMORY, ITERATIONS, PARALLELISM, ARGON2_SALT_STRING);
|
||||
|
||||
private static final String PARAMETERS_HASH = String.format("%s$6LOmoOXYJV0tXBJtxtD1Mg", PARAMETERS);
|
||||
|
||||
Base64.Decoder decoder = Base64.getDecoder();
|
||||
|
||||
Argon2DerivedKeyParameterSpecReader reader;
|
||||
|
||||
@BeforeEach
|
||||
void setReader() {
|
||||
reader = new Argon2DerivedKeyParameterSpecReader();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadException() {
|
||||
assertThrows(IllegalArgumentException.class, () -> reader.read(STRING_PARAMETERS));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRead() {
|
||||
final byte[] serializedParameters = PARAMETERS.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
final Argon2DerivedKeyParameterSpec parameterSpec = reader.read(serializedParameters);
|
||||
|
||||
assertParameterSpecEquals(parameterSpec);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadHash() {
|
||||
final byte[] serializedParameters = PARAMETERS_HASH.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
final Argon2DerivedKeyParameterSpec parameterSpec = reader.read(serializedParameters);
|
||||
|
||||
assertParameterSpecEquals(parameterSpec);
|
||||
}
|
||||
|
||||
private void assertParameterSpecEquals(final Argon2DerivedKeyParameterSpec parameterSpec) {
|
||||
assertNotNull(parameterSpec);
|
||||
assertEquals(MEMORY, parameterSpec.getMemory());
|
||||
assertEquals(ITERATIONS, parameterSpec.getIterations());
|
||||
assertEquals(PARALLELISM, parameterSpec.getParallelism());
|
||||
|
||||
final byte[] salt = decoder.decode(ARGON2_SALT_STRING);
|
||||
assertArrayEquals(salt, parameterSpec.getSalt());
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.bcrypt;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class BcryptDerivedKeyParameterSpecReaderTest {
|
||||
private static final byte[] STRING_PARAMETERS = String.class.getSimpleName().getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
private static final int COST = 12;
|
||||
|
||||
private static final String SALT_ENCODED = "R9h/cIPz0gi.URNNX3kh2O";
|
||||
|
||||
private static final String HASH = "PST9/PgBkqquzi.Ss7KIUgO2t0jWMUW";
|
||||
|
||||
private static final String SERIALIZED = String.format("$2a$%d$%s", COST, SALT_ENCODED);
|
||||
|
||||
private static final String SERIALIZED_HASH = String.format("%s%s", SERIALIZED, HASH);
|
||||
|
||||
BcryptDerivedKeyParameterSpecReader reader;
|
||||
|
||||
@BeforeEach
|
||||
void setReader() {
|
||||
reader = new BcryptDerivedKeyParameterSpecReader();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadException() {
|
||||
assertThrows(IllegalArgumentException.class, () -> reader.read(STRING_PARAMETERS));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRead() {
|
||||
final byte[] serializedParameters = SERIALIZED.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
final BcryptDerivedKeyParameterSpec parameterSpec = reader.read(serializedParameters);
|
||||
|
||||
assertParameterSpecEquals(parameterSpec);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadHash() {
|
||||
final byte[] serializedParameters = SERIALIZED_HASH.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
final BcryptDerivedKeyParameterSpec parameterSpec = reader.read(serializedParameters);
|
||||
|
||||
assertParameterSpecEquals(parameterSpec);
|
||||
}
|
||||
|
||||
private void assertParameterSpecEquals(final BcryptDerivedKeyParameterSpec parameterSpec) {
|
||||
assertNotNull(parameterSpec);
|
||||
assertEquals(COST, parameterSpec.getCost());
|
||||
|
||||
final byte[] salt = BcryptBase64Decoder.decode(SALT_ENCODED);
|
||||
assertArrayEquals(salt, parameterSpec.getSalt());
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.bcrypt;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKey;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeySpec;
|
||||
import org.apache.nifi.security.crypto.key.StandardDerivedKeySpec;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
class BcryptDerivedKeyProviderTest {
|
||||
private static final String PASSWORD = "abc123xyz";
|
||||
|
||||
private static final int COST = 12;
|
||||
|
||||
private static final String SALT_ENCODED = "R9h/cIPz0gi.URNNX3kh2O";
|
||||
|
||||
private static final String HASH = "PST9/PgBkqquzi.Ss7KIUgO2t0jWMUW";
|
||||
|
||||
private static final String SERIALIZED = String.format("$2a$%d$%s%s", COST, SALT_ENCODED, HASH);
|
||||
|
||||
private static final Charset SERIALIZED_CHARACTER_SET = StandardCharsets.US_ASCII;
|
||||
|
||||
private static final int DERIVED_KEY_LENGTH = 16;
|
||||
|
||||
private static final String ALGORITHM = "AES";
|
||||
|
||||
private static final String DIGEST_ALGORITHM = "SHA-512";
|
||||
|
||||
BcryptDerivedKeyProvider provider;
|
||||
|
||||
@BeforeEach
|
||||
void setProvider() {
|
||||
provider = new BcryptDerivedKeyProvider();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetDerivedKey() {
|
||||
final byte[] salt = BcryptBase64Decoder.decode(SALT_ENCODED);
|
||||
final BcryptDerivedKeyParameterSpec parameterSpec = new BcryptDerivedKeyParameterSpec(COST, salt);
|
||||
|
||||
final DerivedKeySpec<BcryptDerivedKeyParameterSpec> derivedKeySpec = new StandardDerivedKeySpec<>(
|
||||
PASSWORD.toCharArray(),
|
||||
DERIVED_KEY_LENGTH,
|
||||
ALGORITHM,
|
||||
parameterSpec
|
||||
);
|
||||
|
||||
final DerivedKey derivedKey = provider.getDerivedKey(derivedKeySpec);
|
||||
|
||||
assertNotNull(derivedKey);
|
||||
assertEquals(ALGORITHM, derivedKey.getAlgorithm());
|
||||
assertEquals(SERIALIZED, derivedKey.getSerialized());
|
||||
|
||||
final byte[] encodedHashBytes = HASH.getBytes(SERIALIZED_CHARACTER_SET);
|
||||
final byte[] digestedDerivedKey = getDerivedKeyBytes(encodedHashBytes);
|
||||
assertArrayEquals(digestedDerivedKey, derivedKey.getEncoded());
|
||||
}
|
||||
|
||||
private byte[] getDerivedKeyBytes(final byte[] hash) {
|
||||
final MessageDigest messageDigest = getMessageDigest();
|
||||
final byte[] digested = messageDigest.digest(hash);
|
||||
return Arrays.copyOf(digested, DERIVED_KEY_LENGTH);
|
||||
}
|
||||
|
||||
private MessageDigest getMessageDigest() {
|
||||
try {
|
||||
return MessageDigest.getInstance(DIGEST_ALGORITHM);
|
||||
} catch (final NoSuchAlgorithmException e) {
|
||||
throw new UnsupportedOperationException(DIGEST_ALGORITHM, e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.detection;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.argon2.Argon2DerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.bcrypt.BcryptDerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.pbkdf2.Pbkdf2DerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.scrypt.ScryptDerivedKeyParameterSpec;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
|
||||
class DetectedDerivedKeyParameterSpecReaderTest {
|
||||
|
||||
private static final String UNSPECIFIED_PARAMETERS = "unspecified";
|
||||
|
||||
private static final String ARGON2_PARAMETERS = "$argon2id$v=19$m=65536,t=2,p=1$QXJnb24yU2FsdFN0cmluZw";
|
||||
|
||||
private static final String BCRYPT_PARAMETERS = "$2a$12$R9h/cIPz0gi.URNNX3kh2O";
|
||||
|
||||
private static final String SCRYPT_PARAMETERS = "$s0$e0801$epIxT/h6HbbwHaehFnh/bw";
|
||||
|
||||
DetectedDerivedKeyParameterSpecReader reader;
|
||||
|
||||
@BeforeEach
|
||||
void setReader() {
|
||||
reader = new DetectedDerivedKeyParameterSpecReader();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testArgon2() {
|
||||
assertParameterSpecInstanceOf(Argon2DerivedKeyParameterSpec.class, ARGON2_PARAMETERS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBcrypt() {
|
||||
assertParameterSpecInstanceOf(BcryptDerivedKeyParameterSpec.class, BCRYPT_PARAMETERS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testScrypt() {
|
||||
assertParameterSpecInstanceOf(ScryptDerivedKeyParameterSpec.class, SCRYPT_PARAMETERS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPbkdf2() {
|
||||
assertParameterSpecInstanceOf(Pbkdf2DerivedKeyParameterSpec.class, UNSPECIFIED_PARAMETERS);
|
||||
}
|
||||
|
||||
private void assertParameterSpecInstanceOf(final Class<? extends DerivedKeyParameterSpec> parameterSpecClass, final String parameters) {
|
||||
final byte[] serializedParameters = parameters.getBytes(StandardCharsets.UTF_8);
|
||||
|
||||
final DerivedKeyParameterSpec parameterSpec = reader.read(serializedParameters);
|
||||
|
||||
assertInstanceOf(parameterSpecClass, parameterSpec);
|
||||
}
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.detection;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKey;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeySpec;
|
||||
import org.apache.nifi.security.crypto.key.StandardDerivedKeySpec;
|
||||
import org.apache.nifi.security.crypto.key.argon2.Argon2DerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.bcrypt.BcryptDerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.pbkdf2.Pbkdf2DerivedKeyParameterSpec;
|
||||
import org.apache.nifi.security.crypto.key.scrypt.ScryptDerivedKeyParameterSpec;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class DetectedDerivedKeyProviderTest {
|
||||
|
||||
private static final char[] PASSWORD = {'w', 'o', 'r', 'd'};
|
||||
|
||||
private static final int DERIVED_KEY_LENGTH = 16;
|
||||
|
||||
private static final String ALGORITHM = "AES";
|
||||
|
||||
private static final byte[] SALT = {'N', 'i', 'F', 'i', 'S', 'A', 'L', 'T'};
|
||||
|
||||
private static final int MINIMUM_ITERATIONS = 1;
|
||||
|
||||
private static final int MINIMUM_ARGON2_MEMORY = 2;
|
||||
|
||||
private static final int MINIMUM_PARALLELISM = 1;
|
||||
|
||||
private static final int MINIMUM_BCRYPT_COST = 4;
|
||||
|
||||
private static final byte[] BCRYPT_SALT = {'S', 'I', 'X', 'T', 'E', 'E', 'N', 'B', 'Y', 'T', 'E', 'S', 'S', 'A', 'L', 'T'};
|
||||
|
||||
private static final int MINIMUM_SCRYPT_COST = 2;
|
||||
|
||||
private static final int SCRYPT_BLOCK_SIZE = 16;
|
||||
|
||||
@Mock
|
||||
DerivedKeyParameterSpec unsupportedDerivedKeyParameterSpec;
|
||||
|
||||
DetectedDerivedKeyProvider provider;
|
||||
|
||||
@BeforeEach
|
||||
void setProvider() {
|
||||
provider = new DetectedDerivedKeyProvider();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testArgon2() {
|
||||
final Argon2DerivedKeyParameterSpec parameterSpec = new Argon2DerivedKeyParameterSpec(MINIMUM_ARGON2_MEMORY, MINIMUM_ITERATIONS, MINIMUM_PARALLELISM, SALT);
|
||||
assertDerivedKey(parameterSpec);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testBcrypt() {
|
||||
final BcryptDerivedKeyParameterSpec parameterSpec = new BcryptDerivedKeyParameterSpec(MINIMUM_BCRYPT_COST, BCRYPT_SALT);
|
||||
assertDerivedKey(parameterSpec);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testPbkdf2() {
|
||||
final Pbkdf2DerivedKeyParameterSpec parameterSpec = new Pbkdf2DerivedKeyParameterSpec(MINIMUM_ITERATIONS, SALT);
|
||||
assertDerivedKey(parameterSpec);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testScrypt() {
|
||||
final ScryptDerivedKeyParameterSpec parameterSpec = new ScryptDerivedKeyParameterSpec(MINIMUM_SCRYPT_COST, SCRYPT_BLOCK_SIZE, MINIMUM_PARALLELISM, SALT);
|
||||
assertDerivedKey(parameterSpec);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testUnsupported() {
|
||||
final DerivedKeySpec<DerivedKeyParameterSpec> derivedKeySpec = getDerivedKeySpec(unsupportedDerivedKeyParameterSpec);
|
||||
assertThrows(UnsupportedOperationException.class, () -> provider.getDerivedKey(derivedKeySpec));
|
||||
}
|
||||
|
||||
private <T extends DerivedKeyParameterSpec> DerivedKeySpec<T> getDerivedKeySpec(final T parameterSpec) {
|
||||
return new StandardDerivedKeySpec<>(PASSWORD, DERIVED_KEY_LENGTH, ALGORITHM, parameterSpec);
|
||||
}
|
||||
|
||||
private <T extends DerivedKeyParameterSpec> void assertDerivedKey(final T parameterSpec) {
|
||||
final DerivedKeySpec<DerivedKeyParameterSpec> derivedKeySpec = getDerivedKeySpec(parameterSpec);
|
||||
|
||||
final DerivedKey derivedKey = provider.getDerivedKey(derivedKeySpec);
|
||||
|
||||
assertNotNull(derivedKey);
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.pbkdf2;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
class Pbkdf2DerivedKeyParameterSpecReaderTest {
|
||||
private static final String STRING_PARAMETERS = String.class.getName();
|
||||
|
||||
Pbkdf2DerivedKeyParameterSpecReader reader;
|
||||
|
||||
@BeforeEach
|
||||
void setReader() {
|
||||
reader = new Pbkdf2DerivedKeyParameterSpecReader();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRead() {
|
||||
final byte[] serializedParameters = STRING_PARAMETERS.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
final Pbkdf2DerivedKeyParameterSpec parameterSpec = reader.read(serializedParameters);
|
||||
|
||||
assertNotNull(parameterSpec);
|
||||
assertEquals(Pbkdf2DerivedKeyParameterSpecReader.VERSION_0_5_0_ITERATIONS, parameterSpec.getIterations());
|
||||
assertArrayEquals(serializedParameters, parameterSpec.getSalt());
|
||||
}
|
||||
}
|
|
@ -1,88 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.scrypt;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Base64;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
|
||||
class ScryptDerivedKeyParameterSpecReaderTest {
|
||||
private static final byte[] STRING_PARAMETERS = String.class.getSimpleName().getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
private static final int COST = 16384;
|
||||
|
||||
private static final int BLOCK_SIZE = 8;
|
||||
|
||||
private static final int PARALLELIZATION = 1;
|
||||
|
||||
private static final String SALT_ENCODED = "epIxT/h6HbbwHaehFnh/bw";
|
||||
|
||||
private static final String HASH = "7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0";
|
||||
|
||||
private static final String SERIALIZED = String.format("$s0$e0801$%s", SALT_ENCODED);
|
||||
|
||||
private static final String SERIALIZED_HASH = String.format("%s$%s", SERIALIZED, HASH);
|
||||
|
||||
private static final Base64.Decoder decoder = Base64.getDecoder();
|
||||
|
||||
ScryptDerivedKeyParameterSpecReader reader;
|
||||
|
||||
@BeforeEach
|
||||
void setReader() {
|
||||
reader = new ScryptDerivedKeyParameterSpecReader();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadException() {
|
||||
assertThrows(IllegalArgumentException.class, () -> reader.read(STRING_PARAMETERS));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRead() {
|
||||
final byte[] serializedParameters = SERIALIZED.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
final ScryptDerivedKeyParameterSpec parameterSpec = reader.read(serializedParameters);
|
||||
|
||||
assertParameterSpecEquals(parameterSpec);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testReadHash() {
|
||||
final byte[] serializedParameters = SERIALIZED_HASH.getBytes(StandardCharsets.US_ASCII);
|
||||
|
||||
final ScryptDerivedKeyParameterSpec parameterSpec = reader.read(serializedParameters);
|
||||
|
||||
assertParameterSpecEquals(parameterSpec);
|
||||
}
|
||||
|
||||
private void assertParameterSpecEquals(final ScryptDerivedKeyParameterSpec parameterSpec) {
|
||||
assertNotNull(parameterSpec);
|
||||
assertEquals(COST, parameterSpec.getCost());
|
||||
assertEquals(BLOCK_SIZE, parameterSpec.getBlockSize());
|
||||
assertEquals(PARALLELIZATION, parameterSpec.getParallelization());
|
||||
|
||||
final byte[] salt = decoder.decode(SALT_ENCODED);
|
||||
assertArrayEquals(salt, parameterSpec.getSalt());
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.apache.nifi.security.crypto.key.scrypt;
|
||||
|
||||
import org.apache.nifi.security.crypto.key.DerivedKey;
|
||||
import org.apache.nifi.security.crypto.key.DerivedKeySpec;
|
||||
import org.apache.nifi.security.crypto.key.StandardDerivedKeySpec;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Base64;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
|
||||
class ScryptDerivedKeyProviderTest {
|
||||
private static final String PASSWORD = "secret";
|
||||
|
||||
private static final int COST = 16384;
|
||||
|
||||
private static final int BLOCK_SIZE = 8;
|
||||
|
||||
private static final int PARALLELIZATION = 1;
|
||||
|
||||
private static final String SALT_ENCODED = "epIxT/h6HbbwHaehFnh/bw";
|
||||
|
||||
private static final String HASH = "7H0vsXlY8UxxyW/BWx/9GuY7jEvGjT71GFd6O4SZND0";
|
||||
|
||||
private static final String SERIALIZED = String.format("$s0$e0801$%s$%s", SALT_ENCODED, HASH);
|
||||
|
||||
private static final int DERIVED_KEY_LENGTH = 32;
|
||||
|
||||
private static final String ALGORITHM = "AES";
|
||||
|
||||
private static final Base64.Decoder decoder = Base64.getDecoder();
|
||||
|
||||
ScryptDerivedKeyProvider provider;
|
||||
|
||||
@BeforeEach
|
||||
void setProvider() {
|
||||
provider = new ScryptDerivedKeyProvider();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testGetDerivedKey() {
|
||||
final byte[] salt = decoder.decode(SALT_ENCODED);
|
||||
final ScryptDerivedKeyParameterSpec parameterSpec = new ScryptDerivedKeyParameterSpec(COST, BLOCK_SIZE, PARALLELIZATION, salt);
|
||||
|
||||
final DerivedKeySpec<ScryptDerivedKeyParameterSpec> derivedKeySpec = new StandardDerivedKeySpec<>(
|
||||
PASSWORD.toCharArray(),
|
||||
DERIVED_KEY_LENGTH,
|
||||
ALGORITHM,
|
||||
parameterSpec
|
||||
);
|
||||
|
||||
final DerivedKey derivedKey = provider.getDerivedKey(derivedKeySpec);
|
||||
|
||||
assertNotNull(derivedKey);
|
||||
assertEquals(ALGORITHM, derivedKey.getAlgorithm());
|
||||
assertEquals(SERIALIZED, derivedKey.getSerialized());
|
||||
|
||||
final byte[] hashBytes = decoder.decode(HASH);
|
||||
assertArrayEquals(hashBytes, derivedKey.getEncoded());
|
||||
}
|
||||
}
|
|
@ -30,11 +30,6 @@
|
|||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-utils</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.nifi</groupId>
|
||||
<artifactId>nifi-security-crypto-key</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.opentest4j</groupId>
|
||||
<artifactId>opentest4j</artifactId>
|
||||
|
|
Loading…
Reference in New Issue