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

com.microsoft.windowsazure.storage.StorageKey Maven / Gradle / Ivy

/**
 * Copyright Microsoft Corporation
 * 
 * Licensed 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 com.microsoft.windowsazure.storage;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.microsoft.windowsazure.storage.core.Base64;

/**
 * Represents a container for a storage key.
 */
public final class StorageKey {
    /**
     * Computes a signature for the specified string using the HMAC-SHA256 algorithm.
     * 
     * @param storageKey
     *            A StorageKey object that represents the storage key to use.
     * @param stringToSign
     *            The UTF-8-encoded string to sign.
     * 
     * @return A String that contains the HMAC-SHA256-encoded signature.
     * 
     * @throws IllegalArgumentException
     *             If the string to sign is not a valid Base64-encoded string.
     * @throws InvalidKeyException
     *             If the key is not a valid storage key.
     */
    public static synchronized String computeMacSha256(final StorageKey storageKey, final String stringToSign)
            throws InvalidKeyException {
        if (storageKey.hmacSha256 == null) {
            storageKey.initHmacSha256();
        }

        byte[] utf8Bytes = null;
        try {
            utf8Bytes = stringToSign.getBytes("UTF8");
        }
        catch (final UnsupportedEncodingException e) {
            throw new IllegalArgumentException(e);
        }

        return Base64.encode(storageKey.hmacSha256.doFinal(utf8Bytes));
    }

    /**
     * Computes a signature for the specified string using the HMAC-SHA512 algorithm.
     * 
     * @param storageKey
     *            A StorageKey object that represents the storage key to use.
     * @param stringToSign
     *            The UTF-8-encoded string to sign.
     * 
     * @return A String that contains the HMAC-SHA512-encoded signature.
     * 
     * @throws IllegalArgumentException
     *             If the string to sign is not a valid Base64-encoded string.
     * @throws InvalidKeyException
     *             If the key is not a valid storage key.
     */
    public static synchronized String computeMacSha512(final StorageKey storageKey, final String stringToSign)
            throws InvalidKeyException {
        if (storageKey.hmacSha512 == null) {
            storageKey.initHmacSha512();
        }

        byte[] utf8Bytes = null;
        try {
            utf8Bytes = stringToSign.getBytes("UTF8");
        }
        catch (final UnsupportedEncodingException e) {
            throw new IllegalArgumentException(e);
        }

        return Base64.encode(storageKey.hmacSha512.doFinal(utf8Bytes));
    }

    /**
     * Stores a reference to the hmacsha256 Mac.
     */
    private Mac hmacSha256;

    /**
     * Stores a reference to the hmacsha512 Mac.
     */
    private Mac hmacSha512;

    /**
     * Stores a reference to the hmacsha256 SecretKey.
     */
    private SecretKey key256;

    /**
     * Stores a reference to the hmacsha512 SecretKey.
     */
    private SecretKey key512;

    /**
     * Stores the key.
     */
    private byte[] key;

    /**
     * Creates an instance of the StorageKey class.
     * 
     * @param key
     *            An array of bytes that represent the storage key.
     */
    public StorageKey(final byte[] key) {
        this.setKey(key);
    }

    /**
     * Returns the Base64-encoded key.
     * 
     * @return A String that represents the Base64-encoded key.
     */
    public String getBase64EncodedKey() {
        return Base64.encode(this.key);
    }

    /**
     * Returns the key.
     * 
     * @return A byte array that represents the key.
     */
    public byte[] getKey() {
        final byte[] copy = this.key.clone();
        return copy;
    }

    /**
     * Initializes the hmacsha256 Mac and SecretKey.
     * 
     * @throws InvalidKeyException
     *             if the key is not a valid SecretKey according to spec.
     */
    private void initHmacSha256() throws InvalidKeyException {
        this.key256 = new SecretKeySpec(this.key, "HmacSHA256");
        try {
            this.hmacSha256 = Mac.getInstance("HmacSHA256");
        }
        catch (final NoSuchAlgorithmException e) {
            throw new IllegalArgumentException();
        }
        this.hmacSha256.init(this.key256);
    }

    /**
     * Initializes the hmacsha512 Mac and SecretKey.
     * 
     * @throws InvalidKeyException
     *             if the key is not a valid SecretKey according to spec.
     */
    private void initHmacSha512() throws InvalidKeyException {
        this.key512 = new SecretKeySpec(this.key, "HmacSHA512");
        try {
            this.hmacSha512 = Mac.getInstance("HmacSHA512");
        }
        catch (final NoSuchAlgorithmException e) {
            throw new IllegalArgumentException();
        }
        this.hmacSha512.init(this.key512);
    }

    /**
     * Sets the key to be used, using the specified byte array as the key.
     * 

* This method is provided to support key rotation. This method is not thread-safe. * * @param key * A byte array that represents the key being assigned. */ public void setKey(final byte[] key) { this.key = key; this.hmacSha256 = null; this.hmacSha512 = null; this.key256 = null; this.key512 = null; } /** * Sets the key to be used, using the specified String as the key. *

* This method is provided to support key rotation. This method is not thread-safe. * * @param key * A String that represents the key being assigned. * @throws IOException * If the specified key is not a valid Base64-encoded string. */ public void setKey(final String key) throws IOException { this.key = Base64.decode(key); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy