diff --git a/src/main/java/de/mlessmann/certassist/openssl/OpenSSLCertificateCreator.java b/src/main/java/de/mlessmann/certassist/openssl/OpenSSLCertificateCreator.java
index b3d1007..18730c3 100644
--- a/src/main/java/de/mlessmann/certassist/openssl/OpenSSLCertificateCreator.java
+++ b/src/main/java/de/mlessmann/certassist/openssl/OpenSSLCertificateCreator.java
@@ -15,6 +15,7 @@ import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.Optional;
+import java.util.UUID;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
@@ -25,7 +26,6 @@ import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.NonNull;
-import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.zeroturnaround.exec.ProcessExecutor;
@@ -135,6 +135,7 @@ public class OpenSSLCertificateCreator {
"genrsa",
"-out",
keyFile.toString(),
+ "-aes256",
"-passout",
"env:KEY_PASS",
Integer.toString(request.getRequestedKeyLength())
@@ -282,20 +283,28 @@ public class OpenSSLCertificateCreator {
}
}
+ /**
+ * Checks whether the provided key file is encrypted using a passphrase
+ */
public boolean isKeyEncrypted(@NonNull Path keyFile) throws InterruptedException, CommandLineOperationException {
- // If any random passphrase works, the key is not encrypted.
- return !verifyKeyPassphrase(keyFile, null);
+ // If the key is not encrypted, any passphrase will work -> so generate a random one to check.
+ String passphrase = UUID.randomUUID().toString();
+ boolean firstPass = verifyKeyPassphrase(keyFile, passphrase);
+ if (firstPass) {
+ // Try with another random passphrase in case we randomly got lucky guessing the passphrase the first time.
+ passphrase = UUID.randomUUID().toString();
+ return !verifyKeyPassphrase(keyFile, passphrase);
+ }
+ return true;
}
/**
* Verifies a passphrase against a provided key.
- * @implNote Due to the implementation of the OpenSSL cli, any password will be valid for unencrypted keys. (Check with {@link #isKeyEncrypted(Path) or by passing {@code null} as the passphrase.)
+ * @implNote Due to the implementation of the OpenSSL cli, any password will be valid for unencrypted keys. (Check with {@link #isKeyEncrypted(Path).)
*/
- public boolean verifyKeyPassphrase(@NonNull Path keyFile, @Nullable String passphrase)
+ public boolean verifyKeyPassphrase(@NonNull Path keyFile, @NonNull String passphrase)
throws CommandLineOperationException, InterruptedException {
- // Run OpenSSL command: openssl rsa -check -in -passin pass: -noout and check exit code
try {
- String keyPass = passphrase != null ? passphrase : passwordProvider.generateNewPassword();
StartedProcess verifyCommand = new ProcessExecutor()
.command(
resolveOpenSSL(),
@@ -304,16 +313,14 @@ public class OpenSSLCertificateCreator {
"-in",
keyFile.toString(),
"-passin",
- "pass:" + keyPass,
+ "pass:" + passphrase,
"-noout"
)
.redirectOutput(Slf4jStream.ofCaller().asError())
.redirectError(Slf4jStream.ofCaller().asError())
.start();
var verifyResult = verifyCommand.getFuture().get();
- boolean commandSuccess = verifyResult.getExitValue() == 0;
- log.trace("Key check {} with passphrase provided={}", commandSuccess, passphrase != null);
- return commandSuccess;
+ return verifyResult.getExitValue() == 0;
} catch (IOException | InterruptedException | ExecutionException e) {
throw new CommandLineOperationException("Failed to verify key encryption", e);
}