com.azaptree.services.security.domain.config.impl.HashServiceConfig.java Source code

Java tutorial

Introduction

Here is the source code for com.azaptree.services.security.domain.config.impl.HashServiceConfig.java

Source

package com.azaptree.services.security.domain.config.impl;

/*
 * #%L
 * AZAPTREE SECURITY SERVICE
 * %%
 * Copyright (C) 2012 - 2013 AZAPTREE.COM
 * %%
 * 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.
 * #L%
 */

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Objects;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.DefaultHashService;
import org.apache.shiro.crypto.hash.HashService;
import org.apache.shiro.util.ByteSource;
import org.springframework.util.Assert;

import com.azaptree.services.domain.entity.impl.DomainEntity;
import com.azaptree.services.security.domain.config.HashServiceConfiguration;

public class HashServiceConfig extends DomainEntity implements HashServiceConfiguration {
    private final String name;

    private final byte[] privateSalt;

    private final int hashIterations;

    private final String hashAlgorithmName;

    private final int secureRandomNumberGeneratorNextBytesSize;

    private transient HashService hashService;

    public HashServiceConfig(final HashServiceConfiguration config) {
        super(config);
        name = config.getName();
        privateSalt = config.getPrivateSalt();
        hashIterations = config.getHashIterations();
        hashAlgorithmName = config.getHashAlgorithmName();
        secureRandomNumberGeneratorNextBytesSize = config.getSecureRandomNumberGeneratorNextBytesSize();
        validate();
    }

    public HashServiceConfig(final String name) {
        Assert.hasText(name, "name is required");
        this.name = name;
        hashAlgorithmName = "SHA-256";
        final SecureRandomNumberGenerator rng = new SecureRandomNumberGenerator();
        privateSalt = rng.nextBytes(32).getBytes();
        hashIterations = 1024 * 128;
        secureRandomNumberGeneratorNextBytesSize = 32;
        validate();
    }

    public HashServiceConfig(final String name, final byte[] privateSalt, final int hashIterations,
            final String hashAlgorithmName, final int secureRandomNumberGeneratorNextBytesSize) {
        this.name = name;
        this.privateSalt = privateSalt;
        this.hashIterations = hashIterations;
        this.hashAlgorithmName = hashAlgorithmName;
        this.secureRandomNumberGeneratorNextBytesSize = secureRandomNumberGeneratorNextBytesSize;
        validate();
    }

    @Override
    public HashService getHashService() {
        if (hashService != null) {
            return hashService;
        }
        final DefaultHashService service = new DefaultHashService();
        service.setGeneratePublicSalt(true);
        service.setPrivateSalt(ByteSource.Util.bytes(privateSalt));
        service.setHashAlgorithmName(hashAlgorithmName);
        service.setHashIterations(hashIterations);

        final SecureRandomNumberGenerator rng = new SecureRandomNumberGenerator();
        rng.setDefaultNextBytesSize(secureRandomNumberGeneratorNextBytesSize);
        final SecureRandom random = new SecureRandom();
        final byte rngSeed[] = new byte[20];
        random.nextBytes(rngSeed);
        rng.setSeed(rngSeed);

        service.setRandomNumberGenerator(rng);
        hashService = service;
        return service;
    }

    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (!super.equals(obj)) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final HashServiceConfig other = (HashServiceConfig) obj;
        return Objects.equals(name, other.name) && Objects.equals(hashIterations, other.hashIterations)
                && Objects.equals(hashAlgorithmName, other.hashAlgorithmName)
                && Objects.equals(secureRandomNumberGeneratorNextBytesSize,
                        other.secureRandomNumberGeneratorNextBytesSize)
                && ArrayUtils.isEquals(privateSalt, other.privateSalt);
    }

    @Override
    public String getHashAlgorithmName() {
        return hashAlgorithmName;
    }

    @Override
    public int getHashIterations() {
        return hashIterations;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public byte[] getPrivateSalt() {
        return privateSalt;
    }

    @Override
    public int getSecureRandomNumberGeneratorNextBytesSize() {
        return secureRandomNumberGeneratorNextBytesSize;
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this, ToStringStyle.MULTI_LINE_STYLE).append("name", name)
                .append("hashAlgorithmName", hashAlgorithmName).toString();
    }

    private void validate() {
        Assert.hasText(name, "name is required");
        Assert.isTrue(ArrayUtils.isNotEmpty(privateSalt), "privateSalt is required");
        Assert.hasText(hashAlgorithmName, "hashAlgorithmName is required");
        try {
            MessageDigest.getInstance(hashAlgorithmName);
        } catch (final NoSuchAlgorithmException e) {
            throw new IllegalArgumentException("Unknown algorithm : " + hashAlgorithmName, e);
        }
        Assert.isTrue(hashIterations > 0, "contraint failed: hashIterations > 0");
        Assert.isTrue(secureRandomNumberGeneratorNextBytesSize > 1,
                "contraint failed: secureRandomNumberGeneratorNextBytesSize > 1");
    }

}