package org.ripple.power.wallet;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import org.ripple.bouncycastle.jce.provider.BouncyCastleProvider;
public class WalletDataVault {
public static final String CIPHER_ALGORITHM = "AES";
public static final String KEY_ALGORITHM = "AES";
public static final String PASSWORD_HASH_ALGORITHM = "SHA-256";
private File file;
private Provider provider;
public WalletDataVault(File file) {
this.file = file;
this.provider = new BouncyCastleProvider();
}
public InputStream getInputStream(char[] password)
throws NoSuchAlgorithmException, NoSuchPaddingException,
FileNotFoundException, InvalidKeyException,
UnsupportedEncodingException {
Cipher cipher = buildCipher(password, Cipher.DECRYPT_MODE);
return new CipherInputStream(new FileInputStream(file), cipher);
}
public OutputStream getOutputStream(char[] password)
throws NoSuchAlgorithmException, NoSuchPaddingException,
FileNotFoundException, InvalidKeyException,
UnsupportedEncodingException {
Cipher cipher = buildCipher(password, Cipher.ENCRYPT_MODE);
return new CipherOutputStream(new FileOutputStream(file), cipher);
}
private Cipher buildCipher(char[] password, int mode)
throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, UnsupportedEncodingException {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, provider);
Key key = buildKey(password);
cipher.init(mode, key);
return cipher;
}
private Key buildKey(char[] password) throws NoSuchAlgorithmException,
UnsupportedEncodingException {
MessageDigest digester = MessageDigest.getInstance(
PASSWORD_HASH_ALGORITHM, provider);
digester.update(String.valueOf(password).getBytes("UTF-8"));
byte[] key = digester.digest();
SecretKeySpec spec = new SecretKeySpec(key, KEY_ALGORITHM);
return spec;
}
}