package act.app.util;
/*-
* #%L
* ACT Framework
* %%
* Copyright (C) 2014 - 2017 ActFramework
* %%
* 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 act.conf.AppConfig;
import org.mindrot.jbcrypt.BCrypt;
import org.osgl.exception.UnexpectedException;
import org.osgl.logging.LogManager;
import org.osgl.logging.Logger;
import org.osgl.util.Charsets;
import org.osgl.util.Crypto;
import org.osgl.util.Token;
import java.security.InvalidKeyException;
import java.security.SecureRandom;
public class AppCrypto {
private static Logger logger = LogManager.get(AppCrypto.class);
private byte[] secret;
private SecureRandom secureRandom = new SecureRandom();
public AppCrypto(AppConfig config) {
secret = config.secret().getBytes(Charsets.UTF_8);
}
public String sign(String message) {
return Crypto.sign(message, secret);
}
/**
* Generate crypted hash of given password. This method is more secure than
* {@link #passwordHash(String)} as it will fill the password char array
* with `\0` once used.
*
* See <a href="http://stackoverflow.com/questions/8881291/why-is-char-preferred-over-string-for-passwords-in-java">This SO for more detail</a>
* @param password the password
* @return the password hash
*/
public String passwordHash(char[] password) {
return BCrypt.hashpw(password, BCrypt.gensalt());
}
/**
* Generate crypted hash of give password
* @param password the password
* @return the password hash
*/
public String passwordHash(String password) {
return BCrypt.hashpw(password, BCrypt.gensalt());
}
public boolean verifyPassword(String password, String hash) {
try {
return BCrypt.checkpw(password, hash);
} catch (Exception e) {
return false;
}
}
public boolean verifyPassword(char[] password, String hash) {
try {
return BCrypt.checkpw(password, hash);
} catch (Exception e) {
return false;
}
}
public String encrypt(String message) {
try {
return Crypto.encryptAES(message, secret);
} catch (UnexpectedException e) {
Throwable cause = e.getCause();
if (cause instanceof InvalidKeyException) {
logger.error("Cannot encrypt/decrypt! Please download Java Crypto Extension pack from Oracle: http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136007.html");
}
throw e;
}
}
public String decrypt(String message) {
try {
return Crypto.decryptAES(message, secret);
} catch (UnexpectedException e) {
Throwable cause = e.getCause();
if (cause instanceof InvalidKeyException) {
logger.error("Cannot encrypt/decrypt! Please download Java Crypto Extension pack from Oracle: http://www.oracle.com/technetwork/java/javase/tech/index-jsp-136007.html");
}
throw e;
}
}
public int generateRandomInt(int max) {
return secureRandom.nextInt(max);
}
public int generateRandomInt() {
return secureRandom.nextInt(Integer.MAX_VALUE);
}
public String generateToken(String id, String... payload) {
return Token.generateToken(secret, id, payload);
}
public String generateToken(Token.Life expiration, String id, String ... payload) {
return Token.generateToken(secret, expiration, id, payload);
}
public String generateToken(int seconds, String id, String ... payload) {
return Token.generateToken(secret, seconds, id, payload);
}
public Token parseToken(String tokenString) {
return Token.parseToken(secret, tokenString);
}
}