001/* 002 * nimbus-jose-jwt 003 * 004 * Copyright 2012-2016, Connect2id Ltd and contributors. 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use 007 * this file except in compliance with the License. You may obtain a copy of the 008 * License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software distributed 013 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 014 * CONDITIONS OF ANY KIND, either express or implied. See the License for the 015 * specific language governing permissions and limitations under the License. 016 */ 017 018package com.nimbusds.jose.crypto.impl; 019 020 021import java.security.InvalidKeyException; 022import java.security.NoSuchAlgorithmException; 023import java.security.Provider; 024import javax.crypto.Mac; 025import javax.crypto.SecretKey; 026import javax.crypto.spec.SecretKeySpec; 027 028import com.nimbusds.jose.JOSEException; 029import net.jcip.annotations.ThreadSafe; 030 031 032/** 033 * Static methods for Hash-based Message Authentication Codes (HMAC). This 034 * class is thread-safe. 035 * 036 * @author Axel Nennker 037 * @author Vladimir Dzhuvinov 038 * @version 2015-04-23 039 */ 040@ThreadSafe 041public class HMAC { 042 043 044 public static Mac getInitMac(final SecretKey secretKey, 045 final Provider provider) 046 throws JOSEException { 047 048 Mac mac; 049 050 try { 051 if (provider != null) { 052 mac = Mac.getInstance(secretKey.getAlgorithm(), provider); 053 } else { 054 mac = Mac.getInstance(secretKey.getAlgorithm()); 055 } 056 057 mac.init(secretKey); 058 059 } catch (NoSuchAlgorithmException e) { 060 061 throw new JOSEException("Unsupported HMAC algorithm: " + e.getMessage(), e); 062 063 } catch (InvalidKeyException e) { 064 065 throw new JOSEException("Invalid HMAC key: " + e.getMessage(), e); 066 } 067 068 return mac; 069 } 070 071 072 /** 073 * Computes a Hash-based Message Authentication Code (HMAC) for the 074 * specified secret and message. 075 * 076 * @param alg The Java Cryptography Architecture (JCA) HMAC 077 * algorithm name. Must not be {@code null}. 078 * @param secret The secret. Must not be {@code null}. 079 * @param message The message. Must not be {@code null}. 080 * @param provider The JCA provider, or {@code null} to use the default 081 * one. 082 * 083 * @return A MAC service instance. 084 * 085 * @throws JOSEException If the algorithm is not supported or the 086 * MAC secret key is invalid. 087 */ 088 public static byte[] compute(final String alg, 089 final byte[] secret, 090 final byte[] message, 091 final Provider provider) 092 throws JOSEException { 093 094 return compute(new SecretKeySpec(secret, alg), message, provider); 095 } 096 097 098 /** 099 * Computes a Hash-based Message Authentication Code (HMAC) for the 100 * specified secret key and message. 101 * 102 * @param secretKey The secret key, with the appropriate HMAC 103 * algorithm. Must not be {@code null}. 104 * @param message The message. Must not be {@code null}. 105 * @param provider The JCA provider, or {@code null} to use the 106 * default one. 107 * 108 * @return A MAC service instance. 109 * 110 * @throws JOSEException If the algorithm is not supported or the MAC 111 * secret key is invalid. 112 */ 113 public static byte[] compute(final SecretKey secretKey, 114 final byte[] message, 115 final Provider provider) 116 throws JOSEException { 117 118 Mac mac = getInitMac(secretKey, provider); 119 mac.update(message); 120 return mac.doFinal(); 121 } 122}