All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.encryptionsdk.internal.CommittedKey Maven / Gradle / Ivy

// Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package com.amazonaws.encryptionsdk.internal;

import com.amazonaws.encryptionsdk.CryptoAlgorithm;
import java.nio.charset.StandardCharsets;
import java.security.NoSuchAlgorithmException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import javax.management.openmbean.InvalidKeyException;

public final class CommittedKey {

  private final SecretKey key_;
  private final byte[] commitment_;

  CommittedKey(SecretKey key, byte[] commitment) {
    key_ = key;
    commitment_ = commitment;
  }

  public SecretKey getKey() {
    return key_;
  }

  public byte[] getCommitment() {
    return commitment_.clone();
  }

  /**
   * The template for creating the label/info for deriving the encryption key from the data key.
   *
   * 

Note that this value must be cloned and modified prior to use. Cloned to prevent * modification of the template and threading issues. Modified to insert the algorithm id into the * first two bytes. */ private static byte[] DERIVE_KEY_LABEL_TEMPLATE = "__DERIVEKEY".getBytes(StandardCharsets.UTF_8); /** * Full label/info for deriving the key commitment value from the data key. * *

Unlike {@link #DERIVE_KEY_LABEL_TEMPLATE} this value does not need to be cloned or modified * prior to use. */ private static byte[] COMMITKEY_LABEL = "COMMITKEY".getBytes(StandardCharsets.UTF_8); private static final String RAW_DATA_FORMAT = "RAW"; private static final String HKDF_SHA_512 = "HkdfSHA512"; private static final String HMAC_SHA_512 = "HmacSHA512"; /** Generates an encryption key along with associated commitment value. */ public static CommittedKey generate(CryptoAlgorithm alg, SecretKey dataKey, byte[] nonce) throws InvalidKeyException { if (!alg.isCommitting()) { throw new IllegalArgumentException("Algorithm does not support key commitment."); } if (nonce.length != alg.getCommitmentNonceLength()) { throw new IllegalArgumentException("Invalid nonce size"); } if (dataKey.getFormat() == null || !dataKey.getFormat().equalsIgnoreCase(RAW_DATA_FORMAT)) { throw new IllegalArgumentException( "Currently only RAW format keys are supported for HKDF algorithms. Actual format was " + dataKey.getFormat()); } if (dataKey.getAlgorithm() == null || !dataKey.getAlgorithm().equalsIgnoreCase(alg.getDataKeyAlgo())) { throw new IllegalArgumentException( "DataKey of incorrect algorithm. Expected " + alg.getDataKeyAlgo() + " but was " + dataKey.getAlgorithm()); } final byte[] rawDataKey = dataKey.getEncoded(); if (rawDataKey.length != alg.getDataKeyLength()) { throw new IllegalArgumentException( "DataKey of incorrect length. Expected " + alg.getDataKeyLength() + " but was " + rawDataKey.length); } final String macAlgorithm; switch (alg.getKeyCommitmentAlgo_()) { case HKDF_SHA_512: macAlgorithm = HMAC_SHA_512; break; default: throw new UnsupportedOperationException( "Support for commitment with " + alg.getKeyCommitmentAlgo_() + " not yet built."); } HmacKeyDerivationFunction kdf = null; try { kdf = HmacKeyDerivationFunction.getInstance(macAlgorithm); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException(e); } kdf.init(rawDataKey, nonce); final byte[] commitment = kdf.deriveKey(COMMITKEY_LABEL, alg.getCommitmentLength()); // Clone to prevent modification of the master copy final byte[] deriveKeyLabel = DERIVE_KEY_LABEL_TEMPLATE.clone(); final short algId = alg.getValue(); deriveKeyLabel[0] = (byte) ((algId >> 8) & 0xFF); deriveKeyLabel[1] = (byte) (algId & 0xFF); SecretKey ek = new SecretKeySpec(kdf.deriveKey(deriveKeyLabel, alg.getKeyLength()), alg.getKeyAlgo()); return new CommittedKey(ek, commitment); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy