/** * Register this file system. */ public static void register() { FilePath.register(new FilePathEncrypt()); }
@Override public long size() { long size = getBase().size() - FileEncrypt.HEADER_LENGTH; size = Math.max(0, size); if ((size & FileEncrypt.BLOCK_SIZE_MASK) != 0) { size -= FileEncrypt.BLOCK_SIZE; } return size; }
@Override public FilePath unwrap(String fileName) { return FilePath.get(parse(fileName)[1]); }
@Override public InputStream newInputStream() throws IOException { return new FileChannelInputStream(open("r"), true); }
/** * Split the password property into file password and user password if * necessary, and convert them to the internal hash format. */ private void convertPasswords() { char[] password = removePassword(); boolean passwordHash = removeProperty("PASSWORD_HASH", false); if (getProperty("CIPHER", null) != null) { // split password into (filePassword+' '+userPassword) int space = -1; for (int i = 0, len = password.length; i < len; i++) { if (password[i] == ' ') { space = i; break; } } if (space < 0) { throw DbException.get(ErrorCode.WRONG_PASSWORD_FORMAT); } char[] np = new char[password.length - space - 1]; char[] filePassword = new char[space]; System.arraycopy(password, space + 1, np, 0, np.length); System.arraycopy(password, 0, filePassword, 0, space); Arrays.fill(password, (char) 0); password = np; fileEncryptionKey = FilePathEncrypt.getPasswordBytes(filePassword); filePasswordHash = hashPassword(passwordHash, "file", filePassword); } userPasswordHash = hashPassword(passwordHash, user, password); }
/** * Split the file name into algorithm, password, and base file name. * * @param fileName the file name * @return an array with algorithm, password, and base file name */ private String[] parse(String fileName) { if (!fileName.startsWith(getScheme())) { throw new IllegalArgumentException(fileName + " doesn't start with " + getScheme()); } fileName = fileName.substring(getScheme().length() + 1); int idx = fileName.indexOf(':'); String password; if (idx < 0) { throw new IllegalArgumentException(fileName + " doesn't contain encryption algorithm and password"); } password = fileName.substring(0, idx); fileName = fileName.substring(idx + 1); return new String[] { password, fileName }; }
@Override public FileChannel open(String mode) throws IOException { String[] parsed = parse(name); FileChannel file = FileUtils.open(parsed[1], mode); byte[] passwordBytes = parsed[0].getBytes(Constants.UTF8); return new FileEncrypt(name, passwordBytes, file); }
@Override public OutputStream newOutputStream(boolean append) throws IOException { return new FileChannelOutputStream(open("rw"), append); }
file = f.open(readOnly ? "r" : "rw"); if (encryptionKey != null) { byte[] key = FilePathEncrypt.getPasswordBytes(encryptionKey); encryptedFile = file; file = new FilePathEncrypt.FileEncrypt(fileName, key, file);