Xamarin.android-如何更快地加密/解密图像

时间:2018-01-17 17:00:49

标签: c# android encryption xamarin.android

我希望用户从图库中选择图片/视频,并在我的应用中保护他们的图片。为此,我加密了这些图像。图像加密工作正常(我想是这样!)。 8MB图像需要1.5到2秒。但视频怎么样?视频可能是GB。所以这需要很多时间。即使在加密/解密中,我也必须对每个图像执行操作,这可能会导致内存问题。 This链接帮助我实现了这一目标。

如果你看,ES文件浏览器还提供图像/视频的加密和解密。它只需几秒钟即可完成GB的操作。那么我可以知道这些人使用哪种技术/算法吗?

或者即使我以自己的方式使用,是否有任何技巧可以让它更快?或者有没有其他方法使用户无法访问文件?更改MIME类型是否有效?

即使我通过添加更改扩展名或隐藏它。在文件名之前,用户仍然可以在某个文件资源管理器中查看图像。

实际上对于xamarin,我没有找到任何与加密解密文件相关的帖子/博客。它们提供的只是字符串解决方案。

如果有人指导我解决这个问题,我将非常感激。

修改

您好,@ Joe Lv,正如我所说,我尝试过你的方法,加密速度很慢,但解密速度非常快。所以我实现了用于加密事物的相同解密技术。它的工作原理!!但我想知道这是否有效。

现在我的加密方法如下所示:

public void encrypt(string filename)
    {

        // Here you read the cleartext.
        try
        {
            File extStore = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryMovies);
            startTime = System.DateTime.Now.Millisecond;
            Android.Util.Log.Error("Encryption Started", extStore + "/" + filename);

            // This stream write the encrypted text. This stream will be wrapped by
            // another stream.
        //    createFile(filename, extStore);
        //    System.IO.FileStream fs=System.IO.File.OpenRead(extStore + "/" + filename);
      //      FileOutputStream fos = new FileOutputStream(extStore + "/" + filename + ".aes", false);

            FileInputStream fis = new FileInputStream(filepath);


            FileOutputStream fos = new FileOutputStream(filepath, false);
            System.IO.FileStream fs = System.IO.File.OpenWrite(filepath + filename);
            // Create cipher

            // Length is 16 byte
            Cipher cipher = Cipher.GetInstance("AES/CBC/PKCS5Padding");
            byte[] raw = System.Text.Encoding.Default.GetBytes(sKey);
            SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
            IvParameterSpec iv = new IvParameterSpec(System.Text.Encoding.Default.GetBytes(ivParameter));//
            cipher.Init(CipherMode.EncryptMode, skeySpec, iv);

            // Wrap the output stream
           // CipherInputStream cis = new CipherInputStream(fs, cipher);
            CipherOutputStream cos = new CipherOutputStream(fs, cipher);

            // Write bytes
            int b;
            byte[] d = new byte[512 * 1024];
            while ((b = fis.Read(d)) != -1)
            {
                cos.Write(d, 0, b);
            }
            // Flush and close streams.
            fos.Flush();
            fos.Close();
            cos.Close();
   fis.Close();

            stopTime = System.DateTime.Now.Millisecond;
            Android.Util.Log.Error("Encryption Ended", extStore + "/5mbtest/" + filename + ".aes");
            Android.Util.Log.Error("Time Elapsed", ((stopTime - startTime) / 1000.0) + "");
        }
        catch (Exception e)
        {
            Android.Util.Log.Error("lv",e.Message);
        }

    }

1 个答案:

答案 0 :(得分:1)

  

我没有找到任何与加密解密文件有关的帖子/博客

您可以使用CipherOutputStreamCipherInputStream来实现它。

以下是我的测试演示,您可以尝试一下,并且需要将名为 videoplayback.mp4 的视频文件推送到您的手机中,路径为/storage/sdcard/Movies,以便您可以测试我的代码直接。

using Android.App;
using Android.Widget;
using Android.OS;
using Javax.Crypto.Spec;
using Java.Lang;
using Java.IO;
using Javax.Crypto;
using System.Text;

namespace EncryTest
{
    [Activity(Label = "EncryTest", MainLauncher = true)]
    public class MainActivity : Activity
    {
        long stopTime, startTime;
        private string sKey = "0123456789abcdef";//key,
        private string ivParameter = "1020304050607080";
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            // Set our view from the "main" layout resource
            SetContentView(Resource.Layout.Main);

