001/* 002 * nimbus-jose-jwt 003 * 004 * Copyright 2012-2023, 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 com.nimbusds.jose.JOSEException; 022import net.jcip.annotations.ThreadSafe; 023 024import javax.crypto.Mac; 025import javax.crypto.SecretKey; 026import javax.crypto.spec.SecretKeySpec; 027import java.security.InvalidKeyException; 028import java.security.NoSuchAlgorithmException; 029import java.security.Provider; 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 * @author Ulrich Winter 039 * @version 2023-09-14 040 */ 041@ThreadSafe 042public class HMAC { 043 044 045 /** 046 * Gets an initialised Message Authentication Code (MAC) service 047 * instance. 048 * 049 * @param secretKey The secret key, with the appropriate HMAC 050 * algorithm. Must not be {@code null}. 051 * @param provider The JCA provider, or {@code null} to use the 052 * default one. 053 * 054 * @return The MAC service instance. 055 * 056 * @throws JOSEException If the algorithm is not supported or the 057 * MAC secret key is invalid. 058 */ 059 public static Mac getInitMac(final SecretKey secretKey, final Provider provider) 060 throws JOSEException { 061 062 return getInitMac(secretKey.getAlgorithm(), secretKey, provider); 063 } 064 065 066 /** 067 * Gets an initialised Message Authentication Code (MAC) service 068 * instance. 069 * 070 * @param alg The Java Cryptography Architecture (JCA) HMAC 071 * algorithm name. Must not be {@code null}. 072 * @param secretKey The secret key. Its algorithm name is ignored. 073 * Must not be {@code null}. 074 * @param provider The JCA provider, or {@code null} to use the 075 * default one. 076 * 077 * @return The MAC service instance. 078 * 079 * @throws JOSEException If the algorithm is not supported or the 080 * MAC secret key is invalid. 081 */ 082 public static Mac getInitMac(final String alg, 083 final SecretKey secretKey, 084 final Provider provider) 085 throws JOSEException { 086 087 Mac mac; 088 try { 089 if (provider != null) { 090 mac = Mac.getInstance(alg, provider); 091 } else { 092 mac = Mac.getInstance(alg); 093 } 094 095 mac.init(secretKey); 096 097 } catch (NoSuchAlgorithmException e) { 098 throw new JOSEException("Unsupported HMAC algorithm: " + e.getMessage(), e); 099 } catch (InvalidKeyException e) { 100 throw new JOSEException("Invalid HMAC key: " + e.getMessage(), e); 101 } 102 103 return mac; 104 } 105 106 107 /** 108 * Computes a Hash-based Message Authentication Code (HMAC) for the 109 * specified secret and message. 110 * 111 * @param alg The Java Cryptography Architecture (JCA) HMAC 112 * algorithm name. Must not be {@code null}. 113 * @param secret The secret. Must not be {@code null}. 114 * @param message The message. Must not be {@code null}. 115 * @param provider The JCA provider, or {@code null} to use the default 116 * one. 117 * 118 * @return The computed HMAC. 119 * 120 * @throws JOSEException If the algorithm is not supported or the 121 * MAC secret key is invalid. 122 */ 123 @Deprecated 124 public static byte[] compute(final String alg, 125 final byte[] secret, 126 final byte[] message, 127 final Provider provider) 128 throws JOSEException { 129 130 return compute(alg, new SecretKeySpec(secret, alg), message, provider); 131 } 132 133 134 /** 135 * Computes a Hash-based Message Authentication Code (HMAC) for the 136 * specified secret key and message. 137 * 138 * @param alg The Java Cryptography Architecture (JCA) HMAC 139 * algorithm name. Must not be {@code null}. 140 * @param secretKey The secret key. Its algorithm name is ignored. 141 * Must not be {@code null}. 142 * @param message The message. Must not be {@code null}. 143 * @param provider The JCA provider, or {@code null} to use the 144 * default one. 145 * 146 * @return The computed HMAC. 147 * 148 * @throws JOSEException If the algorithm is not supported or the MAC 149 * secret key is invalid. 150 */ 151 public static byte[] compute(final String alg, 152 final SecretKey secretKey, 153 final byte[] message, 154 final Provider provider) 155 throws JOSEException { 156 157 Mac mac = getInitMac(alg, secretKey, provider); 158 mac.update(message); 159 return mac.doFinal(); 160 } 161 162 /** 163 * Computes a Hash-based Message Authentication Code (HMAC) for the 164 * specified secret key and message. 165 * 166 * @param secretKey The secret key, with the appropriate HMAC 167 * algorithm. Must not be {@code null}. 168 * @param message The message. Must not be {@code null}. 169 * @param provider The JCA provider, or {@code null} to use the 170 * default one. 171 * 172 * @return A MAC service instance. 173 * 174 * @throws JOSEException If the algorithm is not supported or the MAC 175 * secret key is invalid. 176 */ 177 public static byte[] compute(final SecretKey secretKey, 178 final byte[] message, 179 final Provider provider) 180 throws JOSEException { 181 182 return compute(secretKey.getAlgorithm(), secretKey, message, provider); 183 } 184}