Skip to content

Instantly share code, notes, and snippets.

@ForceTower
Last active July 31, 2020 18:56
Show Gist options
  • Save ForceTower/e610f1d7e18d3bd2bb4a0ae8fc2d78c1 to your computer and use it in GitHub Desktop.
Save ForceTower/e610f1d7e18d3bd2bb4a0ae8fc2d78c1 to your computer and use it in GitHub Desktop.
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.ByteBuffer;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public final class AesFlushingCipher {
private final Cipher cipher;
private int pendingXorBytes;
public AesFlushingCipher(int mode, byte[] secretKey, long nonce, long offset) {
try {
cipher = Cipher.getInstance("AES/CTR/NoPadding");
int blockSize = cipher.getBlockSize();
long counter = offset / blockSize;
int startPadding = (int) (offset % blockSize);
SecretKeySpec aes = new SecretKeySpec(secretKey, "AES");
cipher.init(
mode,
aes,
new IvParameterSpec(getInitializationVector(nonce, counter)));
if (startPadding != 0) {
updateInPlace(new byte[startPadding], 0, startPadding);
}
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
| InvalidAlgorithmParameterException e) {
throw new RuntimeException(e);
}
}
public void updateInPlace(byte[] data, int offset, int length) {
update(data, offset, length, data, offset);
}
public void update(byte[] in, int inOffset, int length, byte[] out, int outOffset) {
// Do the bulk of the update.
nonFlushingUpdate(in, inOffset, length, out, outOffset);
}
private void nonFlushingUpdate(byte[] in, int inOffset, int length, byte[] out, int outOffset) {
try {
cipher.update(in, inOffset, length, out, outOffset);
} catch (ShortBufferException e) {
// Should never happen.
throw new RuntimeException(e);
}
}
private byte[] getInitializationVector(long nonce, long counter) {
return ByteBuffer.allocate(16).putLong(nonce).putLong(counter).array();
}
}
import java.io.*;
import java.nio.charset.StandardCharsets;
import javax.crypto.Cipher;
public class CryptoUtils {
public static void element(File in, File out, String secret) throws IOException {
FileInputStream read = new FileInputStream(in);
FileOutputStream write = new FileOutputStream(out);
byte[] bytes = toByteArray(read);
read.close();
AesFlushingCipher cipher = new AesFlushingCipher(Cipher.ENCRYPT_MODE, getUtf8Bytes(secret), 0, 0);
cipher.updateInPlace(bytes, 0, bytes.length);
write.write(bytes, 0, bytes.length);
}
public static void main(String[] args) throws IOException {
File input = new File("C:\\Users\\joaop\\Documents\\Development\\Projects\\ExoTester\\app\\src\\main\\assets\\lion.mp4");
File output = new File("C:\\Users\\joaop\\Documents\\Development\\Projects\\ExoTester\\app\\src\\main\\assets\\lion_cipher2");
output.createNewFile();
element(input, output, "a_really_strong_password");
}
public static long getFNV64Hash(String input) {
if (input == null) {
return 0;
}
long hash = 0;
for (int i = 0; i < input.length(); i++) {
hash ^= input.charAt(i);
// This is equivalent to hash *= 0x100000001b3 (the FNV magic prime number).
hash += (hash << 1) + (hash << 4) + (hash << 5) + (hash << 7) + (hash << 8) + (hash << 40);
}
return hash;
}
public static byte[] getUtf8Bytes(String value) {
return value.getBytes(StandardCharsets.UTF_8);
}
public static byte[] toByteArray(InputStream inputStream) throws IOException {
byte[] buffer = new byte[1024 * 4];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
return outputStream.toByteArray();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment