org.jose4j.jwk.JsonWebKey Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jose4j Show documentation
Show all versions of jose4j Show documentation
The jose.4.j library is a robust and easy to use open source implementation of JSON Web Token (JWT) and the JOSE specification suite (JWS, JWE, and JWK).
It is written in Java and relies solely on the JCA APIs for cryptography.
Please see https://bitbucket.org/b_c/jose4j/wiki/Home for more info, examples, etc..
/*
* Copyright 2012-2017 Brian Campbell
*
* 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 org.jose4j.jwk;
import org.jose4j.base64url.Base64Url;
import org.jose4j.json.JsonUtil;
import org.jose4j.lang.HashUtil;
import org.jose4j.lang.JoseException;
import org.jose4j.lang.JsonHelp;
import org.jose4j.lang.StringUtil;
import java.io.Serializable;
import java.security.Key;
import java.security.MessageDigest;
import java.security.PublicKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
*/
public abstract class JsonWebKey implements Serializable
{
public enum OutputControlLevel {INCLUDE_PRIVATE, INCLUDE_SYMMETRIC, PUBLIC_ONLY}
public static final String KEY_TYPE_PARAMETER = "kty";
public static final String USE_PARAMETER = "use";
public static final String KEY_ID_PARAMETER = "kid";
public static final String ALGORITHM_PARAMETER = "alg";
public static final String KEY_OPERATIONS = "key_ops";
private String use;
private String keyId;
private String algorithm;
private List keyOps;
protected Map otherParameters = new LinkedHashMap<>();
protected Key key;
protected JsonWebKey(Key key)
{
this.key = key;
}
protected JsonWebKey(Map params) throws JoseException
{
otherParameters.putAll(params);
removeFromOtherParams(KEY_TYPE_PARAMETER, USE_PARAMETER, KEY_ID_PARAMETER, ALGORITHM_PARAMETER, KEY_OPERATIONS);
setUse(getString(params, USE_PARAMETER));
setKeyId(getString(params, KEY_ID_PARAMETER));
setAlgorithm(getString(params, ALGORITHM_PARAMETER));
if (params.containsKey(KEY_OPERATIONS))
{
keyOps = JsonHelp.getStringArray(params, KEY_OPERATIONS);
}
}
public abstract String getKeyType();
protected abstract void fillTypeSpecificParams(Map params, OutputControlLevel outputLevel);
/**
* @deprecated deprecated in favor {@link #getKey()} or {@link PublicJsonWebKey#getPublicKey()}
*/
public PublicKey getPublicKey()
{
try
{
return (PublicKey) key;
}
catch (Exception e)
{
return null;
}
}
public Key getKey()
{
return key;
}
public String getUse()
{
return use;
}
public void setUse(String use)
{
this.use = use;
}
public String getKeyId()
{
return keyId;
}
public void setKeyId(String keyId)
{
this.keyId = keyId;
}
public String getAlgorithm()
{
return algorithm;
}
public void setAlgorithm(String algorithm)
{
this.algorithm = algorithm;
}
public List getKeyOps()
{
return keyOps;
}
public void setKeyOps(List keyOps)
{
this.keyOps = keyOps;
}
public void setOtherParameter(String name, Object value)
{
otherParameters.put(name, value);
}
public T getOtherParameterValue(String name, Class type)
{
Object o = otherParameters.get(name);
return type.cast(o);
}
protected void removeFromOtherParams(String... names)
{
for (String name : names)
{
otherParameters.remove(name);
}
}
public Map toParams(OutputControlLevel outputLevel)
{
Map params = new LinkedHashMap();
params.put(KEY_TYPE_PARAMETER, getKeyType());
putIfNotNull(KEY_ID_PARAMETER, getKeyId(), params);
putIfNotNull(USE_PARAMETER, getUse(), params);
putIfNotNull(KEY_OPERATIONS, keyOps, params);
putIfNotNull(ALGORITHM_PARAMETER, getAlgorithm(), params);
fillTypeSpecificParams(params, outputLevel);
params.putAll(otherParameters);
return params;
}
public String toJson()
{
return toJson(OutputControlLevel.INCLUDE_SYMMETRIC);
}
public String toJson(OutputControlLevel outputLevel)
{
Map params = toParams(outputLevel);
return JsonUtil.toJson(params);
}
@Override
public String toString()
{
return getClass().getName() + toParams(OutputControlLevel.PUBLIC_ONLY);
}
public String calculateBase64urlEncodedThumbprint(String hashAlgorithm)
{
byte[] thumbprint = calculateThumbprint(hashAlgorithm);
return Base64Url.encode(thumbprint);
}
public byte[] calculateThumbprint(String hashAlgorithm)
{
MessageDigest digest = HashUtil.getMessageDigest(hashAlgorithm);
String hashInputString = produceThumbprintHashInput();
byte[] hashInputBytes = StringUtil.getBytesUtf8(hashInputString);
return digest.digest(hashInputBytes);
}
protected abstract String produceThumbprintHashInput();
protected void putIfNotNull(String name, Object value, Map params)
{
if (value != null)
{
params.put(name,value);
}
}
protected static String getString(Map params, String name) throws JoseException
{
return JsonHelp.getStringChecked(params, name);
}
protected static String getStringRequired(Map params, String name) throws JoseException
{
return getString(params, name, true);
}
protected static String getString(Map params, String name, boolean required) throws JoseException
{
String value = getString(params, name);
if (value == null && required)
{
throw new JoseException("Missing required '" + name + "' parameter.");
}
return value;
}
public static class Factory
{
public static JsonWebKey newJwk(Map params) throws JoseException
{
String kty = getStringRequired(params, KEY_TYPE_PARAMETER);
switch (kty)
{
case RsaJsonWebKey.KEY_TYPE:
return new RsaJsonWebKey(params);
case EllipticCurveJsonWebKey.KEY_TYPE:
return new EllipticCurveJsonWebKey(params);
case OctetSequenceJsonWebKey.KEY_TYPE:
return new OctetSequenceJsonWebKey(params);
default:
throw new JoseException("Unknown key type algorithm: '" + kty + "'");
}
}
public static JsonWebKey newJwk(Key key) throws JoseException
{
if (RSAPublicKey.class.isInstance(key))
{
return new RsaJsonWebKey((RSAPublicKey)key);
}
else if (ECPublicKey.class.isInstance(key))
{
return new EllipticCurveJsonWebKey((ECPublicKey)key);
}
else if (PublicKey.class.isInstance(key))
{
throw new JoseException("Unsupported or unknown public key " + key);
}
else
{
return new OctetSequenceJsonWebKey(key);
}
}
public static JsonWebKey newJwk(String json) throws JoseException
{
Map parsed = JsonUtil.parseJson(json);
return newJwk(parsed);
}
}
}