简体   繁体   English

重新启动应用程序时,加密密钥会更改吗?

[英]Encryption key changes when application is restarted?

i am trying to encrypt some videos and then decrypting them later when required. 我正在尝试加密一些视频,然后在需要时将其解密。 the code works fine but since the key is generated randomly, if i encrypt a video and exit the application i wont be able to decrypt it again since next time when i open the application the keys are changed. 该代码可以正常工作,但是由于密钥是随机生成的,因此,如果我加密视频并退出应用程序,则自下次我打开该应用程序以来,将无法再次对其进行解密,因此密钥已更改。 I am using Gson to save my keys. 我正在使用Gson保存我的密钥。 but even that did not work. 但即使那样也没有用。

The below is my encryption class code. 下面是我的加密类代码。 Thanks in advance. 提前致谢。

package com.example.videoplay;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;

import javax.crypto.Cipher;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import com.google.gson.Gson;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Environment;
import android.preference.PreferenceManager;
import android.util.Log;

public class Encrypter { 
Context contxt;
File inFile;
File outFile;
File outFile_dec;
SecretKey key;
byte[] keyData;
SecretKey key2;
byte[] iv;
AlgorithmParameterSpec paramSpec;

private final static int IV_LENGTH = 16; // Default length with Default 128
                                            // key AES encryption 
private final static int DEFAULT_READ_WRITE_BLOCK_BUFFER_SIZE = 1024;

private final static String ALGO_RANDOM_NUM_GENERATOR = "SHA1PRNG";
private final static String ALGO_SECRET_KEY_GENERATOR = "AES";
private final static String ALGO_VIDEO_ENCRYPTOR = "AES/CBC/PKCS5Padding";

public static String str_key,str_paramSpec,str_key2;

@SuppressWarnings("resource") 
public static void encrypt(SecretKey key, AlgorithmParameterSpec paramSpec, InputStream in, OutputStream out)
        throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
        InvalidAlgorithmParameterException, IOException {
    try { 
         byte[] iv = new byte[] { (byte) 0x8E, 0x12, 0x39, (byte) 0x9C, 
         0x07, 0x72, 0x6F, 0x5A, (byte) 0x8E, 0x12, 0x39, (byte) 0x9C, 
         0x07, 0x72, 0x6F, 0x5A }; 
         paramSpec = new IvParameterSpec(iv); 
        Cipher c = Cipher.getInstance(ALGO_VIDEO_ENCRYPTOR);
        c.init(Cipher.ENCRYPT_MODE, key, paramSpec);
        out = new CipherOutputStream(out, c);
        int count = 0;
        byte[] buffer = new byte[DEFAULT_READ_WRITE_BLOCK_BUFFER_SIZE];
        while ((count = in.read(buffer)) >= 0) {
            out.write(buffer, 0, count);
        } 
    } finally { 
        out.close();
    } 
} 

@SuppressWarnings("resource") 
public static void decrypt(SecretKey key, AlgorithmParameterSpec paramSpec, InputStream in, OutputStream out)
        throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
        InvalidAlgorithmParameterException, IOException {
    try { 
         byte[] iv = new byte[] { (byte) 0x8E, 0x12, 0x39, (byte) 0x9C, 
         0x07, 0x72, 0x6F, 0x5A, (byte) 0x8E, 0x12, 0x39, (byte) 0x9C, 
         0x07, 0x72, 0x6F, 0x5A }; 
         paramSpec = new IvParameterSpec(iv); 
        Cipher c = Cipher.getInstance(ALGO_VIDEO_ENCRYPTOR);
        c.init(Cipher.DECRYPT_MODE, key, paramSpec);
        out = new CipherOutputStream(out, c);
        int count = 0;
        byte[] buffer = new byte[DEFAULT_READ_WRITE_BLOCK_BUFFER_SIZE];
        while ((count = in.read(buffer)) >= 0) {
            out.write(buffer, 0, count);
        } 
    } finally { 
        out.close();
    } 
} 

