mirror of
https://gitlab.futo.org/videostreaming/grayjay.git
synced 2025-05-13 12:57:17 +02:00
Merge branch 'encryption-provider-split' into 'master'
Encryption provider split. See merge request videostreaming/grayjay!2
This commit is contained in:
commit
00e40e8cd6
@ -36,23 +36,6 @@ class EncryptionProviderTests {
|
|||||||
assertArrayEquals(bytes, decrypted);
|
assertArrayEquals(bytes, decrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
fun testEncryptDecryptBytesPassword() {
|
|
||||||
val encryptionProvider = EncryptionProvider.instance
|
|
||||||
val bytes = "This is a test string.".toByteArray();
|
|
||||||
val password = "1234".padStart(32, '9');
|
|
||||||
|
|
||||||
// Encrypt the plaintext
|
|
||||||
val ciphertext = encryptionProvider.encrypt(bytes, password)
|
|
||||||
|
|
||||||
// Decrypt the ciphertext
|
|
||||||
val decrypted = encryptionProvider.decrypt(ciphertext, password)
|
|
||||||
|
|
||||||
// The decrypted string should be equal to the original plaintext
|
|
||||||
assertArrayEquals(bytes, decrypted);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun assertArrayEquals(a: ByteArray, b: ByteArray) {
|
private fun assertArrayEquals(a: ByteArray, b: ByteArray) {
|
||||||
assertEquals(a.size, b.size);
|
assertEquals(a.size, b.size);
|
||||||
for(i in 0 until a.size) {
|
for(i in 0 until a.size) {
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.futo.platformplayer
|
||||||
|
|
||||||
|
import com.futo.platformplayer.encryption.EncryptionProvider
|
||||||
|
import com.futo.platformplayer.encryption.PasswordEncryptionProvider
|
||||||
|
import junit.framework.TestCase.assertEquals
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class PasswordEncryptionProviderTests {
|
||||||
|
@Test
|
||||||
|
fun testEncryptDecryptBytesPassword() {
|
||||||
|
val password = "1234".padStart(32, '9');
|
||||||
|
val encryptionProvider = PasswordEncryptionProvider(password);
|
||||||
|
val bytes = "This is a test string.".toByteArray();
|
||||||
|
|
||||||
|
// Encrypt the plaintext
|
||||||
|
val ciphertext = encryptionProvider.encrypt(bytes)
|
||||||
|
|
||||||
|
// Decrypt the ciphertext
|
||||||
|
val decrypted = encryptionProvider.decrypt(ciphertext)
|
||||||
|
|
||||||
|
// The decrypted string should be equal to the original plaintext
|
||||||
|
assertArrayEquals(bytes, decrypted);
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun assertArrayEquals(a: ByteArray, b: ByteArray) {
|
||||||
|
assertEquals(a.size, b.size);
|
||||||
|
for(i in 0 until a.size) {
|
||||||
|
assertEquals(a[i], b[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package com.futo.platformplayer.encryption
|
|||||||
import android.security.keystore.KeyGenParameterSpec
|
import android.security.keystore.KeyGenParameterSpec
|
||||||
import android.security.keystore.KeyProperties
|
import android.security.keystore.KeyProperties
|
||||||
import android.util.Base64
|
import android.util.Base64
|
||||||
|
import com.futo.polycentric.core.EncryptionProvider
|
||||||
import java.security.Key
|
import java.security.Key
|
||||||
import java.security.KeyStore
|
import java.security.KeyStore
|
||||||
import javax.crypto.Cipher
|
import javax.crypto.Cipher
|
||||||
@ -25,35 +26,32 @@ class EncryptionProvider {
|
|||||||
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
|
.setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
|
||||||
.setRandomizedEncryptionRequired(false)
|
.setRandomizedEncryptionRequired(false)
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
keyGenerator.generateKey();
|
keyGenerator.generateKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun encrypt(decrypted: String, password: String? = null): String {
|
fun encrypt(decrypted: String): String {
|
||||||
val encodedBytes = encrypt(decrypted.toByteArray(), password);
|
val encodedBytes = encrypt(decrypted.toByteArray());
|
||||||
val encrypted = Base64.encodeToString(encodedBytes, Base64.DEFAULT);
|
val encrypted = Base64.encodeToString(encodedBytes, Base64.DEFAULT);
|
||||||
return encrypted;
|
return encrypted;
|
||||||
}
|
}
|
||||||
fun encrypt(decrypted: ByteArray, password: String? = null): ByteArray {
|
fun encrypt(decrypted: ByteArray): ByteArray {
|
||||||
val c: Cipher = Cipher.getInstance(AES_MODE);
|
val c: Cipher = Cipher.getInstance(AES_MODE);
|
||||||
val keyToUse = if(password == null) secretKey else SecretKeySpec(password.toByteArray(), "AES");
|
c.init(Cipher.ENCRYPT_MODE, secretKey, GCMParameterSpec(128, FIXED_IV));
|
||||||
c.init(Cipher.ENCRYPT_MODE, keyToUse, GCMParameterSpec(128, FIXED_IV));
|
|
||||||
val encodedBytes: ByteArray = c.doFinal(decrypted);
|
val encodedBytes: ByteArray = c.doFinal(decrypted);
|
||||||
return encodedBytes;
|
return encodedBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
fun decrypt(encrypted: String, password: String? = null): String {
|
fun decrypt(encrypted: String): String {
|
||||||
val c = Cipher.getInstance(AES_MODE);
|
val c = Cipher.getInstance(AES_MODE);
|
||||||
val keyToUse = if(password == null) secretKey else SecretKeySpec(password.toByteArray(), "AES");
|
c.init(Cipher.DECRYPT_MODE, secretKey, GCMParameterSpec(128, FIXED_IV));
|
||||||
c.init(Cipher.DECRYPT_MODE, keyToUse, GCMParameterSpec(128, FIXED_IV));
|
|
||||||
val decrypted = String(c.doFinal(Base64.decode(encrypted, Base64.DEFAULT)));
|
val decrypted = String(c.doFinal(Base64.decode(encrypted, Base64.DEFAULT)));
|
||||||
return decrypted;
|
return decrypted;
|
||||||
}
|
}
|
||||||
fun decrypt(encrypted: ByteArray, password: String? = null): ByteArray {
|
fun decrypt(encrypted: ByteArray): ByteArray {
|
||||||
val c = Cipher.getInstance(AES_MODE);
|
val c = Cipher.getInstance(AES_MODE);
|
||||||
val keyToUse = if(password == null) secretKey else SecretKeySpec(password.toByteArray(), "AES");
|
c.init(Cipher.DECRYPT_MODE, secretKey, GCMParameterSpec(128, FIXED_IV));
|
||||||
c.init(Cipher.DECRYPT_MODE, keyToUse, GCMParameterSpec(128, FIXED_IV));
|
|
||||||
return c.doFinal(encrypted);
|
return c.doFinal(encrypted);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
package com.futo.platformplayer.encryption
|
||||||
|
|
||||||
|
import android.util.Base64
|
||||||
|
import javax.crypto.Cipher
|
||||||
|
import javax.crypto.spec.GCMParameterSpec
|
||||||
|
import javax.crypto.spec.SecretKeySpec
|
||||||
|
|
||||||
|
class PasswordEncryptionProvider {
|
||||||
|
private val _key: SecretKeySpec;
|
||||||
|
|
||||||
|
constructor(password: String) {
|
||||||
|
_key = SecretKeySpec(password.toByteArray(), "AES");
|
||||||
|
}
|
||||||
|
|
||||||
|
fun encrypt(decrypted: String): String {
|
||||||
|
val encodedBytes = encrypt(decrypted.toByteArray());
|
||||||
|
val encrypted = Base64.encodeToString(encodedBytes, Base64.DEFAULT);
|
||||||
|
return encrypted;
|
||||||
|
}
|
||||||
|
fun encrypt(decrypted: ByteArray): ByteArray {
|
||||||
|
val c: Cipher = Cipher.getInstance(AES_MODE);
|
||||||
|
c.init(Cipher.ENCRYPT_MODE, _key, GCMParameterSpec(128, FIXED_IV));
|
||||||
|
val encodedBytes: ByteArray = c.doFinal(decrypted);
|
||||||
|
return encodedBytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
fun decrypt(encrypted: String): String {
|
||||||
|
val c = Cipher.getInstance(AES_MODE);
|
||||||
|
c.init(Cipher.DECRYPT_MODE, _key, GCMParameterSpec(128, FIXED_IV));
|
||||||
|
val decrypted = String(c.doFinal(Base64.decode(encrypted, Base64.DEFAULT)));
|
||||||
|
return decrypted;
|
||||||
|
}
|
||||||
|
fun decrypt(encrypted: ByteArray): ByteArray {
|
||||||
|
val c = Cipher.getInstance(AES_MODE);
|
||||||
|
c.init(Cipher.DECRYPT_MODE, _key, GCMParameterSpec(128, FIXED_IV));
|
||||||
|
return c.doFinal(encrypted);
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val FIXED_IV = byteArrayOf(12, 43, 127, 2, 99, 22, 6, 78, 24, 53, 8, 101);
|
||||||
|
private const val AES_MODE = "AES/GCM/NoPadding";
|
||||||
|
private val TAG = "PasswordEncryptionProvider";
|
||||||
|
}
|
||||||
|
}
|
@ -20,6 +20,7 @@ import com.futo.platformplayer.api.media.models.video.SerializedPlatformVideo
|
|||||||
import com.futo.platformplayer.copyTo
|
import com.futo.platformplayer.copyTo
|
||||||
import com.futo.platformplayer.copyToOutputStream
|
import com.futo.platformplayer.copyToOutputStream
|
||||||
import com.futo.platformplayer.encryption.EncryptionProvider
|
import com.futo.platformplayer.encryption.EncryptionProvider
|
||||||
|
import com.futo.platformplayer.encryption.PasswordEncryptionProvider
|
||||||
import com.futo.platformplayer.getInputStream
|
import com.futo.platformplayer.getInputStream
|
||||||
import com.futo.platformplayer.getNowDiffHours
|
import com.futo.platformplayer.getNowDiffHours
|
||||||
import com.futo.platformplayer.getOutputStream
|
import com.futo.platformplayer.getOutputStream
|
||||||
@ -106,7 +107,7 @@ class StateBackup {
|
|||||||
val data = export();
|
val data = export();
|
||||||
val zip = data.asZip();
|
val zip = data.asZip();
|
||||||
|
|
||||||
val encryptedZip = EncryptionProvider.instance.encrypt(zip, getAutomaticBackupPassword());
|
val encryptedZip = PasswordEncryptionProvider(getAutomaticBackupPassword()).encrypt(zip);
|
||||||
|
|
||||||
if(!Settings.instance.storage.isStorageMainValid(context)) {
|
if(!Settings.instance.storage.isStorageMainValid(context)) {
|
||||||
StateApp.instance.scopeOrNull?.launch(Dispatchers.Main) {
|
StateApp.instance.scopeOrNull?.launch(Dispatchers.Main) {
|
||||||
@ -151,7 +152,7 @@ class StateBackup {
|
|||||||
throw IllegalStateException("Backup file does not exist");
|
throw IllegalStateException("Backup file does not exist");
|
||||||
|
|
||||||
val backupBytesEncrypted = backupFiles.first!!.readBytes(context) ?: throw IllegalStateException("Could not read stream of [${backupFiles.first?.uri}]");
|
val backupBytesEncrypted = backupFiles.first!!.readBytes(context) ?: throw IllegalStateException("Could not read stream of [${backupFiles.first?.uri}]");
|
||||||
val backupBytes = EncryptionProvider.instance.decrypt(backupBytesEncrypted, getAutomaticBackupPassword(password));
|
val backupBytes = PasswordEncryptionProvider(getAutomaticBackupPassword(password)).decrypt(backupBytesEncrypted);
|
||||||
importZipBytes(context, scope, backupBytes);
|
importZipBytes(context, scope, backupBytes);
|
||||||
Logger.i(TAG, "Finished AutoBackup restore");
|
Logger.i(TAG, "Finished AutoBackup restore");
|
||||||
}
|
}
|
||||||
@ -179,7 +180,7 @@ class StateBackup {
|
|||||||
throw ex;
|
throw ex;
|
||||||
|
|
||||||
val backupBytesEncrypted = backupFiles.second!!.readBytes(context) ?: throw IllegalStateException("Could not read stream of [${backupFiles.second?.uri}]");
|
val backupBytesEncrypted = backupFiles.second!!.readBytes(context) ?: throw IllegalStateException("Could not read stream of [${backupFiles.second?.uri}]");
|
||||||
val backupBytes = EncryptionProvider.instance.decrypt(backupBytesEncrypted, getAutomaticBackupPassword(password));
|
val backupBytes = PasswordEncryptionProvider(getAutomaticBackupPassword(password)).decrypt(backupBytesEncrypted);
|
||||||
importZipBytes(context, scope, backupBytes);
|
importZipBytes(context, scope, backupBytes);
|
||||||
Logger.i(TAG, "Finished AutoBackup restore");
|
Logger.i(TAG, "Finished AutoBackup restore");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user