This is an automated email from the ASF dual-hosted git repository.
pvillard31 pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new b8487608eba NIFI-16499 Fixed tests for Encrypted Private Keys on Java
25.0.5 (#11843)
b8487608eba is described below
commit b8487608eba1eaa35ead137a8dd88709bff2ae6b
Author: David Handermann <[email protected]>
AuthorDate: Fri Oct 23 14:23:41 2026 -0500
NIFI-16499 Fixed tests for Encrypted Private Keys on Java 25.0.5 (#11843)
- Added EncryptedPrivateKeyInfoEncoder with manual DER encoding to avoid
behavior changes from JDK-8343232
---
.../service/EncryptedPrivateKeyInfoEncoder.java | 86 ++++++++++++++++++++++
.../key/service/StandardPrivateKeyServiceTest.java | 28 +------
.../reader/StandardPrivateKeyReaderTest.java | 25 +------
3 files changed, 91 insertions(+), 48 deletions(-)
diff --git
a/nifi-extension-bundles/nifi-standard-services/nifi-key-service-bundle/nifi-key-service/src/test/java/org/apache/nifi/key/service/EncryptedPrivateKeyInfoEncoder.java
b/nifi-extension-bundles/nifi-standard-services/nifi-key-service-bundle/nifi-key-service/src/test/java/org/apache/nifi/key/service/EncryptedPrivateKeyInfoEncoder.java
new file mode 100644
index 00000000000..22caca0486e
--- /dev/null
+++
b/nifi-extension-bundles/nifi-standard-services/nifi-key-service-bundle/nifi-key-service/src/test/java/org/apache/nifi/key/service/EncryptedPrivateKeyInfoEncoder.java
@@ -0,0 +1,86 @@
+/*
+ * 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.key.service;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.AlgorithmParameters;
+import java.security.GeneralSecurityException;
+import java.util.HexFormat;
+import javax.crypto.Cipher;
+import javax.crypto.EncryptedPrivateKeyInfo;
+
+/**
+ * Encodes PKCS8 EncryptedPrivateKeyInfo for testing without using external
libraries
+ */
+public final class EncryptedPrivateKeyInfoEncoder {
+ private static final HexFormat HEX_FORMAT = HexFormat.of();
+
+ private static final byte[] PBES2_OBJECT_IDENTIFIER =
HEX_FORMAT.parseHex("06092a864886f70d01050d");
+ private static final String PBES2_CIPHER_PREFIX = "PBEWithHmac";
+
+ private static final int SEQUENCE_TAG = 0x30;
+ private static final int OCTET_STRING_TAG = 0x04;
+ private static final int LONG_FORM_LENGTH_FLAG = 0x80;
+
+ private EncryptedPrivateKeyInfoEncoder() {
+ }
+
+ /**
+ * Encode encrypted PKCS8 private key information using DER with
constructing PBES2 AlgorithmParameters to avoid Java behavior changes
+ *
+ * @param cipher Cipher initialized for encryption, including algorithm
parameters
+ * @param encrypted Encrypted private key
+ * @return DER encoded EncryptedPrivateKeyInfo
+ */
+ public static byte[] encode(final Cipher cipher, final byte[] encrypted)
throws GeneralSecurityException, IOException {
+ final AlgorithmParameters cipherParameters = cipher.getParameters();
+ if (cipherParameters.getAlgorithm().startsWith(PBES2_CIPHER_PREFIX)) {
+ final byte[] parameters = cipherParameters.getEncoded();
+ final byte[] algorithmIdentifier = getDerEncoded(SEQUENCE_TAG,
PBES2_OBJECT_IDENTIFIER, parameters);
+ final byte[] encryptedOctetString =
getDerEncoded(OCTET_STRING_TAG, encrypted);
+ return getDerEncoded(SEQUENCE_TAG, algorithmIdentifier,
encryptedOctetString);
+ }
+
+ return new EncryptedPrivateKeyInfo(cipherParameters,
encrypted).getEncoded();
+ }
+
+ private static byte[] getDerEncoded(final int tag, final byte[]...
contents) {
+ final ByteArrayOutputStream contentsStream = new
ByteArrayOutputStream();
+ for (final byte[] content : contents) {
+ contentsStream.writeBytes(content);
+ }
+
+ final ByteArrayOutputStream encodedStream = new
ByteArrayOutputStream();
+ encodedStream.write(tag);
+
+ final int length = contentsStream.size();
+ if (length < LONG_FORM_LENGTH_FLAG) {
+ encodedStream.write(length);
+ } else {
+ final byte[] signedLength =
BigInteger.valueOf(length).toByteArray();
+ final int lengthOffset = signedLength[0] == 0 ? 1 : 0;
+ final int lengthBytes = signedLength.length - lengthOffset;
+ encodedStream.write(LONG_FORM_LENGTH_FLAG | lengthBytes);
+ encodedStream.write(signedLength, lengthOffset, lengthBytes);
+ }
+
+ encodedStream.writeBytes(contentsStream.toByteArray());
+ return encodedStream.toByteArray();
+ }
+}
diff --git
a/nifi-extension-bundles/nifi-standard-services/nifi-key-service-bundle/nifi-key-service/src/test/java/org/apache/nifi/key/service/StandardPrivateKeyServiceTest.java
b/nifi-extension-bundles/nifi-standard-services/nifi-key-service-bundle/nifi-key-service/src/test/java/org/apache/nifi/key/service/StandardPrivateKeyServiceTest.java
index 9fcb5965fac..fafa001a61f 100644
---
a/nifi-extension-bundles/nifi-standard-services/nifi-key-service-bundle/nifi-key-service/src/test/java/org/apache/nifi/key/service/StandardPrivateKeyServiceTest.java
+++
b/nifi-extension-bundles/nifi-standard-services/nifi-key-service-bundle/nifi-key-service/src/test/java/org/apache/nifi/key/service/StandardPrivateKeyServiceTest.java
@@ -31,7 +31,6 @@ import org.junit.jupiter.params.provider.MethodSource;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
@@ -41,7 +40,6 @@ import java.util.Base64;
import java.util.Map;
import java.util.UUID;
import javax.crypto.Cipher;
-import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
@@ -63,10 +61,6 @@ class StandardPrivateKeyServiceTest {
private static final String PBE_SHA1_DESEDE = "PBEWithSHA1AndDESede";
- private static final String PBES2_ALGORITHM = "PBES2";
-
- private static final String PBES2_CIPHER_PREFIX = "PBEWithHmac";
-
private static final String PRIVATE_KEY_TYPE = "PRIVATE KEY";
private static final String ENCRYPTED_PRIVATE_KEY_TYPE = "ENCRYPTED
PRIVATE KEY";
@@ -178,26 +172,8 @@ class StandardPrivateKeyServiceTest {
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
final byte[] encrypted = cipher.doFinal(privateKey.getEncoded());
- final EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new
EncryptedPrivateKeyInfo(getEncryptionParameters(cipher), encrypted);
- return getPem(ENCRYPTED_PRIVATE_KEY_TYPE,
encryptedPrivateKeyInfo.getEncoded());
- }
-
- /**
- * Get encryption parameters with an algorithm name that
EncryptedPrivateKeyInfo can resolve to an Object Identifier,
- * which requires PBES2 instead of cipher names such as
PBEWithHmacSHA256AndAES_256
- */
- private AlgorithmParameters getEncryptionParameters(final Cipher cipher)
throws GeneralSecurityException, IOException {
- final AlgorithmParameters cipherParameters = cipher.getParameters();
-
- final AlgorithmParameters encryptionParameters;
- if (cipherParameters.getAlgorithm().startsWith(PBES2_CIPHER_PREFIX)) {
- encryptionParameters =
AlgorithmParameters.getInstance(PBES2_ALGORITHM);
- encryptionParameters.init(cipherParameters.getEncoded());
- } else {
- encryptionParameters = cipherParameters;
- }
-
- return encryptionParameters;
+ final byte[] encoded = EncryptedPrivateKeyInfoEncoder.encode(cipher,
encrypted);
+ return getPem(ENCRYPTED_PRIVATE_KEY_TYPE, encoded);
}
private String getPem(final String type, final byte[] encoded) {
diff --git
a/nifi-extension-bundles/nifi-standard-services/nifi-key-service-bundle/nifi-key-service/src/test/java/org/apache/nifi/key/service/reader/StandardPrivateKeyReaderTest.java
b/nifi-extension-bundles/nifi-standard-services/nifi-key-service-bundle/nifi-key-service/src/test/java/org/apache/nifi/key/service/reader/StandardPrivateKeyReaderTest.java
index ee3c6491f11..8fb3419e5e2 100644
---
a/nifi-extension-bundles/nifi-standard-services/nifi-key-service-bundle/nifi-key-service/src/test/java/org/apache/nifi/key/service/reader/StandardPrivateKeyReaderTest.java
+++
b/nifi-extension-bundles/nifi-standard-services/nifi-key-service-bundle/nifi-key-service/src/test/java/org/apache/nifi/key/service/reader/StandardPrivateKeyReaderTest.java
@@ -16,6 +16,7 @@
*/
package org.apache.nifi.key.service.reader;
+import org.apache.nifi.key.service.EncryptedPrivateKeyInfoEncoder;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
@@ -26,7 +27,6 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
-import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
@@ -37,7 +37,6 @@ import java.util.HexFormat;
import java.util.UUID;
import java.util.stream.Stream;
import javax.crypto.Cipher;
-import javax.crypto.EncryptedPrivateKeyInfo;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
@@ -77,10 +76,6 @@ class StandardPrivateKeyReaderTest {
private static final String PBE_SHA1_DESEDE = "PBEWithSHA1AndDESede";
- private static final String PBES2_ALGORITHM = "PBES2";
-
- private static final String PBES2_CIPHER_PREFIX = "PBEWithHmac";
-
private static final String PBKDF2_HMAC_SHA256 = "PBKDF2WithHmacSHA256";
private static final int PBKDF2_ITERATION_COUNT = 2048;
@@ -242,22 +237,8 @@ class StandardPrivateKeyReaderTest {
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
final byte[] encrypted = cipher.doFinal(privateKey.getEncoded());
- final EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new
EncryptedPrivateKeyInfo(getEncryptionParameters(cipher), encrypted);
- return getPem(ENCRYPTED_PRIVATE_KEY_TYPE,
encryptedPrivateKeyInfo.getEncoded());
- }
-
- private static AlgorithmParameters getEncryptionParameters(final Cipher
cipher) throws GeneralSecurityException, IOException {
- final AlgorithmParameters cipherParameters = cipher.getParameters();
-
- final AlgorithmParameters encryptionParameters;
- if (cipherParameters.getAlgorithm().startsWith(PBES2_CIPHER_PREFIX)) {
- encryptionParameters =
AlgorithmParameters.getInstance(PBES2_ALGORITHM);
- encryptionParameters.init(cipherParameters.getEncoded());
- } else {
- encryptionParameters = cipherParameters;
- }
-
- return encryptionParameters;
+ final byte[] encoded = EncryptedPrivateKeyInfoEncoder.encode(cipher,
encrypted);
+ return getPem(ENCRYPTED_PRIVATE_KEY_TYPE, encoded);
}
private static String getPbes2DesEde3Pem(final PrivateKey privateKey)
throws GeneralSecurityException {