package org.cnodejs.android.md.util;
import android.support.annotation.NonNull;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public final class Crypto {
public static final Crypto AES = new Crypto("AES", 16, 16);
private final String algorithm;
private final int secretLength;
private final int ivLength;
private Crypto(@NonNull String algorithm, int secretLength, int ivLength) {
this.algorithm = algorithm;
this.secretLength = secretLength;
this.ivLength = ivLength;
}
public SecretKey generateSecret(@NonNull byte[] seed) {
return new SecretKeySpec(Arrays.copyOf(seed, secretLength), algorithm);
}
public IvParameterSpec generateIv(@NonNull byte[] seed) {
return new IvParameterSpec(Arrays.copyOf(seed, ivLength));
}
public byte[] encrypt(@NonNull SecretKey secret, @NonNull IvParameterSpec iv, @NonNull byte[] data) throws CryptoException {
try {
Cipher cipher = Cipher.getInstance(algorithm + "/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret, iv);
return cipher.doFinal(data);
} catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
throw new CryptoException("Encrypt error.", e);
}
}
public byte[] decrypt(@NonNull SecretKey secret, @NonNull IvParameterSpec iv, @NonNull byte[] data) throws CryptoException {
try {
Cipher cipher = Cipher.getInstance(algorithm + "/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, iv);
return cipher.doFinal(data);
} catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException e) {
throw new CryptoException("Decrypt error.", e);
}
}
public static class CryptoException extends Exception {
private CryptoException(String message, Throwable cause) {
super(message, cause);
}
}
}