    public Encrypter(Context ctx) {
    //      
    inFile = new File(Environment.getExternalStorageDirectory().getPath() +MainActivity.Directory+MainActivity.filename );
    outFile = new File(Environment.getExternalStorageDirectory().getPath() + MainActivity.Directory+"/"+MainActivity.temponlyfilename);
    outFile_dec = new File(Environment.getExternalStorageDirectory().getPath() + MainActivity.Directory+MainActivity.filename);

    contxt=ctx;
    try { 

        //........................................................................................

        SharedPreferences  mPrefs = PreferenceManager.getDefaultSharedPreferences(ctx);
        String json = mPrefs.getString("pref_str_key", "empty");
        if(json.equalsIgnoreCase("empty"))
        {
            key = KeyGenerator.getInstance(ALGO_SECRET_KEY_GENERATOR).generateKey();

            keyData = key.getEncoded();
            key2 = new SecretKeySpec(keyData, 0, keyData.length, ALGO_SECRET_KEY_GENERATOR); //if you want to store key bytes to db so its just how to //recreate back key from bytes array

            iv = new byte[IV_LENGTH];
            SecureRandom.getInstance(ALGO_RANDOM_NUM_GENERATOR).nextBytes(iv); // If
                                                                                // storing 
                                                                                // separately 
            paramSpec = new IvParameterSpec(iv);

            Editor prefsEditor = mPrefs.edit();
            Gson gson = new Gson();
            str_key = gson.toJson(key);
            prefsEditor.putString("pref_str_key", str_key);
            str_key2 = gson.toJson(2);
            prefsEditor.putString("pref_str_key2", str_key2);
            prefsEditor.commit();

        }else
        {
            Gson gson = new Gson();
            str_key = mPrefs.getString("pref_str_key", "");
            key = gson.fromJson(str_key, SecretKey.class);
            str_key2 = mPrefs.getString("pref_str_key2", "");
            key2 = gson.fromJson(str_key2, SecretKey.class);
        }
        //........................................................................................

    } catch (Exception e) {
        e.printStackTrace();
    } 

}

public File Decrypt(File dir)
{
    File dirout = new File(dir.getParent()+"/temp.ts");
try {
    Encrypter.decrypt(key2, paramSpec, new FileInputStream(dir), new FileOutputStream(dirout));
    outFile_dec.delete();
} catch (Exception e) {
    e.printStackTrace();
} 
return dirout;
}

public File Encrypt(File dir) {
    File dirout = new File(dir.getParent()+"/temp.ts");
    // TODO Auto-generated method stub
    try {
        Encrypter.encrypt(key, paramSpec, new FileInputStream(dir), new FileOutputStream(dirout));
        dir.delete();
    } catch (Exception e) {
        e.printStackTrace();
    } 
    return dirout;
}




public void DecryptFromTo(File dir,File dirout)
{

try {
    Encrypter.decrypt(key2, paramSpec, new FileInputStream(dir), new FileOutputStream(dirout));

} catch (Exception e) {
    e.printStackTrace();
} 

}



} 

For temporary solution, I think it is better for you to use the static key as suggested by the Duncan. 对于临时解决方案,我认为最好使用Duncan建议的静态密钥。 Because even though the new key is generated every time, if you store the key in the plain JSON file for next usage, what would be so different than keep it in the code and reuse it over again? 因为即使每次都生成新密钥,但是如果将密钥存储在纯JSON文件中以备下次使用,与将其保留在代码中并再次重用又有什么不同呢? If anyone is trying to get the key and decrypt the video, he/she would have to either debug/de-assemble the code to find the static key or just look at the application directory for plain JSON key file, which both are not much difficult tasks. 如果有人试图获取密钥并解密视频,则他/她将不得不调试/反汇编代码以找到静态密钥,或者只是在应用程序目录中查找纯JSON密钥文件,两者都不多艰巨的任务。

If you really care about the security(I guess that's the reason that you are trying to encrypt the video stream at the first place) I suggest you to look at the Android Keystore and try to encrypt and store your video encryption key with user's PIN or passphrase that can be provided from user-side. 如果您真的很在意安全性(我想这就是您首先尝试加密视频流的原因),建议您查看Android密钥库,并尝试使用用户的PIN或可以从用户端提供的密码短语。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 方向更改时重新启动android活动 - android activity restarted when orientation changes 在对任何类进行任何更改之后,是否应该重新启动应用程序服务器? - Should an application server be restarted after making any changes in any class? IDEA + tomcat,在重新启动tomcat时不会更新javaFile上的更改 - IDEA +tomcat, won't update the changes on javaFile when tomcat was restarted 当cassandra重新启动时,应用程序的预准备语句会发生什么? - What happens to the prepared statements of an application when cassandra is restarted? 关闭/重新启动应用程序时,如何关闭db4o连接? - How to close a db4o connection when application is shutdown/restarted? RCP应用程序未重新启动 - RCP application is not restarted 重新启动活动后功能发生变化 - Functionality changes after Activity is restarted 从“最近使用的应用程序”列表中删除应用程序后,Android服务将重新启动 - Android service gets restarted when application is removed from Recent Apps list 在 Spring Data Redis 和 Spring Data jpa 中重新启动应用程序时,数据库中的数据消失 - Data in database get vanished when application is restarted in Spring Data Redis and Spring Data jpa 重新启动活动后线程继续 - Threads continue when activity is restarted
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM