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

com.nimbusds.openid.connect.sdk.id.SIVAESBasedPairwiseSubjectCodec Maven / Gradle / Ivy

Go to download

OAuth 2.0 SDK with OpenID Connection extensions for developing client and server applications.

There is a newer version: 11.19.1
Show newest version
/*
 * oauth2-oidc-sdk
 *
 * Copyright 2012-2016, Connect2id Ltd and contributors.
 *
 * 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.nimbusds.openid.connect.sdk.id;


import java.util.AbstractMap;
import java.util.Map;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

import com.nimbusds.jose.util.Base64URL;
import com.nimbusds.jose.util.ByteUtils;
import com.nimbusds.oauth2.sdk.id.Subject;
import net.jcip.annotations.ThreadSafe;
import org.cryptomator.siv.SivMode;


/**
 * SIV AES - based encoder / decoder of pairwise subject identifiers. Requires
 * a 256, 384, or 512-bit secret key. Reversal is supported.
 *
 * 

The plain text is formatted as follows ('|' as delimiter): * *

 * sector_id|local_sub
 * 
* *

Related specifications: * *

    *
  • Synthetic Initialization Vector (SIV) Authenticated Encryption Using * the Advanced Encryption Standard (AES) (RFC 5297). *
  • OpenID Connect Core 1.0, section 8.1. *
*/ @ThreadSafe public class SIVAESBasedPairwiseSubjectCodec extends PairwiseSubjectCodec { /** * The AES SIV crypto engine. */ private static final SivMode AES_SIV = new SivMode(); /** * The AES CTR key (1st half). */ private final byte[] aesCtrKey; /** * The MAC key (2nd half). */ private final byte[] macKey; /** * Creates a new SIV AES - based codec for pairwise subject * identifiers. * * @param secretKey A 256, 384, or 512-bit secret key. Must not be * {@code null}. */ public SIVAESBasedPairwiseSubjectCodec(final SecretKey secretKey) { super(null); if (secretKey == null) { throw new IllegalArgumentException("The SIV AES secret key must not be null"); } byte[] keyBytes = secretKey.getEncoded(); switch (keyBytes.length) { case 32: aesCtrKey = ByteUtils.subArray(keyBytes, 0, 16); macKey = ByteUtils.subArray(keyBytes, 16, 16); break; case 48: aesCtrKey = ByteUtils.subArray(keyBytes, 0, 24); macKey = ByteUtils.subArray(keyBytes, 24, 24); break; case 64: aesCtrKey = ByteUtils.subArray(keyBytes, 0, 32); macKey = ByteUtils.subArray(keyBytes, 32, 32); break; default: throw new IllegalArgumentException("The SIV AES secret key length must be 256, 384 or 512 bits"); } } /** * Returns the secret key. * * @return The key. */ public SecretKey getSecretKey() { return new SecretKeySpec(ByteUtils.concat(aesCtrKey, macKey), "AES"); } @Override public Subject encode(final SectorID sectorID, final Subject localSub) { // Join parameters, delimited by '\' byte[] plainText = (sectorID.getValue().replace("|", "\\|") + '|' + localSub.getValue().replace("|", "\\|")).getBytes(CHARSET); byte[] cipherText = AES_SIV.encrypt(aesCtrKey, macKey, plainText); return new Subject(Base64URL.encode(cipherText).toString()); } @Override public Map.Entry decode(final Subject pairwiseSubject) throws InvalidPairwiseSubjectException { byte[] cipherText = new Base64URL(pairwiseSubject.getValue()).decode(); byte[] plainText; try { plainText = AES_SIV.decrypt(aesCtrKey, macKey, cipherText); } catch (Exception e) { throw new InvalidPairwiseSubjectException("Decryption failed: " + e.getMessage(), e); } String[] parts = new String(plainText, CHARSET).split("(?(new SectorID(parts[0]), new Subject(parts[1])); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy