
com.amazonaws.mobileconnectors.cognitoidentityprovider.util.Hkdf Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aws-android-sdk-cognitoidentityprovider Show documentation
Show all versions of aws-android-sdk-cognitoidentityprovider Show documentation
The AWS Android SDK for Amazon Cognito Identity Provider module holds the client classes that are used for communicating with Amazon Cognito Identity Provider Service
/*
* Copyright 2013-2016 Amazon.com,
* Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Amazon Software License (the "License").
* You may not use this file except in compliance with the
* License. A copy of the License is located at
*
* http://aws.amazon.com/asl/
*
* or in the "license" file accompanying this file. This file is
* distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, express or implied. See the License
* for the specific language governing permissions and
* limitations under the License.
*/
package com.amazonaws.mobileconnectors.cognitoidentityprovider.util;
import com.amazonaws.util.StringUtils;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.SecretKeySpec;
/**
* Utility class for all HKDF operations.
*/
public final class Hkdf {
private static final byte[] EMPTY_ARRAY = new byte[0];
private final String algorithm;
private SecretKey prk = null;
public static Hkdf getInstance(String algorithm) throws NoSuchAlgorithmException {
Mac mac = Mac.getInstance(algorithm);
return new Hkdf(algorithm);
}
public void init(byte[] ikm) {
this.init(ikm, (byte[])null);
}
public void init(byte[] ikm, byte[] salt) {
byte[] realSalt = salt == null?EMPTY_ARRAY:(byte[])salt.clone();
byte[] rawKeyMaterial = EMPTY_ARRAY;
try {
Mac e = Mac.getInstance(this.algorithm);
if(realSalt.length == 0) {
realSalt = new byte[e.getMacLength()];
Arrays.fill(realSalt, (byte)0);
}
e.init(new SecretKeySpec(realSalt, this.algorithm));
rawKeyMaterial = e.doFinal(ikm);
SecretKeySpec key = new SecretKeySpec(rawKeyMaterial, this.algorithm);
Arrays.fill(rawKeyMaterial, (byte)0);
this.unsafeInitWithoutKeyExtraction(key);
} catch (GeneralSecurityException var10) {
throw new RuntimeException("Unexpected exception", var10);
} finally {
Arrays.fill(rawKeyMaterial, (byte)0);
}
}
public void unsafeInitWithoutKeyExtraction(SecretKey rawKey) throws InvalidKeyException {
if(!rawKey.getAlgorithm().equals(this.algorithm)) {
throw new InvalidKeyException("Algorithm for the provided key must match the algorithm for this Hkdf. Expected " + this.algorithm + " but found " + rawKey.getAlgorithm());
} else {
this.prk = rawKey;
}
}
private Hkdf(String algorithm) {
if(!algorithm.startsWith("Hmac")) {
throw new IllegalArgumentException("Invalid algorithm " + algorithm + ". Hkdf may only be used with Hmac algorithms.");
} else {
this.algorithm = algorithm;
}
}
public byte[] deriveKey(String info, int length) throws IllegalStateException {
return this.deriveKey(info != null?info.getBytes(StringUtils.UTF8):null, length);
}
public byte[] deriveKey(byte[] info, int length) throws IllegalStateException {
byte[] result = new byte[length];
try {
this.deriveKey(info, length, result, 0);
return result;
} catch (ShortBufferException var5) {
throw new RuntimeException(var5);
}
}
public void deriveKey(byte[] info, int length, byte[] output, int offset) throws ShortBufferException, IllegalStateException {
this.assertInitialized();
if(length < 0) {
throw new IllegalArgumentException("Length must be a non-negative value.");
} else if(output.length < offset + length) {
throw new ShortBufferException();
} else {
Mac mac = this.createMac();
if(length > 255 * mac.getMacLength()) {
throw new IllegalArgumentException("Requested keys may not be longer than 255 times the underlying HMAC length.");
} else {
byte[] t = EMPTY_ARRAY;
try {
int loc = 0;
for(byte i = 1; loc < length; ++i) {
mac.update(t);
mac.update(info);
mac.update(i);
t = mac.doFinal();
for(int x = 0; x < t.length && loc < length; ++loc) {
output[loc] = t[x];
++x;
}
}
} finally {
Arrays.fill(t, (byte)0);
}
}
}
}
private Mac createMac() {
try {
Mac ex = Mac.getInstance(this.algorithm);
ex.init(this.prk);
return ex;
} catch (NoSuchAlgorithmException var2) {
throw new RuntimeException(var2);
} catch (InvalidKeyException var3) {
throw new RuntimeException(var3);
}
}
private void assertInitialized() throws IllegalStateException {
if(this.prk == null) {
throw new IllegalStateException("Hkdf has not been initialized");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy