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.util.Collections; 022import java.util.LinkedHashSet; 023import java.util.Set; 024import javax.crypto.SecretKey; 025import javax.crypto.spec.SecretKeySpec; 026 027import com.nimbusds.jose.JOSEException; 028import com.nimbusds.jose.JWSAlgorithm; 029import com.nimbusds.jose.KeyLengthException; 030import com.nimbusds.jose.util.StandardCharset; 031 032 033/** 034 * The base abstract class for Message Authentication Code (MAC) signers and 035 * verifiers of {@link com.nimbusds.jose.JWSObject JWS objects}. 036 * 037 * <p>Supports the following algorithms: 038 * 039 * <ul> 040 * <li>{@link com.nimbusds.jose.JWSAlgorithm#HS256} 041 * <li>{@link com.nimbusds.jose.JWSAlgorithm#HS384} 042 * <li>{@link com.nimbusds.jose.JWSAlgorithm#HS512} 043 * </ul> 044 * 045 * @author Vladimir Dzhuvinov 046 * @version 2016-07-27 047 */ 048public abstract class MACProvider extends BaseJWSProvider { 049 050 051 /** 052 * The supported JWS algorithms by the MAC provider class. 053 */ 054 public static final Set<JWSAlgorithm> SUPPORTED_ALGORITHMS; 055 056 057 static { 058 Set<JWSAlgorithm> algs = new LinkedHashSet<>(); 059 algs.add(JWSAlgorithm.HS256); 060 algs.add(JWSAlgorithm.HS384); 061 algs.add(JWSAlgorithm.HS512); 062 SUPPORTED_ALGORITHMS = Collections.unmodifiableSet(algs); 063 } 064 065 066 /** 067 * Gets the matching Java Cryptography Architecture (JCA) algorithm 068 * name for the specified HMAC-based JSON Web Algorithm (JWA). 069 * 070 * @param alg The JSON Web Algorithm (JWA). Must be supported and not 071 * {@code null}. 072 * 073 * @return The matching JCA algorithm name. 074 * 075 * @throws JOSEException If the algorithm is not supported. 076 */ 077 protected static String getJCAAlgorithmName(final JWSAlgorithm alg) 078 throws JOSEException { 079 080 if (alg.equals(JWSAlgorithm.HS256)) { 081 return "HMACSHA256"; 082 } else if (alg.equals(JWSAlgorithm.HS384)) { 083 return "HMACSHA384"; 084 } else if (alg.equals(JWSAlgorithm.HS512)) { 085 return "HMACSHA512"; 086 } else { 087 throw new JOSEException(AlgorithmSupportMessage.unsupportedJWSAlgorithm( 088 alg, 089 SUPPORTED_ALGORITHMS)); 090 } 091 } 092 093 094 /** 095 * The secret. 096 */ 097 private final byte[] secret; 098 099 100 /** 101 * Creates a new Message Authentication (MAC) provider. 102 * 103 * @param secret The secret. Must be at least 256 bits long and 104 * not {@code null}. 105 * @param supportedAlgs The supported HMAC algorithms. Must not be 106 * {@code null}. 107 * 108 * @throws KeyLengthException If the secret length is shorter than the 109 * minimum 256-bit requirement. 110 */ 111 protected MACProvider(final byte[] secret, 112 final Set<JWSAlgorithm> supportedAlgs) 113 throws KeyLengthException { 114 115 super(supportedAlgs); 116 117 if (secret.length < 256 / 8) { 118 throw new KeyLengthException("The secret length must be at least 256 bits"); 119 } 120 121 this.secret = secret; 122 } 123 124 125 /** 126 * Gets the secret key. 127 * 128 * @return The secret key. 129 */ 130 public SecretKey getSecretKey() { 131 132 return new SecretKeySpec(secret, "MAC"); 133 } 134 135 136 /** 137 * Gets the secret bytes. 138 * 139 * @return The secret bytes. 140 */ 141 public byte[] getSecret() { 142 143 return secret; 144 } 145 146 147 /** 148 * Gets the secret as a UTF-8 encoded string. 149 * 150 * @return The secret as a UTF-8 encoded string. 151 */ 152 public String getSecretString() { 153 154 return new String(secret, StandardCharset.UTF_8); 155 } 156}