            encrypt("videoplayback.mp4");
            decrypt("videoplayback.mp4");
        }

        public void encrypt(string filename)
        {

            // Here you read the cleartext.
            try
            {
                File extStore = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryMovies);
                startTime = System.DateTime.Now.Millisecond;
                Android.Util.Log.Error("Encryption Started", extStore + "/" + filename);

                // This stream write the encrypted text. This stream will be wrapped by
                // another stream.
                createFile(filename, extStore);
                System.IO.FileStream fs=System.IO.File.OpenRead(extStore + "/" + filename);
                FileOutputStream fos = new FileOutputStream(extStore + "/" + filename + ".aes", false);

                // Length is 16 byte
                Cipher cipher = Cipher.GetInstance("AES/CBC/PKCS5Padding");
                byte[] raw = System.Text.Encoding.Default.GetBytes(sKey);
                SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
                IvParameterSpec iv = new IvParameterSpec(System.Text.Encoding.Default.GetBytes(ivParameter));//
                cipher.Init(CipherMode.EncryptMode, skeySpec, iv);

                // Wrap the output stream
                CipherInputStream cis = new CipherInputStream(fs, cipher);
                // Write bytes
                int b;
                byte[] d = new byte[1024 * 1024];
                while ((b = cis.Read(d)) != -1)
                {
                    fos.Write(d, 0, b);
                }
                // Flush and close streams.
                fos.Flush();
                fos.Close();
                cis.Close();
                stopTime = System.DateTime.Now.Millisecond;
                Android.Util.Log.Error("Encryption Ended", extStore + "/5mbtest/" + filename + ".aes");
                Android.Util.Log.Error("Time Elapsed", ((stopTime - startTime) / 1000.0) + "");
            }
            catch (Exception e)
            {
                Android.Util.Log.Error("lv",e.Message);
            }

        }


        private void createFile(string filename, File extStore)
        {
            File file = new File(extStore + "/" + filename + ".aes");

            if (filename.IndexOf(".") != -1)
            {
                try
                {
                    file.CreateNewFile();
                }
                catch (IOException e)
                {
                    // TODO Auto-generated catch block
                    Android.Util.Log.Error("lv",e.Message);
                }
                Android.Util.Log.Error("lv","file created");
            }
            else
            {
                file.Mkdir();
                Android.Util.Log.Error("lv","folder created");
            }

            file.Mkdirs();
        }
        public void decrypt(string filename)
        {
            try
            {

                File extStore = Environment.GetExternalStoragePublicDirectory(Environment.DirectoryMovies);
                Android.Util.Log.Error("Decryption Started", extStore + "");
                FileInputStream fis = new FileInputStream(extStore + "/" + filename + ".aes");

                createFile(filename, extStore);
                FileOutputStream fos = new FileOutputStream(extStore + "/" + "decrypted" + filename, false);
                System.IO.FileStream fs = System.IO.File.OpenWrite(extStore + "/" + "decrypted" + filename);
                // Create cipher

                Cipher cipher = Cipher.GetInstance("AES/CBC/PKCS5Padding");
                byte[] raw = System.Text.Encoding.Default.GetBytes(sKey);
                SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
                IvParameterSpec iv = new IvParameterSpec(System.Text.Encoding.Default.GetBytes(ivParameter));//
                cipher.Init(CipherMode.DecryptMode, skeySpec, iv);

                startTime = System.DateTime.Now.Millisecond;
                CipherOutputStream cos = new CipherOutputStream(fs, cipher);
                int b;
                byte[] d = new byte[1024 * 1024];
                while ((b = fis.Read(d)) != -1)
                {
                    cos.Write(d, 0, b);
                }

                stopTime = System.DateTime.Now.Millisecond;

                Android.Util.Log.Error("Decryption Ended", extStore + "/" + "decrypted" + filename);
                Android.Util.Log.Error("Time Elapsed", ((stopTime - startTime) / 1000.0) + "");

                cos.Flush();
                cos.Close();
                fis.Close();
            }
            catch (Exception e)
            {
                Android.Util.Log.Error("lv", e.Message);
            }
        }
    }
}

视频只是为了测试,你可以从另一条路径获取视频文件,只需稍加改动即可。

关于路径/storage/sdcard/Movies,我认为最好先了解一下enter image description here