You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@santuario.apache.org by "jrihtarsic (via GitHub)" <gi...@apache.org> on 2024/01/19 09:00:36 UTC
[PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
jrihtarsic opened a new pull request, #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271
Purpose of the PR is the key derivation function implementation (HKDF) for the Key Agreement Algorithm
The code is contributed on behalf of the European Commission’s edelivery project to support [eDelivery AS4 2.0 profile](https://ec.europa.eu/digital-building-blocks/wikis/pages/viewpage.action?pageId=467117621).
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1592394464
##########
src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java:
##########
@@ -274,13 +274,18 @@ public static KeyAgreementParameters constructAgreementParameters(String agreeme
* @param keyDerivationMethod element with the key derivation method data
* @param keyBitLength expected derived key length in bits
* @return KeyDerivationParameters data
- * @throws XMLSecurityException if the invalid key derivation parameters are provide
- * @throws XMLEncryptionException if the invalid key derivation is not supported
+ * @throws XMLEncryptionException throwen in case if KDFParams cannot be created or the
Review Comment:
typo: "throwen", but I would just remove "thrown in case" as that is implied. Also, a nit but you don't need to end with a period.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1581872323
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,177 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as defined in RFC 5869.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm {
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+ private final String hmacHashAlgorithmURI;
+ private final Mac hmac;
+
+ /**
+ * Constructor HKDF initializes the Mac object with the given algorithmURI and salt.
+ *
+ * @param hmacHashAlgorithmURI the Hash algorithm
+ * @param salt the salt value to initialize the MAC algorithm.
+ * @throws XMLSecurityException if the key derivation initialization fails for any reason
+ */
+ public HKDF(String hmacHashAlgorithmURI, byte[] salt) throws XMLSecurityException {
Review Comment:
Done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1581874128
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/KeyDerivationMethodImpl.java:
##########
@@ -71,29 +73,43 @@ public String getAlgorithm() {
return getLocalAttribute(EncryptionConstants._ATT_ALGORITHM);
}
- public ConcatKDFParamsImpl getConcatKDFParams() throws XMLSecurityException {
- if (concatKDFParams != null) {
- return concatKDFParams;
- }
+ @Override
+ public KDFParams getKDFParams() throws XMLSecurityException {
- Element concatKDFParamsElement =
- XMLUtils.selectXenc11Node(getElement().getFirstChild(), EncryptionConstants._TAG_CONCATKDFPARAMS, 0);
+ if (kdfParams != null) {
+ LOG.log(DEBUG, "Returning cached KDFParams");
+ return kdfParams;
+ }
- if (concatKDFParamsElement == null) {
- return null;
+ String kdfAlgorithm = getAlgorithm();
+ if (EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(kdfAlgorithm)) {
+ Element concatKDFParamsElement =
+ XMLUtils.selectXenc11Node(getElement().getFirstChild(),
+ EncryptionConstants._TAG_CONCATKDFPARAMS, 0);
+ kdfParams = new ConcatKDFParamsImpl(concatKDFParamsElement, getBaseURI());
+ } else if (EncryptionConstants.ALGO_ID_KEYDERIVATION_HKDF.equals(kdfAlgorithm)) {
+ Element hkdfParamsElement =
+ XMLUtils.selectNode(getElement().getFirstChild(),
+ Constants.XML_DSIG_NS_MORE_21_04,
+ EncryptionConstants._TAG_HKDFPARAMS, 0);
+ kdfParams = new HKDFParamsImpl(hkdfParamsElement, Constants.XML_DSIG_NS_MORE_07_05);
}
- concatKDFParams = new ConcatKDFParamsImpl(concatKDFParamsElement, getBaseURI());
- return concatKDFParams;
+ return kdfParams;
}
- public void setConcatKDFParams(ConcatKDFParamsImpl concatKDFParams) {
- this.concatKDFParams = concatKDFParams;
- appendSelf(concatKDFParams);
- addReturnToSelf();
+ public void setKDFParams(KDFParams kdfParams) {
Review Comment:
Added the validation and if KDF Params are not supported and error is thrown.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-1935493181
Hi @coheigea I want to inform you that the update for HKDF xsd scheme for RFC9231
https://datatracker.ietf.org/doc/draft-eastlake-rfc9231bis-xmlsec-uris/
was accepted and the PR can be reviewed now.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-2014385650
@seanjmullan Thank you for checking it. And no worries about time. I'd rather see my code thoroughly vetted by a security expert than to skip/miss some security issues or bugs. So take as much time as you need.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1581872000
##########
src/main/java/org/apache/xml/security/encryption/params/HKDFParams.java:
##########
@@ -0,0 +1,76 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.params;
+
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.utils.EncryptionConstants;
+
+/**
+ * Class HMacKeyDerivationParameter (HKDF parameter) is used to specify
Review Comment:
done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "coheigea (via GitHub)" <gi...@apache.org>.
coheigea commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-2100369954
@seanjmullan Is it ready to be merged from your PoV?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-1979485675
> @seanjmullan Can you have a look as well please?
I can try to look at this over the next couple of weeks. I was off work for a while so I am still catching up with things.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-2011501924
I reverted the "cleaning of the code" (empty lines) from commit [PR updates (docs and clean empty lines)](https://github.com/apache/santuario-xml-security-java/pull/271/commits/491a7d36b69837b8db2b8192be5af117984ebb68)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1534523455
##########
src/main/java/org/apache/xml/security/resource/xmlsecurity_en.properties:
##########
@@ -111,7 +111,9 @@ KeyStore.registerStore.register = Registration error for type {0}
KeyValue.IllegalArgument = Cannot create a {0} from {1}
KeyDerivation.TooShortParameter = Key derivation parameter {0} is too short
KeyDerivation.InvalidParameter = Key derivation parameter {0} is illegal
+KeyDerivation.InvalidParametersType = Algorithm {0} requires key derivation parameters of type {1} to be provided.
Review Comment:
Nit: most of the other error messages don't end in a period, so suggest removing it.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "github-advanced-security[bot] (via GitHub)" <gi...@apache.org>.
github-advanced-security[bot] commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1593884444
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,182 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.encryption.params.HKDFParams;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.utils.I18n;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
+ * as defined in <a href="https://datatracker.ietf.org/doc/html/rfc5869">RFC 5869</a>.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm<HKDFParams> {
+
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+
+ /**
+ * Derive a key using the HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
+ * as defined in <a href="https://datatracker.ietf.org/doc/html/rfc5869">RFC 5869</a>.
+ *
+ * @param secret The "shared" secret to use for key derivation
+ * @param params The key derivation parameters (salt, info, key length, ...)
+ * @return The derived key of the specified length in bytes defined in the params
+ * @throws IllegalArgumentException if the parameters are missing
+ * @throws XMLSecurityException if the hmac hash algorithm is not supported
+ */
+ @Override
+ public byte[] deriveKey(byte[] secret, HKDFParams params) throws XMLSecurityException {
+ // check if the parameters are set
+ if (params == null) {
+ throw new IllegalArgumentException(I18n.translate("KeyDerivation.MissingParameters"));
+ }
+
+ String jceAlgorithmName;
+ try {
+ jceAlgorithmName = XMLCipherUtil.getJCEMacHashForUri(params.getHmacHashAlgorithm());
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(e, "KeyDerivation.NotSupportedParameter", new Object[]{params.getHmacHashAlgorithm()});
+ }
+
+ byte[] prk = extractKey(jceAlgorithmName, params.getSalt(), secret);
+ return expandKey(jceAlgorithmName, prk, params.getInfo(), params.getKeyLength());
+ }
+
+ /**
+ * The method "extracts" the pseudo-random key (PRK) based on HMAC-Hash function
+ * (optional) salt value (a non-secret random value) and the shared secret/input
+ * keying material (IKM).
+ * Calculation of the extracted key:
+ * <pre>PRK = HMAC-Hash(salt, IKM)</pre>
+ *
+ * @param jceAlgorithmName the java JCE HMAC algorithm name to use for key derivation
+ * (e.g. HmacSHA256, HmacSHA384, HmacSHA512)
+ * @param salt the optional salt value (a non-secret random value);
+ * @param secret the shared secret/input keying material (IKM) to use for
+ * key derivation
+ * @return the pseudo-random key bytes
+ * @throws XMLSecurityException if the jceAlgorithmName is not supported
+ */
+ public byte[] extractKey(String jceAlgorithmName, byte[] salt, byte[] secret) throws XMLSecurityException {
+ Mac hMac = initHMac(jceAlgorithmName, salt, true);
+ hMac.reset();
+ return hMac.doFinal(secret);
+ }
+
+ /**
+ * The method inits Hash-MAC with given PRK (as salt) and output OKM is calculated as follows:
+ * <pre>
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ *
+ * @param jceHmacAlgorithmName the java JCE HMAC algorithm name to use to expand
+ * the key (e.g. HmacSHA256, HmacSHA384, HmacSHA512)
+ * @param prk pseudo-random key derived from the shared secret
+ * @param info used to derive the key
+ * @param keyLength key length in bytes of the derived key
+ * @return the output keying material (OKM) size of keyLength octets
+ * @throws XMLSecurityException if the jceHmacAlgorithmName is not supported
+ */
+ public byte[] expandKey(String jceHmacAlgorithmName, byte[] prk, byte[] info, long keyLength) throws XMLSecurityException {
+ // prepare for expanding the key
+ Mac hMac = initHMac(jceHmacAlgorithmName, prk, false);
+ int iMacLength = hMac.getMacLength();
+
+ int toGenerateSize = (int) keyLength;
+ ByteBuffer result = ByteBuffer.allocate(toGenerateSize);
+ byte[] prevResult = new byte[0];
+ short counter = 1;
+ while (toGenerateSize > 0) {
+ hMac.reset();
+ hMac.update(prevResult);
+ if (info != null && info.length > 0) {
+ hMac.update(info);
+ }
+ hMac.update((byte) counter);
+ prevResult = hMac.doFinal();
+ result.put(prevResult, 0, Math.min(toGenerateSize, iMacLength));
+ // get ready for next iteration
+ toGenerateSize -= iMacLength;
+ counter++;
+ }
+ return result.array();
+ }
+
+ /**
+ * Method initializes a Message Authentication Code (MAC) object using the
+ * init secret/salt or an empty byte array if initSecret parameter is null or empty.
+ *
+ * @param jceAlgorithmName the java JCE HMAC algorithm name to use to init Mac
+ * @param initSecret the secret/salt to initialize the hmac
+ * @param initPRK if true, the salt is initialized with a string of zero octets
+ * as long as the hash function output see [RFC5869] Section 2.2
+ * @return Initialized Mac object
+ * @throws XMLSecurityException if the hmac algorithm is not supported or if it
+ * fails to initialize
+ */
+ private Mac initHMac(String jceAlgorithmName, byte[] initSecret, boolean initPRK) throws XMLSecurityException {
+ Mac mac;
+ try {
+ LOG.log(DEBUG, "Init Mac with hash algorithm: [{}]", jceAlgorithmName);
+ mac = Mac.getInstance(jceAlgorithmName);
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(e, "KeyDerivation.NotSupportedParameter", new Object[]{jceAlgorithmName});
+ }
+
+ if (initPRK && (initSecret == null || initSecret.length == 0)) {
+ // If "initSecret"/salt is not provided, a string of zero octets as long as the hash function output is used
+ LOG.log(DEBUG, "Init Mac with hmac algorithm [{}] and empty salt!", jceAlgorithmName);
+ initSecret = new byte[mac.getMacLength()];
+ }
+ SecretKeySpec secretKey = new SecretKeySpec(initSecret, jceAlgorithmName);
Review Comment:
## Use of a potentially broken or risky cryptographic algorithm
Cryptographic algorithm [HmacSHA224](1) may not be secure, consider using a different algorithm.
Cryptographic algorithm [HmacSHA384](2) may not be secure, consider using a different algorithm.
Cryptographic algorithm [HMACRIPEMD160](3) may not be secure, consider using a different algorithm.
[Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1150)
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,182 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.encryption.params.HKDFParams;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.utils.I18n;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
+ * as defined in <a href="https://datatracker.ietf.org/doc/html/rfc5869">RFC 5869</a>.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm<HKDFParams> {
+
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+
+ /**
+ * Derive a key using the HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
+ * as defined in <a href="https://datatracker.ietf.org/doc/html/rfc5869">RFC 5869</a>.
+ *
+ * @param secret The "shared" secret to use for key derivation
+ * @param params The key derivation parameters (salt, info, key length, ...)
+ * @return The derived key of the specified length in bytes defined in the params
+ * @throws IllegalArgumentException if the parameters are missing
+ * @throws XMLSecurityException if the hmac hash algorithm is not supported
+ */
+ @Override
+ public byte[] deriveKey(byte[] secret, HKDFParams params) throws XMLSecurityException {
+ // check if the parameters are set
+ if (params == null) {
+ throw new IllegalArgumentException(I18n.translate("KeyDerivation.MissingParameters"));
+ }
+
+ String jceAlgorithmName;
+ try {
+ jceAlgorithmName = XMLCipherUtil.getJCEMacHashForUri(params.getHmacHashAlgorithm());
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(e, "KeyDerivation.NotSupportedParameter", new Object[]{params.getHmacHashAlgorithm()});
+ }
+
+ byte[] prk = extractKey(jceAlgorithmName, params.getSalt(), secret);
+ return expandKey(jceAlgorithmName, prk, params.getInfo(), params.getKeyLength());
+ }
+
+ /**
+ * The method "extracts" the pseudo-random key (PRK) based on HMAC-Hash function
+ * (optional) salt value (a non-secret random value) and the shared secret/input
+ * keying material (IKM).
+ * Calculation of the extracted key:
+ * <pre>PRK = HMAC-Hash(salt, IKM)</pre>
+ *
+ * @param jceAlgorithmName the java JCE HMAC algorithm name to use for key derivation
+ * (e.g. HmacSHA256, HmacSHA384, HmacSHA512)
+ * @param salt the optional salt value (a non-secret random value);
+ * @param secret the shared secret/input keying material (IKM) to use for
+ * key derivation
+ * @return the pseudo-random key bytes
+ * @throws XMLSecurityException if the jceAlgorithmName is not supported
+ */
+ public byte[] extractKey(String jceAlgorithmName, byte[] salt, byte[] secret) throws XMLSecurityException {
+ Mac hMac = initHMac(jceAlgorithmName, salt, true);
+ hMac.reset();
+ return hMac.doFinal(secret);
+ }
+
+ /**
+ * The method inits Hash-MAC with given PRK (as salt) and output OKM is calculated as follows:
+ * <pre>
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ *
+ * @param jceHmacAlgorithmName the java JCE HMAC algorithm name to use to expand
+ * the key (e.g. HmacSHA256, HmacSHA384, HmacSHA512)
+ * @param prk pseudo-random key derived from the shared secret
+ * @param info used to derive the key
+ * @param keyLength key length in bytes of the derived key
+ * @return the output keying material (OKM) size of keyLength octets
+ * @throws XMLSecurityException if the jceHmacAlgorithmName is not supported
+ */
+ public byte[] expandKey(String jceHmacAlgorithmName, byte[] prk, byte[] info, long keyLength) throws XMLSecurityException {
+ // prepare for expanding the key
+ Mac hMac = initHMac(jceHmacAlgorithmName, prk, false);
+ int iMacLength = hMac.getMacLength();
+
+ int toGenerateSize = (int) keyLength;
+ ByteBuffer result = ByteBuffer.allocate(toGenerateSize);
+ byte[] prevResult = new byte[0];
+ short counter = 1;
+ while (toGenerateSize > 0) {
+ hMac.reset();
+ hMac.update(prevResult);
+ if (info != null && info.length > 0) {
+ hMac.update(info);
+ }
+ hMac.update((byte) counter);
+ prevResult = hMac.doFinal();
+ result.put(prevResult, 0, Math.min(toGenerateSize, iMacLength));
+ // get ready for next iteration
+ toGenerateSize -= iMacLength;
+ counter++;
+ }
+ return result.array();
+ }
+
+ /**
+ * Method initializes a Message Authentication Code (MAC) object using the
+ * init secret/salt or an empty byte array if initSecret parameter is null or empty.
+ *
+ * @param jceAlgorithmName the java JCE HMAC algorithm name to use to init Mac
+ * @param initSecret the secret/salt to initialize the hmac
+ * @param initPRK if true, the salt is initialized with a string of zero octets
+ * as long as the hash function output see [RFC5869] Section 2.2
+ * @return Initialized Mac object
+ * @throws XMLSecurityException if the hmac algorithm is not supported or if it
+ * fails to initialize
+ */
+ private Mac initHMac(String jceAlgorithmName, byte[] initSecret, boolean initPRK) throws XMLSecurityException {
+ Mac mac;
+ try {
+ LOG.log(DEBUG, "Init Mac with hash algorithm: [{}]", jceAlgorithmName);
+ mac = Mac.getInstance(jceAlgorithmName);
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(e, "KeyDerivation.NotSupportedParameter", new Object[]{jceAlgorithmName});
+ }
+
+ if (initPRK && (initSecret == null || initSecret.length == 0)) {
+ // If "initSecret"/salt is not provided, a string of zero octets as long as the hash function output is used
+ LOG.log(DEBUG, "Init Mac with hmac algorithm [{}] and empty salt!", jceAlgorithmName);
+ initSecret = new byte[mac.getMacLength()];
+ }
+ SecretKeySpec secretKey = new SecretKeySpec(initSecret, jceAlgorithmName);
Review Comment:
## Use of a broken or risky cryptographic algorithm
Cryptographic algorithm [HmacSHA1](1) is weak and should not be used.
[Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1147)
##########
src/main/java/org/apache/xml/security/utils/KeyUtils.java:
##########
@@ -247,34 +245,76 @@
}
}
-
/**
- * Derive a key encryption key from a shared secret and keyDerivationParameter. Currently only the ConcatKDF is supported.
+ * Derive a key encryption key from a shared secret and keyDerivationParameter.
+ * Currently only the ConcatKDF and HMAC-base Extract-and-Expand Key Derivation
+ * Function (HKDF) are supported.
+ *
* @param sharedSecret the shared secret
* @param keyDerivationParameter the key derivation parameters
* @return the derived key encryption key
+ * @throws IllegalArgumentException if the keyDerivationParameter is null
* @throws XMLSecurityException if the key derivation algorithm is not supported
*/
public static byte[] deriveKeyEncryptionKey(byte[] sharedSecret, KeyDerivationParameters keyDerivationParameter)
throws XMLSecurityException {
- int iKeySize = keyDerivationParameter.getKeyBitLength()/8;
+
+ if (keyDerivationParameter == null) {
+ throw new IllegalArgumentException(I18n.translate("KeyDerivation.MissingParameters"));
+ }
+
String keyDerivationAlgorithm = keyDerivationParameter.getAlgorithm();
- if (!EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(keyDerivationAlgorithm)) {
- throw new XMLEncryptionException( "unknownAlgorithm",
- keyDerivationAlgorithm);
+ if (keyDerivationParameter instanceof HKDFParams) {
+ return deriveKeyEncryptionKey(sharedSecret, (HKDFParams) keyDerivationParameter);
+ } else if (keyDerivationParameter instanceof ConcatKDFParams) {
+ return deriveKeyEncryptionKey(sharedSecret, (ConcatKDFParams) keyDerivationParameter);
+ }
+
+ throw new XMLEncryptionException("KeyDerivation.UnsupportedAlgorithm", keyDerivationAlgorithm,
+ keyDerivationParameter.getClass().getName());
+ }
+
+ /**
+ * Derive a key using the HMAC-based Extract-and-Expand Key Derivation
+ * Function (HKDF) with implementation instance {@link HKDFParams}.
+ *
+ * @param sharedSecret the shared secret
+ * @param hkdfParameter the HKDF parameters
+ * @return the derived key encryption key.
+ * @throws XMLSecurityException if the key derivation parameters are invalid or
+ * the hmac algorithm is not supported.
+ */
+ public static byte[] deriveKeyEncryptionKey(byte[] sharedSecret, HKDFParams hkdfParameter)
+ throws XMLSecurityException {
+
+ if (!EncryptionConstants.ALGO_ID_KEYDERIVATION_HKDF.equals(hkdfParameter.getAlgorithm())){
+ throw new XMLEncryptionException("KeyDerivation.UnsupportedAlgorithm", hkdfParameter.getAlgorithm(),
+ HKDFParams.class.getName());
}
- ConcatKDFParams ckdfParameter = (ConcatKDFParams) keyDerivationParameter;
- // get parameters
- String digestAlgorithm = ckdfParameter.getDigestAlgorithm();
+ HKDF kdf = new HKDF();
+ return kdf.deriveKey(sharedSecret, hkdfParameter);
+ }
- String algorithmID = ckdfParameter.getAlgorithmID();
- String partyUInfo = ckdfParameter.getPartyUInfo();
- String partyVInfo = ckdfParameter.getPartyVInfo();
- String suppPubInfo = ckdfParameter.getSuppPubInfo();
- String suppPrivInfo = ckdfParameter.getSuppPrivInfo();
+ /**
+ * Derive a key using the Concatenation Key Derivation Function (ConcatKDF)
+ * with implementation instance {@link ConcatKDFParams}.
+ *
+ * @param sharedSecret the shared secret/ input keying material
+ * @param ckdfParameter the ConcatKDF parameters
+ * @return the derived key
+ * @throws XMLSecurityException if the key derivation parameters are invalid or
+ * the hash algorithm is not supported.
+ */
+ public static byte[] deriveKeyEncryptionKey(byte[] sharedSecret, ConcatKDFParams ckdfParameter)
Review Comment:
## Confusing overloading of methods
Method KeyUtils.deriveKeyEncryptionKey(..) could be confused with overloaded method [deriveKeyEncryptionKey](1), since dispatch depends on static types.
[Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1148)
##########
src/main/java/org/apache/xml/security/utils/KeyUtils.java:
##########
@@ -247,34 +245,76 @@
}
}
-
/**
- * Derive a key encryption key from a shared secret and keyDerivationParameter. Currently only the ConcatKDF is supported.
+ * Derive a key encryption key from a shared secret and keyDerivationParameter.
+ * Currently only the ConcatKDF and HMAC-base Extract-and-Expand Key Derivation
+ * Function (HKDF) are supported.
+ *
* @param sharedSecret the shared secret
* @param keyDerivationParameter the key derivation parameters
* @return the derived key encryption key
+ * @throws IllegalArgumentException if the keyDerivationParameter is null
* @throws XMLSecurityException if the key derivation algorithm is not supported
*/
public static byte[] deriveKeyEncryptionKey(byte[] sharedSecret, KeyDerivationParameters keyDerivationParameter)
throws XMLSecurityException {
- int iKeySize = keyDerivationParameter.getKeyBitLength()/8;
+
+ if (keyDerivationParameter == null) {
+ throw new IllegalArgumentException(I18n.translate("KeyDerivation.MissingParameters"));
+ }
+
String keyDerivationAlgorithm = keyDerivationParameter.getAlgorithm();
- if (!EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(keyDerivationAlgorithm)) {
- throw new XMLEncryptionException( "unknownAlgorithm",
- keyDerivationAlgorithm);
+ if (keyDerivationParameter instanceof HKDFParams) {
+ return deriveKeyEncryptionKey(sharedSecret, (HKDFParams) keyDerivationParameter);
+ } else if (keyDerivationParameter instanceof ConcatKDFParams) {
+ return deriveKeyEncryptionKey(sharedSecret, (ConcatKDFParams) keyDerivationParameter);
+ }
+
+ throw new XMLEncryptionException("KeyDerivation.UnsupportedAlgorithm", keyDerivationAlgorithm,
+ keyDerivationParameter.getClass().getName());
+ }
+
+ /**
+ * Derive a key using the HMAC-based Extract-and-Expand Key Derivation
+ * Function (HKDF) with implementation instance {@link HKDFParams}.
+ *
+ * @param sharedSecret the shared secret
+ * @param hkdfParameter the HKDF parameters
+ * @return the derived key encryption key.
+ * @throws XMLSecurityException if the key derivation parameters are invalid or
+ * the hmac algorithm is not supported.
+ */
+ public static byte[] deriveKeyEncryptionKey(byte[] sharedSecret, HKDFParams hkdfParameter)
Review Comment:
## Confusing overloading of methods
Method KeyUtils.deriveKeyEncryptionKey(..) could be confused with overloaded method [deriveKeyEncryptionKey](1), since dispatch depends on static types.
[Show more details](https://github.com/apache/santuario-xml-security-java/security/code-scanning/1149)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1575668885
##########
src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java:
##########
@@ -140,7 +140,7 @@ public static OAEPParameterSpec constructOAEPParameters(
public static MGF1ParameterSpec constructMGF1Parameter(String mgh1AlgorithmURI) {
LOG.log(Level.DEBUG, "Creating MGF1ParameterSpec for [{0}]", mgh1AlgorithmURI);
if (mgh1AlgorithmURI == null || mgh1AlgorithmURI.isEmpty()) {
- LOG.log(Level.WARNING,"MGF1 algorithm URI is null or empty. Using SHA-1 as default.");
+ LOG.log(Level.WARNING, "MGF1 algorithm URI is null or empty. Using SHA-1 as default.");
Review Comment:
Totally agree with the comment. But this wold change the existing behavior and mya break some "useges" which is following the
https://www.w3.org/TR/xmlenc-core1/#sec-RSA-OAEP
`The message digest function SHOULD be specified using the Algorithm attribute of the ds:DigestMethod child element of the xenc:EncryptionMethod element. If it is not specified, the default value of SHA1 is to be used. `
@coheigea if you agree I will change this to SHA-256, and I suggest that this is duly noted in the release notes.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1576280611
##########
src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java:
##########
@@ -140,7 +140,7 @@ public static OAEPParameterSpec constructOAEPParameters(
public static MGF1ParameterSpec constructMGF1Parameter(String mgh1AlgorithmURI) {
LOG.log(Level.DEBUG, "Creating MGF1ParameterSpec for [{0}]", mgh1AlgorithmURI);
if (mgh1AlgorithmURI == null || mgh1AlgorithmURI.isEmpty()) {
- LOG.log(Level.WARNING,"MGF1 algorithm URI is null or empty. Using SHA-1 as default.");
+ LOG.log(Level.WARNING, "MGF1 algorithm URI is null or empty. Using SHA-1 as default.");
Review Comment:
Created a ticket [SANTUARIO-618](https://issues.apache.org/jira/browse/SANTUARIO-618)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1489431855
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDFParamsImpl.java:
##########
@@ -0,0 +1,198 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.ElementProxy;
+import org.apache.xml.security.utils.EncryptionConstants;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Class HKDFParamsImpl is an DOM representation of the HKDF Parameters.
+ */
+public class HKDFParamsImpl extends ElementProxy implements KDFParams {
+
+
+ /**
+ * Constructor creates a new HKDFParamsImpl instance.
+ *
+ * @param doc the Document in which to create the DOM tree
+ */
+ public HKDFParamsImpl(Document doc) {
+
Review Comment:
Done. I also remove other "double blank lines" in the code.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-1900022882
@coheigea please note that we did not yet receive final feedback fro IETF regarding the
HKDF scheme. For now we are using the one defined bellow
[src/main/resources/bindings/schemas/dsig-more_2021_04.xsd](https://github.com/apache/santuario-xml-security-java/pull/271/files#diff-da724a891e2b2b97e9dde2b7b90890fa51a55a6a6ce3b6bef24634abc3ec4baf)
I will let you know when this PR will be finalized for the review.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1593378838
##########
src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java:
##########
@@ -274,13 +274,18 @@ public static KeyAgreementParameters constructAgreementParameters(String agreeme
* @param keyDerivationMethod element with the key derivation method data
* @param keyBitLength expected derived key length in bits
* @return KeyDerivationParameters data
- * @throws XMLSecurityException if the invalid key derivation parameters are provide
- * @throws XMLEncryptionException if the invalid key derivation is not supported
+ * @throws XMLEncryptionException throwen in case if KDFParams cannot be created or the
Review Comment:
Thanks for the warning about the typo, I fixed the description now.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "coheigea (via GitHub)" <gi...@apache.org>.
coheigea commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-2011343108
@jrihtarsic Can you remove the whitespace changes in this PR? It makes it difficult to get to the actual changes
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "coheigea (via GitHub)" <gi...@apache.org>.
coheigea commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-1947974167
@jrihtarsic I'm going to call a vote on 4.0.2/3.0.4 to get the Key Agreement feature released and unblock the next CXF release. The HKDF will have to wait until the next release.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1575198060
##########
src/main/java/org/apache/xml/security/encryption/KeyDerivationMethod.java:
##########
@@ -38,9 +43,21 @@
public interface KeyDerivationMethod {
/**
- * Returns the algorithm URI of this <code>KeyDerivationMethod</code>.
+ * Returns the algorithm URI of this <code>KeyDerivationMethod</code>
*
* @return the algorithm URI of this <code>KeyDerivationMethod</code>
*/
String getAlgorithm();
+
+ /**
+ * Returns the KDF parameters used by the key derivation algorithm.
+ * Currently supported types are:
+ * {@link org.apache.xml.security.encryption.params.ConcatKDFParams} and
+ * {@link org.apache.xml.security.encryption.params.HKDFParams}
Review Comment:
There should be a period at the end of the sentence here.
##########
src/main/java/org/apache/xml/security/encryption/KeyDerivationMethod.java:
##########
@@ -38,9 +43,21 @@
public interface KeyDerivationMethod {
/**
- * Returns the algorithm URI of this <code>KeyDerivationMethod</code>.
+ * Returns the algorithm URI of this <code>KeyDerivationMethod</code>
Review Comment:
There should be a period at the end of the sentence here.
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/KeyDerivationMethodImpl.java:
##########
@@ -71,29 +73,43 @@ public String getAlgorithm() {
return getLocalAttribute(EncryptionConstants._ATT_ALGORITHM);
}
- public ConcatKDFParamsImpl getConcatKDFParams() throws XMLSecurityException {
- if (concatKDFParams != null) {
- return concatKDFParams;
- }
+ @Override
+ public KDFParams getKDFParams() throws XMLSecurityException {
- Element concatKDFParamsElement =
- XMLUtils.selectXenc11Node(getElement().getFirstChild(), EncryptionConstants._TAG_CONCATKDFPARAMS, 0);
+ if (kdfParams != null) {
+ LOG.log(DEBUG, "Returning cached KDFParams");
+ return kdfParams;
+ }
- if (concatKDFParamsElement == null) {
- return null;
+ String kdfAlgorithm = getAlgorithm();
+ if (EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(kdfAlgorithm)) {
+ Element concatKDFParamsElement =
+ XMLUtils.selectXenc11Node(getElement().getFirstChild(),
+ EncryptionConstants._TAG_CONCATKDFPARAMS, 0);
+ kdfParams = new ConcatKDFParamsImpl(concatKDFParamsElement, getBaseURI());
+ } else if (EncryptionConstants.ALGO_ID_KEYDERIVATION_HKDF.equals(kdfAlgorithm)) {
+ Element hkdfParamsElement =
+ XMLUtils.selectNode(getElement().getFirstChild(),
+ Constants.XML_DSIG_NS_MORE_21_04,
+ EncryptionConstants._TAG_HKDFPARAMS, 0);
+ kdfParams = new HKDFParamsImpl(hkdfParamsElement, Constants.XML_DSIG_NS_MORE_07_05);
}
- concatKDFParams = new ConcatKDFParamsImpl(concatKDFParamsElement, getBaseURI());
- return concatKDFParams;
+ return kdfParams;
}
- public void setConcatKDFParams(ConcatKDFParamsImpl concatKDFParams) {
- this.concatKDFParams = concatKDFParams;
- appendSelf(concatKDFParams);
- addReturnToSelf();
+ public void setKDFParams(KDFParams kdfParams) {
Review Comment:
Should you check if the KDFParams are of a supported type and throw an Exception if not?
##########
src/main/java/org/apache/xml/security/utils/KeyUtils.java:
##########
@@ -248,7 +246,6 @@ public static int getAESKeyBitSizeForWrapAlgorithm(String keyWrapAlg) throws XML
}
}
-
/**
* Derive a key encryption key from a shared secret and keyDerivationParameter. Currently only the ConcatKDF is supported.
Review Comment:
The second sentence should be updated now that HKDF is also supported.
##########
src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java:
##########
@@ -243,48 +270,55 @@ public static KeyAgreementParameters constructAgreementParameters(String agreeme
/**
* Construct a KeyDerivationParameter object from the given keyDerivationMethod and keyBitLength
*
- * @param keyDerivationMethod element to parse
- * @param keyBitLength expected derived key length
- * @return KeyDerivationParameter object
- * @throws XMLSecurityException if the keyDerivationMethod is not supported
+ * @param keyDerivationMethod element with the key derivation method data
+ * @param keyBitLength expected derived key length
+ * @return KeyDerivationParameters data
+ * @throws XMLSecurityException if the keyDerivationMethod is not supported or invalid parameters are provided
*/
public static KeyDerivationParameters constructKeyDerivationParameter(KeyDerivationMethod keyDerivationMethod, int keyBitLength) throws XMLSecurityException {
String keyDerivationAlgorithm = keyDerivationMethod.getAlgorithm();
- if (!EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(keyDerivationAlgorithm)) {
- throw new XMLEncryptionException("unknownAlgorithm", keyDerivationAlgorithm);
- }
- ConcatKDFParamsImpl concatKDFParams = ((KeyDerivationMethodImpl) keyDerivationMethod).getConcatKDFParams();
+ KDFParams kdfParams = keyDerivationMethod.getKDFParams();
+ if (EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(keyDerivationAlgorithm)) {
+ if (! (kdfParams instanceof ConcatKDFParamsImpl)) {
+ throw new XMLEncryptionException("KeyDerivation.InvalidParametersType", keyDerivationAlgorithm, ConcatKDFParamsImpl.class.getName());
+ }
- return constructConcatKeyDerivationParameter(keyBitLength, concatKDFParams.getDigestMethod(), concatKDFParams.getAlgorithmId(),
- concatKDFParams.getPartyUInfo(), concatKDFParams.getPartyVInfo(),
- concatKDFParams.getSuppPubInfo(),concatKDFParams.getSuppPrivInfo());
+ ConcatKDFParamsImpl concatKDFParams = (ConcatKDFParamsImpl) kdfParams;
- }
+ return constructConcatKeyDerivationParameter(keyBitLength, concatKDFParams.getDigestMethod(), concatKDFParams.getAlgorithmId(),
+ concatKDFParams.getPartyUInfo(), concatKDFParams.getPartyVInfo(),
+ concatKDFParams.getSuppPubInfo(), concatKDFParams.getSuppPrivInfo());
+ } else if (EncryptionConstants.ALGO_ID_KEYDERIVATION_HKDF.equals(keyDerivationAlgorithm)) {
+ if (! (kdfParams instanceof HKDFParamsImpl)) {
- /**
- * Construct a ConcatKeyDerivationParameter object from the key length and digest method.
- *
- * @param keyBitLength expected derived key length
- * @param digestMethod digest method
- * @return ConcatKeyDerivationParameter object
- */
- public static ConcatKDFParams constructConcatKeyDerivationParameter(int keyBitLength,
- String digestMethod){
- return constructConcatKeyDerivationParameter(keyBitLength, digestMethod, null, null, null, null, null);
+ throw new XMLEncryptionException("KeyDerivation.InvalidParametersType", keyDerivationAlgorithm, HKDFParamsImpl.class.getName());
+ }
+ HKDFParamsImpl hKDFParams = (HKDFParamsImpl) kdfParams;
+ return constructHKDFKeyDerivationParameter(keyBitLength,
+ hKDFParams.getPRFAlgorithm(),
+ hKDFParams.getSalt() != null ? Base64.getDecoder().decode(hKDFParams.getSalt()) : null,
+ hKDFParams.getInfo() != null ? Base64.getDecoder().decode(hKDFParams.getInfo()) : null);
+ }
+ throw new XMLEncryptionException("unknownAlgorithm", keyDerivationAlgorithm);
}
/**
- * Construct a ConcatKeyDerivationParameter object from the given parameters
+ * Construct a ConcatKeyDerivationParameter object from the given parameters as specified in the XML Encryption 1.1
+ * and NIST SP 800-56Ar2 specifications. (In a key establishment transaction, the participants,
+ * parties U and V, are considered to be the first and second parties)
*
* @param keyBitLength expected derived key length
- * @param digestMethod digest method
- * @param algorithmId algorithm id
- * @param partyUInfo partyUInfo
- * @param partyVInfo partyVInfo
- * @param suppPubInfo suppPubInfo
- * @param suppPrivInfo suppPrivInfo
- * @return ConcatKeyDerivationParameter object
+ * @param digestMethod digest method element identifies the digest algorithm used by the KDF
+ * @param algorithmId algorithm id indicates how the derived keying material will be parsed and for which
+ * algorithm(s) the derived secret keying material will be used.
+ * @param partyUInfo partyUInfo containing public information about party
+ * @param partyVInfo partyVInfo containing public information about party
+ * @param suppPubInfo suppPubInfo An optional subfield, which could be null that contains additional, mutually
+ * known public information
+ * @param suppPrivInfo suppPrivInfo An optional subfield, which could be null, that contains additional, mutually
+ * known private information
+ * @return ConcatKeyDerivationParameter parameters used as input to the Concatenation Key Derivation Function
Review Comment:
s/ConcatKeyDerivationParameter/ConcatKDFParams/
##########
src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java:
##########
@@ -140,7 +140,7 @@ public static OAEPParameterSpec constructOAEPParameters(
public static MGF1ParameterSpec constructMGF1Parameter(String mgh1AlgorithmURI) {
LOG.log(Level.DEBUG, "Creating MGF1ParameterSpec for [{0}]", mgh1AlgorithmURI);
if (mgh1AlgorithmURI == null || mgh1AlgorithmURI.isEmpty()) {
- LOG.log(Level.WARNING,"MGF1 algorithm URI is null or empty. Using SHA-1 as default.");
+ LOG.log(Level.WARNING, "MGF1 algorithm URI is null or empty. Using SHA-1 as default.");
Review Comment:
We should strongly consider updating the default to at least SHA-256. Please file a separate issue for this.
##########
src/main/java/org/apache/xml/security/encryption/KeyDerivationMethod.java:
##########
@@ -19,10 +19,15 @@
package org.apache.xml.security.encryption;
+import org.apache.xml.security.encryption.keys.content.derivedKey.KDFParams;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+
/**
- * The key derivation is to generate new cryptographic key material from existing key material such as the shared
- * secret and any other (private or public) information. The purpose of the key derivation is an extension of a given
- * but limited set of original key materials and to limit the use (exposure) of such key material.
+ * The key derivation is to generate new cryptographic key material from existing
+ * key material such as the shared secret and any other (private or public)
+ * information. The purpose of the key derivation is an extension of a given
+ * but limited set of original key materials and to limit the use (exposure)
+ * of such key material.
Review Comment:
Suggest some rewording to improve readability:
"The purpose of key derivation is to generate new cryptographic key material from existing key material such as the shared secret and any other (private or public) information. This class represents the KeyDerivationMethod element."
I didn't understand the second sentence.
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/KDFParams.java:
##########
@@ -0,0 +1,26 @@
+/**
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+/**
+ * Marker interface for all KDFParams implementations
Review Comment:
There should be a period at the end of the sentence here.
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/KeyDerivationMethodImpl.java:
##########
@@ -71,29 +73,43 @@ public String getAlgorithm() {
return getLocalAttribute(EncryptionConstants._ATT_ALGORITHM);
}
- public ConcatKDFParamsImpl getConcatKDFParams() throws XMLSecurityException {
- if (concatKDFParams != null) {
- return concatKDFParams;
- }
+ @Override
+ public KDFParams getKDFParams() throws XMLSecurityException {
- Element concatKDFParamsElement =
- XMLUtils.selectXenc11Node(getElement().getFirstChild(), EncryptionConstants._TAG_CONCATKDFPARAMS, 0);
+ if (kdfParams != null) {
+ LOG.log(DEBUG, "Returning cached KDFParams");
+ return kdfParams;
+ }
- if (concatKDFParamsElement == null) {
- return null;
+ String kdfAlgorithm = getAlgorithm();
+ if (EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(kdfAlgorithm)) {
+ Element concatKDFParamsElement =
+ XMLUtils.selectXenc11Node(getElement().getFirstChild(),
+ EncryptionConstants._TAG_CONCATKDFPARAMS, 0);
+ kdfParams = new ConcatKDFParamsImpl(concatKDFParamsElement, getBaseURI());
+ } else if (EncryptionConstants.ALGO_ID_KEYDERIVATION_HKDF.equals(kdfAlgorithm)) {
+ Element hkdfParamsElement =
+ XMLUtils.selectNode(getElement().getFirstChild(),
+ Constants.XML_DSIG_NS_MORE_21_04,
+ EncryptionConstants._TAG_HKDFPARAMS, 0);
+ kdfParams = new HKDFParamsImpl(hkdfParamsElement, Constants.XML_DSIG_NS_MORE_07_05);
}
- concatKDFParams = new ConcatKDFParamsImpl(concatKDFParamsElement, getBaseURI());
- return concatKDFParams;
+ return kdfParams;
Review Comment:
According to the javadoc, this should throw an XMLSecurityException if the params are of an unknown type.
##########
src/main/java/org/apache/xml/security/utils/KeyUtils.java:
##########
@@ -258,17 +255,44 @@ public static int getAESKeyBitSizeForWrapAlgorithm(String keyWrapAlg) throws XML
*/
public static byte[] deriveKeyEncryptionKey(byte[] sharedSecret, KeyDerivationParameters keyDerivationParameter)
throws XMLSecurityException {
- int iKeySize = keyDerivationParameter.getKeyBitLength()/8;
+
+ if (keyDerivationParameter == null) {
+ throw new IllegalArgumentException("KeyDerivationParameter is null");
Review Comment:
The javadoc should have an `@throws IllegalArgumentException if keyDerivationParameter is null`
##########
src/main/java/org/apache/xml/security/encryption/params/HKDFParams.java:
##########
@@ -0,0 +1,76 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.params;
+
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.utils.EncryptionConstants;
+
+/**
+ * Class HMacKeyDerivationParameter (HKDF parameter) is used to specify
Review Comment:
Class name needs to be updated. Several methods need javadoc describing the parameters or return values.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1581872304
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,177 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as defined in RFC 5869.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm {
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+ private final String hmacHashAlgorithmURI;
+ private final Mac hmac;
+
+ /**
+ * Constructor HKDF initializes the Mac object with the given algorithmURI and salt.
+ *
+ * @param hmacHashAlgorithmURI the Hash algorithm
+ * @param salt the salt value to initialize the MAC algorithm.
+ * @throws XMLSecurityException if the key derivation initialization fails for any reason
+ */
+ public HKDF(String hmacHashAlgorithmURI, byte[] salt) throws XMLSecurityException {
+ this.hmacHashAlgorithmURI = hmacHashAlgorithmURI;
+ LOG.log(DEBUG, "Init HmacHash AlgorithmURI: [{}]", hmacHashAlgorithmURI);
+ hmac = initHMac(salt, true);
+ }
+
+ /**
+ * Derives a key from the given secret and info. Method extracts the key and then expands it to the keyLength.
+ *
+ * @param secret The "shared" secret to use for key derivation
+ * @param info The "info" parameter for key derivation describing purpose or derivation key context
+ * @param offset the starting position in derived keying material of size: offset + keyLength
+ * @param keyLength The length of the key to derive
+ * @return the derived key using HKDF for the given parameters.
+ * @throws XMLSecurityException if the key derivation fails for any reason
+ */
+ @Override
+ public byte[] deriveKey(byte[] secret, byte[] info, int offset, long keyLength) throws XMLSecurityException {
Review Comment:
The interface is changed to have a more generic method as suggested in another comment. I will update the WSS4J to use this interface as it can be more easily extended with new key derivation parameters.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1489429869
##########
src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java:
##########
@@ -302,4 +338,30 @@ public static ConcatKDFParams constructConcatKeyDerivationParameter(int keyBitLe
kdp.setSuppPrivInfo(suppPrivInfo);
return kdp;
}
+
Review Comment:
Done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-2112457974
> @seanjmullan Is it ready to be merged from your PoV?
Yes, although I think we should try to add the secureValidation mode support before we post the next release.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-2107386673
The branch is now updated with latest changes from the main, the build after the merge should pass now.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-2115123240
> @jrihtarsic Do you need this merged to 3.0.x as well?
@coheigea, yes indeed we would need it in 3.0.x so that we can use the latest feature with current apache/cxf
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1537411909
##########
src/main/java/org/apache/xml/security/resource/xmlsecurity_en.properties:
##########
@@ -111,7 +111,9 @@ KeyStore.registerStore.register = Registration error for type {0}
KeyValue.IllegalArgument = Cannot create a {0} from {1}
KeyDerivation.TooShortParameter = Key derivation parameter {0} is too short
KeyDerivation.InvalidParameter = Key derivation parameter {0} is illegal
+KeyDerivation.InvalidParametersType = Algorithm {0} requires key derivation parameters of type {1} to be provided.
Review Comment:
Done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1581870899
##########
src/main/java/org/apache/xml/security/encryption/KeyDerivationMethod.java:
##########
@@ -19,10 +19,15 @@
package org.apache.xml.security.encryption;
+import org.apache.xml.security.encryption.keys.content.derivedKey.KDFParams;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+
/**
- * The key derivation is to generate new cryptographic key material from existing key material such as the shared
- * secret and any other (private or public) information. The purpose of the key derivation is an extension of a given
- * but limited set of original key materials and to limit the use (exposure) of such key material.
+ * The key derivation is to generate new cryptographic key material from existing
+ * key material such as the shared secret and any other (private or public)
+ * information. The purpose of the key derivation is an extension of a given
+ * but limited set of original key materials and to limit the use (exposure)
+ * of such key material.
Review Comment:
Indeed it was a bit philosophical :) I updated the class description. Hope it's more readable now.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1576208433
##########
src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java:
##########
@@ -140,7 +140,7 @@ public static OAEPParameterSpec constructOAEPParameters(
public static MGF1ParameterSpec constructMGF1Parameter(String mgh1AlgorithmURI) {
LOG.log(Level.DEBUG, "Creating MGF1ParameterSpec for [{0}]", mgh1AlgorithmURI);
if (mgh1AlgorithmURI == null || mgh1AlgorithmURI.isEmpty()) {
- LOG.log(Level.WARNING,"MGF1 algorithm URI is null or empty. Using SHA-1 as default.");
+ LOG.log(Level.WARNING, "MGF1 algorithm URI is null or empty. Using SHA-1 as default.");
Review Comment:
I think the XML Encryption recommendation made a mistake to allow defaults for algorithms, but I don't think we need to necessarily adhere to that. That said, this could introduce interop issues if we treat a missing DigestMethod as SHA-256 instead of SHA-1. Instead, we could require the application to always specify the MGF digest method and no longer allow null to be passed in as the parameter.
This may be best handled as a separate issue so that all APIs which have defaults are checked - for example, RSA-OAEP also defaults to SHA-1 for the digest algorithm.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-2112478786
> > @seanjmullan Is it ready to be merged from your PoV?
>
> Yes, although I think we should try to add the secureValidation mode support before we post the next release.
@seanjmullan I can make the PR for this by the end of the next week.
The scope is shortly described here: SANTUARIO-620, please let me know if I should implement anything else.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1598354663
##########
src/main/java/org/apache/xml/security/utils/KeyUtils.java:
##########
@@ -247,34 +245,76 @@
}
}
-
/**
- * Derive a key encryption key from a shared secret and keyDerivationParameter. Currently only the ConcatKDF is supported.
+ * Derive a key encryption key from a shared secret and keyDerivationParameter.
+ * Currently only the ConcatKDF and HMAC-base Extract-and-Expand Key Derivation
+ * Function (HKDF) are supported.
+ *
* @param sharedSecret the shared secret
* @param keyDerivationParameter the key derivation parameters
* @return the derived key encryption key
+ * @throws IllegalArgumentException if the keyDerivationParameter is null
* @throws XMLSecurityException if the key derivation algorithm is not supported
*/
public static byte[] deriveKeyEncryptionKey(byte[] sharedSecret, KeyDerivationParameters keyDerivationParameter)
throws XMLSecurityException {
- int iKeySize = keyDerivationParameter.getKeyBitLength()/8;
+
+ if (keyDerivationParameter == null) {
+ throw new IllegalArgumentException(I18n.translate("KeyDerivation.MissingParameters"));
+ }
+
String keyDerivationAlgorithm = keyDerivationParameter.getAlgorithm();
- if (!EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(keyDerivationAlgorithm)) {
- throw new XMLEncryptionException( "unknownAlgorithm",
- keyDerivationAlgorithm);
+ if (keyDerivationParameter instanceof HKDFParams) {
+ return deriveKeyEncryptionKey(sharedSecret, (HKDFParams) keyDerivationParameter);
+ } else if (keyDerivationParameter instanceof ConcatKDFParams) {
+ return deriveKeyEncryptionKey(sharedSecret, (ConcatKDFParams) keyDerivationParameter);
+ }
+
+ throw new XMLEncryptionException("KeyDerivation.UnsupportedAlgorithm", keyDerivationAlgorithm,
+ keyDerivationParameter.getClass().getName());
+ }
+
+ /**
+ * Derive a key using the HMAC-based Extract-and-Expand Key Derivation
+ * Function (HKDF) with implementation instance {@link HKDFParams}.
+ *
+ * @param sharedSecret the shared secret
+ * @param hkdfParameter the HKDF parameters
+ * @return the derived key encryption key.
+ * @throws XMLSecurityException if the key derivation parameters are invalid or
+ * the hmac algorithm is not supported.
+ */
+ public static byte[] deriveKeyEncryptionKey(byte[] sharedSecret, HKDFParams hkdfParameter)
Review Comment:
Method renamed
##########
src/main/java/org/apache/xml/security/utils/KeyUtils.java:
##########
@@ -247,34 +245,76 @@
}
}
-
/**
- * Derive a key encryption key from a shared secret and keyDerivationParameter. Currently only the ConcatKDF is supported.
+ * Derive a key encryption key from a shared secret and keyDerivationParameter.
+ * Currently only the ConcatKDF and HMAC-base Extract-and-Expand Key Derivation
+ * Function (HKDF) are supported.
+ *
* @param sharedSecret the shared secret
* @param keyDerivationParameter the key derivation parameters
* @return the derived key encryption key
+ * @throws IllegalArgumentException if the keyDerivationParameter is null
* @throws XMLSecurityException if the key derivation algorithm is not supported
*/
public static byte[] deriveKeyEncryptionKey(byte[] sharedSecret, KeyDerivationParameters keyDerivationParameter)
throws XMLSecurityException {
- int iKeySize = keyDerivationParameter.getKeyBitLength()/8;
+
+ if (keyDerivationParameter == null) {
+ throw new IllegalArgumentException(I18n.translate("KeyDerivation.MissingParameters"));
+ }
+
String keyDerivationAlgorithm = keyDerivationParameter.getAlgorithm();
- if (!EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(keyDerivationAlgorithm)) {
- throw new XMLEncryptionException( "unknownAlgorithm",
- keyDerivationAlgorithm);
+ if (keyDerivationParameter instanceof HKDFParams) {
+ return deriveKeyEncryptionKey(sharedSecret, (HKDFParams) keyDerivationParameter);
+ } else if (keyDerivationParameter instanceof ConcatKDFParams) {
+ return deriveKeyEncryptionKey(sharedSecret, (ConcatKDFParams) keyDerivationParameter);
+ }
+
+ throw new XMLEncryptionException("KeyDerivation.UnsupportedAlgorithm", keyDerivationAlgorithm,
+ keyDerivationParameter.getClass().getName());
+ }
+
+ /**
+ * Derive a key using the HMAC-based Extract-and-Expand Key Derivation
+ * Function (HKDF) with implementation instance {@link HKDFParams}.
+ *
+ * @param sharedSecret the shared secret
+ * @param hkdfParameter the HKDF parameters
+ * @return the derived key encryption key.
+ * @throws XMLSecurityException if the key derivation parameters are invalid or
+ * the hmac algorithm is not supported.
+ */
+ public static byte[] deriveKeyEncryptionKey(byte[] sharedSecret, HKDFParams hkdfParameter)
+ throws XMLSecurityException {
+
+ if (!EncryptionConstants.ALGO_ID_KEYDERIVATION_HKDF.equals(hkdfParameter.getAlgorithm())){
+ throw new XMLEncryptionException("KeyDerivation.UnsupportedAlgorithm", hkdfParameter.getAlgorithm(),
+ HKDFParams.class.getName());
}
- ConcatKDFParams ckdfParameter = (ConcatKDFParams) keyDerivationParameter;
- // get parameters
- String digestAlgorithm = ckdfParameter.getDigestAlgorithm();
+ HKDF kdf = new HKDF();
+ return kdf.deriveKey(sharedSecret, hkdfParameter);
+ }
- String algorithmID = ckdfParameter.getAlgorithmID();
- String partyUInfo = ckdfParameter.getPartyUInfo();
- String partyVInfo = ckdfParameter.getPartyVInfo();
- String suppPubInfo = ckdfParameter.getSuppPubInfo();
- String suppPrivInfo = ckdfParameter.getSuppPrivInfo();
+ /**
+ * Derive a key using the Concatenation Key Derivation Function (ConcatKDF)
+ * with implementation instance {@link ConcatKDFParams}.
+ *
+ * @param sharedSecret the shared secret/ input keying material
+ * @param ckdfParameter the ConcatKDF parameters
+ * @return the derived key
+ * @throws XMLSecurityException if the key derivation parameters are invalid or
+ * the hash algorithm is not supported.
+ */
+ public static byte[] deriveKeyEncryptionKey(byte[] sharedSecret, ConcatKDFParams ckdfParameter)
Review Comment:
Method renamed
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "coheigea (via GitHub)" <gi...@apache.org>.
coheigea merged PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-1947989519
@coheigea understand and thanks for the info. I look forward to the first version of the key agreement option as part of the cxf.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1576234627
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,177 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as defined in RFC 5869.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm {
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+ private final String hmacHashAlgorithmURI;
+ private final Mac hmac;
+
+ /**
+ * Constructor HKDF initializes the Mac object with the given algorithmURI and salt.
+ *
+ * @param hmacHashAlgorithmURI the Hash algorithm
+ * @param salt the salt value to initialize the MAC algorithm.
+ * @throws XMLSecurityException if the key derivation initialization fails for any reason
+ */
+ public HKDF(String hmacHashAlgorithmURI, byte[] salt) throws XMLSecurityException {
+ this.hmacHashAlgorithmURI = hmacHashAlgorithmURI;
+ LOG.log(DEBUG, "Init HmacHash AlgorithmURI: [{}]", hmacHashAlgorithmURI);
+ hmac = initHMac(salt, true);
+ }
+
+ /**
+ * Derives a key from the given secret and info. Method extracts the key and then expands it to the keyLength.
+ *
+ * @param secret The "shared" secret to use for key derivation
+ * @param info The "info" parameter for key derivation describing purpose or derivation key context
+ * @param offset the starting position in derived keying material of size: offset + keyLength
+ * @param keyLength The length of the key to derive
+ * @return the derived key using HKDF for the given parameters.
+ * @throws XMLSecurityException if the key derivation fails for any reason
+ */
+ @Override
+ public byte[] deriveKey(byte[] secret, byte[] info, int offset, long keyLength) throws XMLSecurityException {
Review Comment:
Indeed it is hard to imagine key size to need long type. But the interface for DerivationAlgorithm was taken from ws-wss4 project
https://github.com/apache/ws-wss4j/blob/master/ws-security-common/src/main/java/org/apache/wss4j/common/derivedKey/DerivationAlgorithm.java
The idea behind was to reduce duplication of the code there (wss4j) and use methods from xmlsec .. to make wss4j slimmer/cleaner
Anyhow will change to int.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1581871338
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/KeyDerivationMethodImpl.java:
##########
@@ -71,29 +73,43 @@ public String getAlgorithm() {
return getLocalAttribute(EncryptionConstants._ATT_ALGORITHM);
}
- public ConcatKDFParamsImpl getConcatKDFParams() throws XMLSecurityException {
- if (concatKDFParams != null) {
- return concatKDFParams;
- }
+ @Override
+ public KDFParams getKDFParams() throws XMLSecurityException {
- Element concatKDFParamsElement =
- XMLUtils.selectXenc11Node(getElement().getFirstChild(), EncryptionConstants._TAG_CONCATKDFPARAMS, 0);
+ if (kdfParams != null) {
+ LOG.log(DEBUG, "Returning cached KDFParams");
+ return kdfParams;
+ }
- if (concatKDFParamsElement == null) {
- return null;
+ String kdfAlgorithm = getAlgorithm();
+ if (EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(kdfAlgorithm)) {
+ Element concatKDFParamsElement =
+ XMLUtils.selectXenc11Node(getElement().getFirstChild(),
+ EncryptionConstants._TAG_CONCATKDFPARAMS, 0);
+ kdfParams = new ConcatKDFParamsImpl(concatKDFParamsElement, getBaseURI());
+ } else if (EncryptionConstants.ALGO_ID_KEYDERIVATION_HKDF.equals(kdfAlgorithm)) {
+ Element hkdfParamsElement =
+ XMLUtils.selectNode(getElement().getFirstChild(),
+ Constants.XML_DSIG_NS_MORE_21_04,
+ EncryptionConstants._TAG_HKDFPARAMS, 0);
+ kdfParams = new HKDFParamsImpl(hkdfParamsElement, Constants.XML_DSIG_NS_MORE_07_05);
}
- concatKDFParams = new ConcatKDFParamsImpl(concatKDFParamsElement, getBaseURI());
- return concatKDFParams;
+ return kdfParams;
Review Comment:
Fixed the behavior of the method - to match the description.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1583144930
##########
src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java:
##########
@@ -271,93 +272,42 @@ public static KeyAgreementParameters constructAgreementParameters(String agreeme
* Construct a KeyDerivationParameter object from the given keyDerivationMethod and keyBitLength
*
* @param keyDerivationMethod element with the key derivation method data
- * @param keyBitLength expected derived key length
+ * @param keyBitLength expected derived key length in bits
* @return KeyDerivationParameters data
- * @throws XMLSecurityException if the keyDerivationMethod is not supported or invalid parameters are provided
+ * @throws XMLSecurityException if the invalid key derivation parameters are provide
Review Comment:
Can this method still throw XMLSecurityException? Can it throw XMLEncryptionException instead?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1598253284
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,182 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.encryption.params.HKDFParams;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.utils.I18n;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
+ * as defined in <a href="https://datatracker.ietf.org/doc/html/rfc5869">RFC 5869</a>.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm<HKDFParams> {
+
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+
+ /**
+ * Derive a key using the HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
+ * as defined in <a href="https://datatracker.ietf.org/doc/html/rfc5869">RFC 5869</a>.
+ *
+ * @param secret The "shared" secret to use for key derivation
+ * @param params The key derivation parameters (salt, info, key length, ...)
+ * @return The derived key of the specified length in bytes defined in the params
+ * @throws IllegalArgumentException if the parameters are missing
+ * @throws XMLSecurityException if the hmac hash algorithm is not supported
+ */
+ @Override
+ public byte[] deriveKey(byte[] secret, HKDFParams params) throws XMLSecurityException {
+ // check if the parameters are set
+ if (params == null) {
+ throw new IllegalArgumentException(I18n.translate("KeyDerivation.MissingParameters"));
+ }
+
+ String jceAlgorithmName;
+ try {
+ jceAlgorithmName = XMLCipherUtil.getJCEMacHashForUri(params.getHmacHashAlgorithm());
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(e, "KeyDerivation.NotSupportedParameter", new Object[]{params.getHmacHashAlgorithm()});
+ }
+
+ byte[] prk = extractKey(jceAlgorithmName, params.getSalt(), secret);
+ return expandKey(jceAlgorithmName, prk, params.getInfo(), params.getKeyLength());
+ }
+
+ /**
+ * The method "extracts" the pseudo-random key (PRK) based on HMAC-Hash function
+ * (optional) salt value (a non-secret random value) and the shared secret/input
+ * keying material (IKM).
+ * Calculation of the extracted key:
+ * <pre>PRK = HMAC-Hash(salt, IKM)</pre>
+ *
+ * @param jceAlgorithmName the java JCE HMAC algorithm name to use for key derivation
+ * (e.g. HmacSHA256, HmacSHA384, HmacSHA512)
+ * @param salt the optional salt value (a non-secret random value);
+ * @param secret the shared secret/input keying material (IKM) to use for
+ * key derivation
+ * @return the pseudo-random key bytes
+ * @throws XMLSecurityException if the jceAlgorithmName is not supported
+ */
+ public byte[] extractKey(String jceAlgorithmName, byte[] salt, byte[] secret) throws XMLSecurityException {
+ Mac hMac = initHMac(jceAlgorithmName, salt, true);
+ hMac.reset();
+ return hMac.doFinal(secret);
+ }
+
+ /**
+ * The method inits Hash-MAC with given PRK (as salt) and output OKM is calculated as follows:
+ * <pre>
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ *
+ * @param jceHmacAlgorithmName the java JCE HMAC algorithm name to use to expand
+ * the key (e.g. HmacSHA256, HmacSHA384, HmacSHA512)
+ * @param prk pseudo-random key derived from the shared secret
+ * @param info used to derive the key
+ * @param keyLength key length in bytes of the derived key
+ * @return the output keying material (OKM) size of keyLength octets
+ * @throws XMLSecurityException if the jceHmacAlgorithmName is not supported
+ */
+ public byte[] expandKey(String jceHmacAlgorithmName, byte[] prk, byte[] info, long keyLength) throws XMLSecurityException {
+ // prepare for expanding the key
+ Mac hMac = initHMac(jceHmacAlgorithmName, prk, false);
+ int iMacLength = hMac.getMacLength();
+
+ int toGenerateSize = (int) keyLength;
+ ByteBuffer result = ByteBuffer.allocate(toGenerateSize);
+ byte[] prevResult = new byte[0];
+ short counter = 1;
+ while (toGenerateSize > 0) {
+ hMac.reset();
+ hMac.update(prevResult);
+ if (info != null && info.length > 0) {
+ hMac.update(info);
+ }
+ hMac.update((byte) counter);
+ prevResult = hMac.doFinal();
+ result.put(prevResult, 0, Math.min(toGenerateSize, iMacLength));
+ // get ready for next iteration
+ toGenerateSize -= iMacLength;
+ counter++;
+ }
+ return result.array();
+ }
+
+ /**
+ * Method initializes a Message Authentication Code (MAC) object using the
+ * init secret/salt or an empty byte array if initSecret parameter is null or empty.
+ *
+ * @param jceAlgorithmName the java JCE HMAC algorithm name to use to init Mac
+ * @param initSecret the secret/salt to initialize the hmac
+ * @param initPRK if true, the salt is initialized with a string of zero octets
+ * as long as the hash function output see [RFC5869] Section 2.2
+ * @return Initialized Mac object
+ * @throws XMLSecurityException if the hmac algorithm is not supported or if it
+ * fails to initialize
+ */
+ private Mac initHMac(String jceAlgorithmName, byte[] initSecret, boolean initPRK) throws XMLSecurityException {
+ Mac mac;
+ try {
+ LOG.log(DEBUG, "Init Mac with hash algorithm: [{}]", jceAlgorithmName);
+ mac = Mac.getInstance(jceAlgorithmName);
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(e, "KeyDerivation.NotSupportedParameter", new Object[]{jceAlgorithmName});
+ }
+
+ if (initPRK && (initSecret == null || initSecret.length == 0)) {
+ // If "initSecret"/salt is not provided, a string of zero octets as long as the hash function output is used
+ LOG.log(DEBUG, "Init Mac with hmac algorithm [{}] and empty salt!", jceAlgorithmName);
+ initSecret = new byte[mac.getMacLength()];
+ }
+ SecretKeySpec secretKey = new SecretKeySpec(initSecret, jceAlgorithmName);
Review Comment:
@coheigea, @seanjmullan, I would need your advice on this check failure. The method "XMLCipherUtil.getJCEMacHashForUri" is just mapping URI names to JCE names. Should I just log warning for HmacSHA1, HmacSHA224, HmacSHA384, HMACRIPEMD160 or should the method throw and error since algorithms are weak or should we just ignore the CodeQL?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1599989548
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,182 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.encryption.params.HKDFParams;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.utils.I18n;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
+ * as defined in <a href="https://datatracker.ietf.org/doc/html/rfc5869">RFC 5869</a>.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm<HKDFParams> {
+
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+
+ /**
+ * Derive a key using the HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
+ * as defined in <a href="https://datatracker.ietf.org/doc/html/rfc5869">RFC 5869</a>.
+ *
+ * @param secret The "shared" secret to use for key derivation
+ * @param params The key derivation parameters (salt, info, key length, ...)
+ * @return The derived key of the specified length in bytes defined in the params
+ * @throws IllegalArgumentException if the parameters are missing
+ * @throws XMLSecurityException if the hmac hash algorithm is not supported
+ */
+ @Override
+ public byte[] deriveKey(byte[] secret, HKDFParams params) throws XMLSecurityException {
+ // check if the parameters are set
+ if (params == null) {
+ throw new IllegalArgumentException(I18n.translate("KeyDerivation.MissingParameters"));
+ }
+
+ String jceAlgorithmName;
+ try {
+ jceAlgorithmName = XMLCipherUtil.getJCEMacHashForUri(params.getHmacHashAlgorithm());
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(e, "KeyDerivation.NotSupportedParameter", new Object[]{params.getHmacHashAlgorithm()});
+ }
+
+ byte[] prk = extractKey(jceAlgorithmName, params.getSalt(), secret);
+ return expandKey(jceAlgorithmName, prk, params.getInfo(), params.getKeyLength());
+ }
+
+ /**
+ * The method "extracts" the pseudo-random key (PRK) based on HMAC-Hash function
+ * (optional) salt value (a non-secret random value) and the shared secret/input
+ * keying material (IKM).
+ * Calculation of the extracted key:
+ * <pre>PRK = HMAC-Hash(salt, IKM)</pre>
+ *
+ * @param jceAlgorithmName the java JCE HMAC algorithm name to use for key derivation
+ * (e.g. HmacSHA256, HmacSHA384, HmacSHA512)
+ * @param salt the optional salt value (a non-secret random value);
+ * @param secret the shared secret/input keying material (IKM) to use for
+ * key derivation
+ * @return the pseudo-random key bytes
+ * @throws XMLSecurityException if the jceAlgorithmName is not supported
+ */
+ public byte[] extractKey(String jceAlgorithmName, byte[] salt, byte[] secret) throws XMLSecurityException {
+ Mac hMac = initHMac(jceAlgorithmName, salt, true);
+ hMac.reset();
+ return hMac.doFinal(secret);
+ }
+
+ /**
+ * The method inits Hash-MAC with given PRK (as salt) and output OKM is calculated as follows:
+ * <pre>
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ *
+ * @param jceHmacAlgorithmName the java JCE HMAC algorithm name to use to expand
+ * the key (e.g. HmacSHA256, HmacSHA384, HmacSHA512)
+ * @param prk pseudo-random key derived from the shared secret
+ * @param info used to derive the key
+ * @param keyLength key length in bytes of the derived key
+ * @return the output keying material (OKM) size of keyLength octets
+ * @throws XMLSecurityException if the jceHmacAlgorithmName is not supported
+ */
+ public byte[] expandKey(String jceHmacAlgorithmName, byte[] prk, byte[] info, long keyLength) throws XMLSecurityException {
+ // prepare for expanding the key
+ Mac hMac = initHMac(jceHmacAlgorithmName, prk, false);
+ int iMacLength = hMac.getMacLength();
+
+ int toGenerateSize = (int) keyLength;
+ ByteBuffer result = ByteBuffer.allocate(toGenerateSize);
+ byte[] prevResult = new byte[0];
+ short counter = 1;
+ while (toGenerateSize > 0) {
+ hMac.reset();
+ hMac.update(prevResult);
+ if (info != null && info.length > 0) {
+ hMac.update(info);
+ }
+ hMac.update((byte) counter);
+ prevResult = hMac.doFinal();
+ result.put(prevResult, 0, Math.min(toGenerateSize, iMacLength));
+ // get ready for next iteration
+ toGenerateSize -= iMacLength;
+ counter++;
+ }
+ return result.array();
+ }
+
+ /**
+ * Method initializes a Message Authentication Code (MAC) object using the
+ * init secret/salt or an empty byte array if initSecret parameter is null or empty.
+ *
+ * @param jceAlgorithmName the java JCE HMAC algorithm name to use to init Mac
+ * @param initSecret the secret/salt to initialize the hmac
+ * @param initPRK if true, the salt is initialized with a string of zero octets
+ * as long as the hash function output see [RFC5869] Section 2.2
+ * @return Initialized Mac object
+ * @throws XMLSecurityException if the hmac algorithm is not supported or if it
+ * fails to initialize
+ */
+ private Mac initHMac(String jceAlgorithmName, byte[] initSecret, boolean initPRK) throws XMLSecurityException {
+ Mac mac;
+ try {
+ LOG.log(DEBUG, "Init Mac with hash algorithm: [{}]", jceAlgorithmName);
+ mac = Mac.getInstance(jceAlgorithmName);
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(e, "KeyDerivation.NotSupportedParameter", new Object[]{jceAlgorithmName});
+ }
+
+ if (initPRK && (initSecret == null || initSecret.length == 0)) {
+ // If "initSecret"/salt is not provided, a string of zero octets as long as the hash function output is used
+ LOG.log(DEBUG, "Init Mac with hmac algorithm [{}] and empty salt!", jceAlgorithmName);
+ initSecret = new byte[mac.getMacLength()];
+ }
+ SecretKeySpec secretKey = new SecretKeySpec(initSecret, jceAlgorithmName);
Review Comment:
A few comments/questions:
- Why are all of these considered weak/insecure? Ok, I understand HmacSHA1 could be considered weak, but why HmacSHA224, HmacSHA384?
- There is already a secureValidation mode implemented in Santuario which restricts weak crypto algorithms; however HmacSHA1 is not disabled yet. We could consider disabling it, but we also need to assess the compatibility risk of doing that, which may be too high.
- There may be some more places we should be adding additional secureValidation checks in the HKDF code. Can you explore this further?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1600182025
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,182 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.encryption.params.HKDFParams;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.utils.I18n;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
+ * as defined in <a href="https://datatracker.ietf.org/doc/html/rfc5869">RFC 5869</a>.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm<HKDFParams> {
+
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+
+ /**
+ * Derive a key using the HMAC-based Extract-and-Expand Key Derivation Function (HKDF)
+ * as defined in <a href="https://datatracker.ietf.org/doc/html/rfc5869">RFC 5869</a>.
+ *
+ * @param secret The "shared" secret to use for key derivation
+ * @param params The key derivation parameters (salt, info, key length, ...)
+ * @return The derived key of the specified length in bytes defined in the params
+ * @throws IllegalArgumentException if the parameters are missing
+ * @throws XMLSecurityException if the hmac hash algorithm is not supported
+ */
+ @Override
+ public byte[] deriveKey(byte[] secret, HKDFParams params) throws XMLSecurityException {
+ // check if the parameters are set
+ if (params == null) {
+ throw new IllegalArgumentException(I18n.translate("KeyDerivation.MissingParameters"));
+ }
+
+ String jceAlgorithmName;
+ try {
+ jceAlgorithmName = XMLCipherUtil.getJCEMacHashForUri(params.getHmacHashAlgorithm());
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(e, "KeyDerivation.NotSupportedParameter", new Object[]{params.getHmacHashAlgorithm()});
+ }
+
+ byte[] prk = extractKey(jceAlgorithmName, params.getSalt(), secret);
+ return expandKey(jceAlgorithmName, prk, params.getInfo(), params.getKeyLength());
+ }
+
+ /**
+ * The method "extracts" the pseudo-random key (PRK) based on HMAC-Hash function
+ * (optional) salt value (a non-secret random value) and the shared secret/input
+ * keying material (IKM).
+ * Calculation of the extracted key:
+ * <pre>PRK = HMAC-Hash(salt, IKM)</pre>
+ *
+ * @param jceAlgorithmName the java JCE HMAC algorithm name to use for key derivation
+ * (e.g. HmacSHA256, HmacSHA384, HmacSHA512)
+ * @param salt the optional salt value (a non-secret random value);
+ * @param secret the shared secret/input keying material (IKM) to use for
+ * key derivation
+ * @return the pseudo-random key bytes
+ * @throws XMLSecurityException if the jceAlgorithmName is not supported
+ */
+ public byte[] extractKey(String jceAlgorithmName, byte[] salt, byte[] secret) throws XMLSecurityException {
+ Mac hMac = initHMac(jceAlgorithmName, salt, true);
+ hMac.reset();
+ return hMac.doFinal(secret);
+ }
+
+ /**
+ * The method inits Hash-MAC with given PRK (as salt) and output OKM is calculated as follows:
+ * <pre>
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ *
+ * @param jceHmacAlgorithmName the java JCE HMAC algorithm name to use to expand
+ * the key (e.g. HmacSHA256, HmacSHA384, HmacSHA512)
+ * @param prk pseudo-random key derived from the shared secret
+ * @param info used to derive the key
+ * @param keyLength key length in bytes of the derived key
+ * @return the output keying material (OKM) size of keyLength octets
+ * @throws XMLSecurityException if the jceHmacAlgorithmName is not supported
+ */
+ public byte[] expandKey(String jceHmacAlgorithmName, byte[] prk, byte[] info, long keyLength) throws XMLSecurityException {
+ // prepare for expanding the key
+ Mac hMac = initHMac(jceHmacAlgorithmName, prk, false);
+ int iMacLength = hMac.getMacLength();
+
+ int toGenerateSize = (int) keyLength;
+ ByteBuffer result = ByteBuffer.allocate(toGenerateSize);
+ byte[] prevResult = new byte[0];
+ short counter = 1;
+ while (toGenerateSize > 0) {
+ hMac.reset();
+ hMac.update(prevResult);
+ if (info != null && info.length > 0) {
+ hMac.update(info);
+ }
+ hMac.update((byte) counter);
+ prevResult = hMac.doFinal();
+ result.put(prevResult, 0, Math.min(toGenerateSize, iMacLength));
+ // get ready for next iteration
+ toGenerateSize -= iMacLength;
+ counter++;
+ }
+ return result.array();
+ }
+
+ /**
+ * Method initializes a Message Authentication Code (MAC) object using the
+ * init secret/salt or an empty byte array if initSecret parameter is null or empty.
+ *
+ * @param jceAlgorithmName the java JCE HMAC algorithm name to use to init Mac
+ * @param initSecret the secret/salt to initialize the hmac
+ * @param initPRK if true, the salt is initialized with a string of zero octets
+ * as long as the hash function output see [RFC5869] Section 2.2
+ * @return Initialized Mac object
+ * @throws XMLSecurityException if the hmac algorithm is not supported or if it
+ * fails to initialize
+ */
+ private Mac initHMac(String jceAlgorithmName, byte[] initSecret, boolean initPRK) throws XMLSecurityException {
+ Mac mac;
+ try {
+ LOG.log(DEBUG, "Init Mac with hash algorithm: [{}]", jceAlgorithmName);
+ mac = Mac.getInstance(jceAlgorithmName);
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(e, "KeyDerivation.NotSupportedParameter", new Object[]{jceAlgorithmName});
+ }
+
+ if (initPRK && (initSecret == null || initSecret.length == 0)) {
+ // If "initSecret"/salt is not provided, a string of zero octets as long as the hash function output is used
+ LOG.log(DEBUG, "Init Mac with hmac algorithm [{}] and empty salt!", jceAlgorithmName);
+ initSecret = new byte[mac.getMacLength()];
+ }
+ SecretKeySpec secretKey = new SecretKeySpec(initSecret, jceAlgorithmName);
Review Comment:
For the "why HmacSHA224, HmacSHA384 are considered weak/insecure?" I am also not sure about that, but "**_Code scanning / CodeQL_**" is reporting them as "may not be secure, consider using a different algorithm". See below.
@coheigea is it possible CodeQL has configuration issue?
To prevent scope creep, I created a new ticket [SANTUARIO-620](https://issues.apache.org/jira/browse/SANTUARIO-620) to implement the secureValidation feature for the rest comments/questions. This enhancement will apply not only to HKDF but also to the ConcatKDF and Agreement methods.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "coheigea (via GitHub)" <gi...@apache.org>.
coheigea commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-2100372554
@jrihtarsic There is a build error:
```
[INFO] -------------------------------------------------------------
Error: COMPILATION ERROR :
[INFO] -------------------------------------------------------------
Error: /home/runner/work/santuario-xml-security-java/santuario-xml-security-java/src/test/java/org/apache/xml/security/test/dom/encryption/XMLCipherTest.java:[581,58] ConcatKDFParams(int,java.lang.String) has protected access in org.apache.xml.security.encryption.params.ConcatKDFParams
Error: /home/runner/work/santuario-xml-security-java/santuario-xml-security-java/src/test/java/org/apache/xml/security/test/dom/encryption/XMLEncryption11BrainpoolTest.java:[123,58] ConcatKDFParams(int,java.lang.String) has protected access in org.apache.xml.security.encryption.params.ConcatKDFParams
```
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1592359981
##########
src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java:
##########
@@ -271,93 +272,42 @@ public static KeyAgreementParameters constructAgreementParameters(String agreeme
* Construct a KeyDerivationParameter object from the given keyDerivationMethod and keyBitLength
*
* @param keyDerivationMethod element with the key derivation method data
- * @param keyBitLength expected derived key length
+ * @param keyBitLength expected derived key length in bits
* @return KeyDerivationParameters data
- * @throws XMLSecurityException if the keyDerivationMethod is not supported or invalid parameters are provided
+ * @throws XMLSecurityException if the invalid key derivation parameters are provide
Review Comment:
I updated the code now to ensure that only the XMLEncryptionException can be thrown. I made changes to the XMLCipherUtil.constructKeyDerivationParameter method only and retained the XMLSecurityException in the interface KeyDerivationMethod.getKDFParams; because the interface implementation may be used for key derivation functions used for other purposes than just the encryption in the future.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1534523455
##########
src/main/java/org/apache/xml/security/resource/xmlsecurity_en.properties:
##########
@@ -111,7 +111,9 @@ KeyStore.registerStore.register = Registration error for type {0}
KeyValue.IllegalArgument = Cannot create a {0} from {1}
KeyDerivation.TooShortParameter = Key derivation parameter {0} is too short
KeyDerivation.InvalidParameter = Key derivation parameter {0} is illegal
+KeyDerivation.InvalidParametersType = Algorithm {0} requires key derivation parameters of type {1} to be provided.
Review Comment:
Nit: most of the other error messages end in a period, so suggest removing it.
##########
src/main/java/org/apache/xml/security/resource/xmlsecurity_en.properties:
##########
@@ -111,7 +111,9 @@ KeyStore.registerStore.register = Registration error for type {0}
KeyValue.IllegalArgument = Cannot create a {0} from {1}
KeyDerivation.TooShortParameter = Key derivation parameter {0} is too short
KeyDerivation.InvalidParameter = Key derivation parameter {0} is illegal
+KeyDerivation.InvalidParametersType = Algorithm {0} requires key derivation parameters of type {1} to be provided.
KeyDerivation.NotSupportedParameter = Key derivation parameter {0} is not supported
+KeyDerivation.UnsupportedAlgorithm = Unsupported Key derivation Algorithm: {0} for class {1}
Review Comment:
s/Key/key
s/Algorithm:/algorithm (no need for colon)
##########
src/main/java/org/apache/xml/security/encryption/params/HKDFParams.java:
##########
@@ -0,0 +1,76 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.params;
+
+import org.apache.xml.security.algorithms.MessageDigestAlgorithm;
+import org.apache.xml.security.signature.XMLSignature;
+import org.apache.xml.security.utils.EncryptionConstants;
+
+/**
+ * Class HMacKeyDerivationParameter (HKDF parameter) is used to specify parameters for the HMAC-based Extract-and-Expand
Review Comment:
s/HMacKeyDerivationParameter/HKDFParams/
Try to break lines at around 80 chars.
##########
src/main/java/org/apache/xml/security/encryption/KeyDerivationMethod.java:
##########
@@ -43,4 +46,15 @@ public interface KeyDerivationMethod {
* @return the algorithm URI of this <code>KeyDerivationMethod</code>
*/
String getAlgorithm();
+
+ /**
+ * Returns the KDF parameters used by the key derivation algorithm. Currently supported types are
+ * {@link org.apache.xml.security.encryption.params.ConcatKDFParams} and
+ * {@link org.apache.xml.security.encryption.params.HKDFParams}.
+ *
+ * @return the KDFParams used by the key derivation algorithm
+ * @throws XMLSecurityException if the KDFParams cannot be created.
Review Comment:
Nit: no need for period.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "coheigea (via GitHub)" <gi...@apache.org>.
coheigea commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-2011342439
@seanjmullan Just a reminder please, as this PR blocks another Pr in WSS4J
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1489433310
##########
src/test/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDFTest.java:
##########
@@ -0,0 +1,144 @@
+/**
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+
+import org.apache.xml.security.binding.xmldsig.DigestMethodType;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.signature.XMLSignature;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+import javax.xml.crypto.dsig.DigestMethod;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) tests as defined
+ * in RFC 5869, Appendix A. Test Vectors
+ */
+class HKDFTest {
+
+ @ParameterizedTest(name = "{index}. {0}")
+ @CsvSource({
+ "'Rfc5869: Test Case 1','http://www.w3.org/2001/04/xmlenc#sha256'," +
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b," +
+ "000102030405060708090a0b0c,f0f1f2f3f4f5f6f7f8f9,42, " +
+ "077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5," +
+ "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865",
+ "'Rfc5869: Test Case 2','http://www.w3.org/2001/04/xmlenc#sha256', " +
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f," +
+ "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf," +
+ "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff," +
+ "82, " +
+ "06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244," +
+ "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87",
+ "'Rfc5869: Test Case 3','http://www.w3.org/2001/04/xmlenc#sha256', " +
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b," +
+ "''," +
+ "''," +
+ "42, " +
+ "19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04," +
+ "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8",
+ "'Rfc5869: Test Case 4','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "0b0b0b0b0b0b0b0b0b0b0b," +
+ "000102030405060708090a0b0c," +
+ "f0f1f2f3f4f5f6f7f8f9," +
+ "42, " +
+ "9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243," +
+ "085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896",
+ "'Rfc5869: Test Case 5','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f," +
+ "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf," +
+ "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff," +
+ "82, " +
+ "8adae09a2a307059478d309b26c4115a224cfaf6," +
+ "0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4",
+ "'Rfc5869: Test Case 6','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b," +
+ "''," +
+ "''," +
+ "42, " +
+ "da8c8a73c7fa77288ec6f5e7c297786aa0d32d01," +
+ "0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918",
+ "'Rfc5869: Test Case 7','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c," +
+ "," +
+ "''," +
+ "42, " +
+ "2adccada18779e7c2077ad2eb19d3f3e731385dd," +
+ "2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48",
+ })
+ void deriveKey(String name, String hash, String ikm, String salt, String info, int length, String prk, String okm) throws XMLSecurityException {
+ byte[] saltBytes = hexStringToByteArray(salt);
+ byte[] infoBytes = hexStringToByteArray(info);
+ byte[] ikmBytes = hexStringToByteArray(ikm);
+
+ byte[] expectedPRK =hexStringToByteArray(prk);
+ byte[] expectedOKM =hexStringToByteArray(okm);
+ String hMacHashAlgorithmURI = getHMacHashForHashUri(hash);
+ HKDF hkdf = new HKDF(hMacHashAlgorithmURI, saltBytes);
+ byte[] extractedKey = hkdf.extractKey(ikmBytes);
+ byte[] derivedKey = hkdf.deriveKey(ikmBytes, infoBytes, 0, length);
+
+ assertArrayEquals(expectedPRK, extractedKey);
+ assertArrayEquals(expectedOKM, derivedKey);
+ }
+
+
+ public static byte[] hexStringToByteArray(String value){
Review Comment:
Good catch. Updated and reused the method for tests as well.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "seanjmullan (via GitHub)" <gi...@apache.org>.
seanjmullan commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1576158626
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,177 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as defined in RFC 5869.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm {
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+ private final String hmacHashAlgorithmURI;
+ private final Mac hmac;
+
+ /**
+ * Constructor HKDF initializes the Mac object with the given algorithmURI and salt.
+ *
+ * @param hmacHashAlgorithmURI the Hash algorithm
+ * @param salt the salt value to initialize the MAC algorithm.
+ * @throws XMLSecurityException if the key derivation initialization fails for any reason
+ */
+ public HKDF(String hmacHashAlgorithmURI, byte[] salt) throws XMLSecurityException {
+ this.hmacHashAlgorithmURI = hmacHashAlgorithmURI;
+ LOG.log(DEBUG, "Init HmacHash AlgorithmURI: [{}]", hmacHashAlgorithmURI);
+ hmac = initHMac(salt, true);
+ }
+
+ /**
+ * Derives a key from the given secret and info. Method extracts the key and then expands it to the keyLength.
+ *
+ * @param secret The "shared" secret to use for key derivation
+ * @param info The "info" parameter for key derivation describing purpose or derivation key context
+ * @param offset the starting position in derived keying material of size: offset + keyLength
+ * @param keyLength The length of the key to derive
+ * @return the derived key using HKDF for the given parameters.
+ * @throws XMLSecurityException if the key derivation fails for any reason
+ */
+ @Override
+ public byte[] deriveKey(byte[] secret, byte[] info, int offset, long keyLength) throws XMLSecurityException {
Review Comment:
Why is `keyLength` a long instead of an int? Do we really think derived keys will be that large?
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,177 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as defined in RFC 5869.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm {
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+ private final String hmacHashAlgorithmURI;
+ private final Mac hmac;
+
+ /**
+ * Constructor HKDF initializes the Mac object with the given algorithmURI and salt.
+ *
+ * @param hmacHashAlgorithmURI the Hash algorithm
+ * @param salt the salt value to initialize the MAC algorithm.
+ * @throws XMLSecurityException if the key derivation initialization fails for any reason
+ */
+ public HKDF(String hmacHashAlgorithmURI, byte[] salt) throws XMLSecurityException {
Review Comment:
Why is salt specified here but not in the deriveKey method? This means this HKDF object cannot be reused if salt is different.
I think part of the problem is that the `DerivationAlgorithm` interface is too specific and designed to support ConcatKDF. It may make sense to add some more `deriveKey` methods to that interface that take a `KDFParams` object so that the parameters can be more abstract and defined by the subclasses, ex:
`byte[] deriveKey(byte[] secret, KDFParams params) throws XMLSecurityException`
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,177 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as defined in RFC 5869.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm {
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+ private final String hmacHashAlgorithmURI;
+ private final Mac hmac;
+
+ /**
+ * Constructor HKDF initializes the Mac object with the given algorithmURI and salt.
+ *
+ * @param hmacHashAlgorithmURI the Hash algorithm
+ * @param salt the salt value to initialize the MAC algorithm.
+ * @throws XMLSecurityException if the key derivation initialization fails for any reason
+ */
+ public HKDF(String hmacHashAlgorithmURI, byte[] salt) throws XMLSecurityException {
+ this.hmacHashAlgorithmURI = hmacHashAlgorithmURI;
+ LOG.log(DEBUG, "Init HmacHash AlgorithmURI: [{}]", hmacHashAlgorithmURI);
+ hmac = initHMac(salt, true);
+ }
+
+ /**
+ * Derives a key from the given secret and info. Method extracts the key and then expands it to the keyLength.
+ *
+ * @param secret The "shared" secret to use for key derivation
+ * @param info The "info" parameter for key derivation describing purpose or derivation key context
+ * @param offset the starting position in derived keying material of size: offset + keyLength
+ * @param keyLength The length of the key to derive
+ * @return the derived key using HKDF for the given parameters.
+ * @throws XMLSecurityException if the key derivation fails for any reason
+ */
+ @Override
+ public byte[] deriveKey(byte[] secret, byte[] info, int offset, long keyLength) throws XMLSecurityException {
+
+ byte[] prk = extractKey(secret);
+ return expandKey(prk, info, offset, keyLength);
+ }
+
+ /**
+ * The extracted pseudo-random based on HMAC-Hash function. Salt is set at class initialization.
+ * Calculation of the extracted key: <pre>PRK = HMAC-Hash(salt, IKM)</pre>
+ *
+ * @param secret the shared secret (IKM) to use for key derivation
+ * @return the pseudo-random key
+ */
+ public byte[] extractKey(byte[] secret) {
+ hmac.reset();
+ return hmac.doFinal(secret);
+ }
+
+ /**
+ * The method inits Hash-MAC with given PRK (as salt) and output OKM is calculated as follows:
+ * <pre>
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ *
+ * @param prk pseudo-random key
+ * @param info used to derive the key
+ * @param offset in bytes of the derived key
+ * @param keyLength in bytes of the derived key
+ * @return the derived key OKM
+ * @throws XMLSecurityException in case the key derivation fails for any reason
+ */
+
+ public byte[] expandKey(byte[] prk, byte[] info, int offset, long keyLength) throws XMLSecurityException {
+ // prepare for expanding the key
+ Mac hMac = initHMac(prk, false);
+ int iMacLength = hMac.getMacLength();
+
+ int toGenerateSize = (int) keyLength;
+ ByteBuffer result = ByteBuffer.allocate(toGenerateSize);
+ byte[] prevResult = new byte[0];
+ short counter = 1;
+ while (toGenerateSize > 0) {
+ hMac.reset();
+ hMac.update(prevResult);
+ if (info != null && info.length > 0) {
+ hMac.update(info);
+ }
+ hMac.update((byte) counter);
+ prevResult = hMac.doFinal();
+ result.put(prevResult, 0, Math.min(toGenerateSize, iMacLength));
+ // ger ready for next iteration
Review Comment:
s/ger/get/
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDF.java:
##########
@@ -0,0 +1,177 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.encryption.XMLCipherUtil;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static java.lang.System.Logger.Level.DEBUG;
+
+/**
+ * The implementation of the HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as defined in RFC 5869.
+ * <p>
+ * The HKDF algorithm is defined as follows:
+ * <pre>
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L bytes of T
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ */
+public class HKDF implements DerivationAlgorithm {
+
+ private static final System.Logger LOG = System.getLogger(HKDF.class.getName());
+ private final String hmacHashAlgorithmURI;
+ private final Mac hmac;
+
+ /**
+ * Constructor HKDF initializes the Mac object with the given algorithmURI and salt.
+ *
+ * @param hmacHashAlgorithmURI the Hash algorithm
+ * @param salt the salt value to initialize the MAC algorithm.
+ * @throws XMLSecurityException if the key derivation initialization fails for any reason
+ */
+ public HKDF(String hmacHashAlgorithmURI, byte[] salt) throws XMLSecurityException {
+ this.hmacHashAlgorithmURI = hmacHashAlgorithmURI;
+ LOG.log(DEBUG, "Init HmacHash AlgorithmURI: [{}]", hmacHashAlgorithmURI);
+ hmac = initHMac(salt, true);
+ }
+
+ /**
+ * Derives a key from the given secret and info. Method extracts the key and then expands it to the keyLength.
+ *
+ * @param secret The "shared" secret to use for key derivation
+ * @param info The "info" parameter for key derivation describing purpose or derivation key context
+ * @param offset the starting position in derived keying material of size: offset + keyLength
+ * @param keyLength The length of the key to derive
+ * @return the derived key using HKDF for the given parameters.
+ * @throws XMLSecurityException if the key derivation fails for any reason
+ */
+ @Override
+ public byte[] deriveKey(byte[] secret, byte[] info, int offset, long keyLength) throws XMLSecurityException {
+
+ byte[] prk = extractKey(secret);
+ return expandKey(prk, info, offset, keyLength);
+ }
+
+ /**
+ * The extracted pseudo-random based on HMAC-Hash function. Salt is set at class initialization.
+ * Calculation of the extracted key: <pre>PRK = HMAC-Hash(salt, IKM)</pre>
+ *
+ * @param secret the shared secret (IKM) to use for key derivation
+ * @return the pseudo-random key
+ */
+ public byte[] extractKey(byte[] secret) {
+ hmac.reset();
+ return hmac.doFinal(secret);
+ }
+
+ /**
+ * The method inits Hash-MAC with given PRK (as salt) and output OKM is calculated as follows:
+ * <pre>
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ * </pre>
+ *
+ * @param prk pseudo-random key
+ * @param info used to derive the key
+ * @param offset in bytes of the derived key
+ * @param keyLength in bytes of the derived key
+ * @return the derived key OKM
+ * @throws XMLSecurityException in case the key derivation fails for any reason
+ */
+
+ public byte[] expandKey(byte[] prk, byte[] info, int offset, long keyLength) throws XMLSecurityException {
+ // prepare for expanding the key
+ Mac hMac = initHMac(prk, false);
+ int iMacLength = hMac.getMacLength();
+
+ int toGenerateSize = (int) keyLength;
+ ByteBuffer result = ByteBuffer.allocate(toGenerateSize);
+ byte[] prevResult = new byte[0];
+ short counter = 1;
+ while (toGenerateSize > 0) {
+ hMac.reset();
+ hMac.update(prevResult);
+ if (info != null && info.length > 0) {
+ hMac.update(info);
+ }
+ hMac.update((byte) counter);
+ prevResult = hMac.doFinal();
+ result.put(prevResult, 0, Math.min(toGenerateSize, iMacLength));
+ // ger ready for next iteration
+ toGenerateSize -= iMacLength;
+ counter++;
+ }
+ if (offset > 0) {
+ result.position(offset);
+ return result.slice().array();
+ }
+ return result.array();
+ }
+
+ /**
+ * Method initializes a Message Authentication Code (MAC) object using the
+ * init secret/salt or an empty byte array if initSecret parameter is null or empty.
+ *
+ * @param initSecret the secret/salt to initialize the hmac
+ * @param initPRK if true, the salt is initialized with a string of zero octets as long as the hash function output
+ * see [RFC5869] Section 2.2
+ * @return Initialized Mac object
+ * @throws XMLSecurityException if the key derivation initialization fails for any reason
+ */
+ private Mac initHMac(byte[] initSecret, boolean initPRK) throws XMLSecurityException {
+ String jceAlgorithm = null;
+ Mac mac;
+ try {
+ jceAlgorithm = XMLCipherUtil.getJCEMacHashForUri(hmacHashAlgorithmURI);
+ LOG.log(DEBUG, "Init Mac with hash algorithm: [{}]", jceAlgorithm);
+ mac = Mac.getInstance(jceAlgorithm);
+ } catch (NoSuchAlgorithmException e) {
+ throw new XMLSecurityException(e, "KeyDerivation.NotSupportedParameter", new Object[]{jceAlgorithm});
+ }
+
+ if (initPRK && (initSecret == null || initSecret.length == 0)) {
+ // If "initSecret"/salt is not provided, a string of zero octets as long as the hash function output is used
+ LOG.log(DEBUG, "Init Mac with hmac algorithm [{}] and empty salt!", jceAlgorithm);
+ initSecret = new byte[mac.getMacLength()];
+ }
+ SecretKeySpec secret_key = new SecretKeySpec(initSecret, jceAlgorithm);
Review Comment:
s/secret_key/secretKey/
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1581871542
##########
src/main/java/org/apache/xml/security/utils/KeyUtils.java:
##########
@@ -248,7 +246,6 @@ public static int getAESKeyBitSizeForWrapAlgorithm(String keyWrapAlg) throws XML
}
}
-
/**
* Derive a key encryption key from a shared secret and keyDerivationParameter. Currently only the ConcatKDF is supported.
Review Comment:
Good catch, I updated the description
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "jrihtarsic (via GitHub)" <gi...@apache.org>.
jrihtarsic commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1581874128
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/KeyDerivationMethodImpl.java:
##########
@@ -71,29 +73,43 @@ public String getAlgorithm() {
return getLocalAttribute(EncryptionConstants._ATT_ALGORITHM);
}
- public ConcatKDFParamsImpl getConcatKDFParams() throws XMLSecurityException {
- if (concatKDFParams != null) {
- return concatKDFParams;
- }
+ @Override
+ public KDFParams getKDFParams() throws XMLSecurityException {
- Element concatKDFParamsElement =
- XMLUtils.selectXenc11Node(getElement().getFirstChild(), EncryptionConstants._TAG_CONCATKDFPARAMS, 0);
+ if (kdfParams != null) {
+ LOG.log(DEBUG, "Returning cached KDFParams");
+ return kdfParams;
+ }
- if (concatKDFParamsElement == null) {
- return null;
+ String kdfAlgorithm = getAlgorithm();
+ if (EncryptionConstants.ALGO_ID_KEYDERIVATION_CONCATKDF.equals(kdfAlgorithm)) {
+ Element concatKDFParamsElement =
+ XMLUtils.selectXenc11Node(getElement().getFirstChild(),
+ EncryptionConstants._TAG_CONCATKDFPARAMS, 0);
+ kdfParams = new ConcatKDFParamsImpl(concatKDFParamsElement, getBaseURI());
+ } else if (EncryptionConstants.ALGO_ID_KEYDERIVATION_HKDF.equals(kdfAlgorithm)) {
+ Element hkdfParamsElement =
+ XMLUtils.selectNode(getElement().getFirstChild(),
+ Constants.XML_DSIG_NS_MORE_21_04,
+ EncryptionConstants._TAG_HKDFPARAMS, 0);
+ kdfParams = new HKDFParamsImpl(hkdfParamsElement, Constants.XML_DSIG_NS_MORE_07_05);
}
- concatKDFParams = new ConcatKDFParamsImpl(concatKDFParamsElement, getBaseURI());
- return concatKDFParams;
+ return kdfParams;
}
- public void setConcatKDFParams(ConcatKDFParamsImpl concatKDFParams) {
- this.concatKDFParams = concatKDFParams;
- appendSelf(concatKDFParams);
- addReturnToSelf();
+ public void setKDFParams(KDFParams kdfParams) {
Review Comment:
Done
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "coheigea (via GitHub)" <gi...@apache.org>.
coheigea commented on code in PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#discussion_r1488890018
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDFParamsImpl.java:
##########
@@ -0,0 +1,198 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.ElementProxy;
+import org.apache.xml.security.utils.EncryptionConstants;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Class HKDFParamsImpl is an DOM representation of the HKDF Parameters.
+ */
+public class HKDFParamsImpl extends ElementProxy implements KDFParams {
+
+
+ /**
+ * Constructor creates a new HKDFParamsImpl instance.
+ *
+ * @param doc the Document in which to create the DOM tree
+ */
+ public HKDFParamsImpl(Document doc) {
+
Review Comment:
Remove blank line
##########
src/test/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDFTest.java:
##########
@@ -0,0 +1,144 @@
+/**
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+
+import org.apache.xml.security.binding.xmldsig.DigestMethodType;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.signature.XMLSignature;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+import javax.xml.crypto.dsig.DigestMethod;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) tests as defined
+ * in RFC 5869, Appendix A. Test Vectors
+ */
+class HKDFTest {
+
+ @ParameterizedTest(name = "{index}. {0}")
+ @CsvSource({
+ "'Rfc5869: Test Case 1','http://www.w3.org/2001/04/xmlenc#sha256'," +
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b," +
+ "000102030405060708090a0b0c,f0f1f2f3f4f5f6f7f8f9,42, " +
+ "077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5," +
+ "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865",
+ "'Rfc5869: Test Case 2','http://www.w3.org/2001/04/xmlenc#sha256', " +
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f," +
+ "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf," +
+ "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff," +
+ "82, " +
+ "06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244," +
+ "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87",
+ "'Rfc5869: Test Case 3','http://www.w3.org/2001/04/xmlenc#sha256', " +
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b," +
+ "''," +
+ "''," +
+ "42, " +
+ "19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04," +
+ "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8",
+ "'Rfc5869: Test Case 4','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "0b0b0b0b0b0b0b0b0b0b0b," +
+ "000102030405060708090a0b0c," +
+ "f0f1f2f3f4f5f6f7f8f9," +
+ "42, " +
+ "9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243," +
+ "085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896",
+ "'Rfc5869: Test Case 5','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f," +
+ "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf," +
+ "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff," +
+ "82, " +
+ "8adae09a2a307059478d309b26c4115a224cfaf6," +
+ "0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4",
+ "'Rfc5869: Test Case 6','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b," +
+ "''," +
+ "''," +
+ "42, " +
+ "da8c8a73c7fa77288ec6f5e7c297786aa0d32d01," +
+ "0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918",
+ "'Rfc5869: Test Case 7','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c," +
+ "," +
+ "''," +
+ "42, " +
+ "2adccada18779e7c2077ad2eb19d3f3e731385dd," +
+ "2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48",
+ })
+ void deriveKey(String name, String hash, String ikm, String salt, String info, int length, String prk, String okm) throws XMLSecurityException {
+ byte[] saltBytes = hexStringToByteArray(salt);
+ byte[] infoBytes = hexStringToByteArray(info);
+ byte[] ikmBytes = hexStringToByteArray(ikm);
+
+ byte[] expectedPRK =hexStringToByteArray(prk);
+ byte[] expectedOKM =hexStringToByteArray(okm);
+ String hMacHashAlgorithmURI = getHMacHashForHashUri(hash);
+ HKDF hkdf = new HKDF(hMacHashAlgorithmURI, saltBytes);
+ byte[] extractedKey = hkdf.extractKey(ikmBytes);
+ byte[] derivedKey = hkdf.deriveKey(ikmBytes, infoBytes, 0, length);
+
+ assertArrayEquals(expectedPRK, extractedKey);
+ assertArrayEquals(expectedOKM, derivedKey);
+ }
+
+
+ public static byte[] hexStringToByteArray(String value){
Review Comment:
Why can't we use the method in XMLCIpherUtil that was added instead of this?
##########
src/main/java/org/apache/xml/security/encryption/XMLCipherUtil.java:
##########
@@ -302,4 +338,30 @@ public static ConcatKDFParams constructConcatKeyDerivationParameter(int keyBitLe
kdp.setSuppPrivInfo(suppPrivInfo);
return kdp;
}
+
Review Comment:
I guess we should add javadoc here to align with the concat static method?
##########
src/main/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDFParamsImpl.java:
##########
@@ -0,0 +1,198 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.utils.Constants;
+import org.apache.xml.security.utils.ElementProxy;
+import org.apache.xml.security.utils.EncryptionConstants;
+import org.apache.xml.security.utils.XMLUtils;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+/**
+ * Class HKDFParamsImpl is an DOM representation of the HKDF Parameters.
+ */
+public class HKDFParamsImpl extends ElementProxy implements KDFParams {
+
+
+ /**
+ * Constructor creates a new HKDFParamsImpl instance.
+ *
+ * @param doc the Document in which to create the DOM tree
+ */
+ public HKDFParamsImpl(Document doc) {
+
+ super(doc);
+ }
+
+ /**
+ * Constructor HKDFParamsImpl from existing XML element
+ *
+ * @param element the element to use as source
+ * @param baseURI the URI of the resource where the XML instance was stored
+ * @throws XMLSecurityException if the construction fails for any reason
+ */
+ public HKDFParamsImpl(Element element, String baseURI) throws XMLSecurityException {
+ super(element, baseURI);
+ }
+
+ /**
+ * Sets the <code>DigestMethod</code> Element
+ *
+ * @param hmacHashAlgorithm is the digest method URI value.
+ */
+ public void setPRFAlgorithm(String hmacHashAlgorithm) {
+ Element targetElement =
+ XMLUtils.selectNode(getElement().getFirstChild(), getBaseNamespace(), EncryptionConstants._TAG_PRF, 0);
+
Review Comment:
Remove blank lines
##########
src/test/java/org/apache/xml/security/encryption/keys/content/derivedKey/HKDFTest.java:
##########
@@ -0,0 +1,144 @@
+/**
+ * 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.xml.security.encryption.keys.content.derivedKey;
+
+
+import org.apache.xml.security.binding.xmldsig.DigestMethodType;
+import org.apache.xml.security.exceptions.XMLSecurityException;
+import org.apache.xml.security.signature.XMLSignature;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.CsvSource;
+
+import javax.xml.crypto.dsig.DigestMethod;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+/**
+ * The HMAC-based Extract-and-Expand Key Derivation Function (HKDF) tests as defined
+ * in RFC 5869, Appendix A. Test Vectors
+ */
+class HKDFTest {
+
+ @ParameterizedTest(name = "{index}. {0}")
+ @CsvSource({
+ "'Rfc5869: Test Case 1','http://www.w3.org/2001/04/xmlenc#sha256'," +
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b," +
+ "000102030405060708090a0b0c,f0f1f2f3f4f5f6f7f8f9,42, " +
+ "077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5," +
+ "3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865",
+ "'Rfc5869: Test Case 2','http://www.w3.org/2001/04/xmlenc#sha256', " +
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f," +
+ "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf," +
+ "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff," +
+ "82, " +
+ "06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244," +
+ "b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87",
+ "'Rfc5869: Test Case 3','http://www.w3.org/2001/04/xmlenc#sha256', " +
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b," +
+ "''," +
+ "''," +
+ "42, " +
+ "19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04," +
+ "8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8",
+ "'Rfc5869: Test Case 4','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "0b0b0b0b0b0b0b0b0b0b0b," +
+ "000102030405060708090a0b0c," +
+ "f0f1f2f3f4f5f6f7f8f9," +
+ "42, " +
+ "9b6c18c432a7bf8f0e71c8eb88f4b30baa2ba243," +
+ "085a01ea1b10f36933068b56efa5ad81a4f14b822f5b091568a9cdd4f155fda2c22e422478d305f3f896",
+ "'Rfc5869: Test Case 5','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f," +
+ "606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf," +
+ "b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff," +
+ "82, " +
+ "8adae09a2a307059478d309b26c4115a224cfaf6," +
+ "0bd770a74d1160f7c9f12cd5912a06ebff6adcae899d92191fe4305673ba2ffe8fa3f1a4e5ad79f3f334b3b202b2173c486ea37ce3d397ed034c7f9dfeb15c5e927336d0441f4c4300e2cff0d0900b52d3b4",
+ "'Rfc5869: Test Case 6','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b," +
+ "''," +
+ "''," +
+ "42, " +
+ "da8c8a73c7fa77288ec6f5e7c297786aa0d32d01," +
+ "0ac1af7002b3d761d1e55298da9d0506b9ae52057220a306e07b6b87e8df21d0ea00033de03984d34918",
+ "'Rfc5869: Test Case 7','http://www.w3.org/2000/09/xmldsig#sha1', " +
+ "0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c," +
+ "," +
+ "''," +
+ "42, " +
+ "2adccada18779e7c2077ad2eb19d3f3e731385dd," +
+ "2c91117204d745f3500d636a62f64f0ab3bae548aa53d423b0d1f27ebba6f5e5673a081d70cce7acfc48",
+ })
+ void deriveKey(String name, String hash, String ikm, String salt, String info, int length, String prk, String okm) throws XMLSecurityException {
+ byte[] saltBytes = hexStringToByteArray(salt);
+ byte[] infoBytes = hexStringToByteArray(info);
+ byte[] ikmBytes = hexStringToByteArray(ikm);
+
+ byte[] expectedPRK =hexStringToByteArray(prk);
+ byte[] expectedOKM =hexStringToByteArray(okm);
Review Comment:
Add space after the = sign
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
Re: [PR] Implementation of the HKDF derivation function [santuario-xml-security-java]
Posted by "coheigea (via GitHub)" <gi...@apache.org>.
coheigea commented on PR #271:
URL: https://github.com/apache/santuario-xml-security-java/pull/271#issuecomment-2115108545
@jrihtarsic Do you need this merged to 3.0.x as well?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: dev-unsubscribe@santuario.apache.org
For queries about this service, please contact Infrastructure at:
users@infra.apache.org