001package com.nimbusds.openid.connect.sdk.id; 002 003 004import java.security.MessageDigest; 005import java.security.NoSuchAlgorithmException; 006 007import com.nimbusds.jose.util.Base64URL; 008import com.nimbusds.oauth2.sdk.id.Subject; 009import net.jcip.annotations.ThreadSafe; 010 011 012/** 013 * SHA-256 based encoder of pairwise subject identifiers. Reversal is not 014 * supported. 015 * 016 * <p>Algorithm: 017 * 018 * <pre> 019 * sub = SHA-256 ( sector_id || local_sub || salt ) 020 * </pre> 021 * 022 * <p>Related specifications: 023 * 024 * <ul> 025 * <li>OpenID Connect Core 1.0, section 8.1. 026 * </ul> 027 */ 028@ThreadSafe 029public class HashBasedPairwiseSubjectCodec extends PairwiseSubjectCodec { 030 031 032 /** 033 * The hashing algorithm. 034 */ 035 public static final String HASH_ALGORITHM = "SHA-256"; 036 037 038 /** 039 * Creates a new hash-based codec for pairwise subject identifiers. 040 * 041 * @param salt The salt, must not be {@code null}. 042 */ 043 public HashBasedPairwiseSubjectCodec(final byte[] salt) { 044 super(salt); 045 if (salt == null) { 046 throw new IllegalArgumentException("The salt must not be null"); 047 } 048 } 049 050 051 /** 052 * Creates a new hash-based codec for pairwise subject identifiers. 053 * 054 * @param salt The salt, must not be {@code null}. 055 */ 056 public HashBasedPairwiseSubjectCodec(final Base64URL salt) { 057 super(salt.decode()); 058 } 059 060 061 @Override 062 public Subject encode(final SectorID sectorID, final Subject localSub) { 063 064 MessageDigest sha256; 065 try { 066 if (getProvider() != null) { 067 sha256 = MessageDigest.getInstance(HASH_ALGORITHM, getProvider()); 068 } else { 069 sha256 = MessageDigest.getInstance(HASH_ALGORITHM); 070 } 071 } catch (NoSuchAlgorithmException e) { 072 throw new RuntimeException(e.getMessage(), e); 073 } 074 075 sha256.update(sectorID.getValue().getBytes(CHARSET)); 076 sha256.update(localSub.getValue().getBytes(CHARSET)); 077 byte[] hash = sha256.digest(getSalt()); 078 079 return new Subject(Base64URL.encode(hash).toString()); 080 } 081}