That fuck shit the fascists are using
1package org.tm.archive.crypto;
2
3
4import android.util.Pair;
5
6import androidx.annotation.NonNull;
7
8import java.io.File;
9import java.io.FileOutputStream;
10import java.io.IOException;
11import java.io.OutputStream;
12import java.security.InvalidAlgorithmParameterException;
13import java.security.InvalidKeyException;
14import java.security.NoSuchAlgorithmException;
15import java.security.SecureRandom;
16
17import javax.crypto.Cipher;
18import javax.crypto.CipherOutputStream;
19import javax.crypto.Mac;
20import javax.crypto.NoSuchPaddingException;
21import javax.crypto.spec.IvParameterSpec;
22import javax.crypto.spec.SecretKeySpec;
23
24/**
25 * Constructs an OutputStream that encrypts data written to it with the AttachmentSecret provided.
26 *
27 * The on-disk format is very simple, and intentionally no longer includes authentication.
28 */
29public class ModernEncryptingPartOutputStream {
30
31 public static Pair<byte[], OutputStream> createFor(@NonNull AttachmentSecret attachmentSecret, @NonNull File file, boolean inline)
32 throws IOException
33 {
34 byte[] random = new byte[32];
35 new SecureRandom().nextBytes(random);
36
37 try {
38 Mac mac = Mac.getInstance("HmacSHA256");
39 mac.init(new SecretKeySpec(attachmentSecret.getModernKey(), "HmacSHA256"));
40
41 FileOutputStream fileOutputStream = new FileOutputStream(file);
42 byte[] iv = new byte[16];
43 byte[] key = mac.doFinal(random);
44
45 Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
46 cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES"), new IvParameterSpec(iv));
47
48 if (inline) {
49 fileOutputStream.write(random);
50 }
51
52 return new Pair<>(random, new CipherOutputStream(fileOutputStream, cipher));
53 } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException e) {
54 throw new AssertionError(e);
55 }
56 }
57
58 public static long getPlaintextLength(long cipherTextLength) {
59 return cipherTextLength - 32;
60 }
61}