Android AES加密/解密——输入流&字节数组输出流

标签 android encryption aes inputstream outputstream

所以基本上我是从 asses 文件夹加密图像,然后解密它。我把日志放在代码中的几个地方,这样我就可以看到 InputStream 的实际大小,在 bytearrayoutputstream 中复制输入流之后的字节,大小加密和解密后的图像(我认为加密/解密没有问题,但不太确定)。问题是当我运行程序时,我在 LogCat 中得到这个:

07-27 13:41:08.091: VERBOSE/Size(10546): Size of inputstream 29199
07-27 13:41:17.340: WARN/ActivityManager(52): Launch timeout has expired, giving up wake lock!
07-27 13:41:17.670: WARN/ActivityManager(52): Activity idle timeout for HistoryRecord{44defa50 com.example.pbe/.PBEencryptdecryptActivity}

就是这样。我使用的代码是:

package com.example.aes;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import android.app.Activity;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class PBEencryptdecryptActivity extends Activity {
    private int IO_BUFFER_SIZE;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        KeyGenerator keygen;
        try {
            keygen = KeyGenerator.getInstance("AES");
            SecretKey aesKey = keygen.generateKey();
            Cipher aesCipher,aesCipherDec;

            AssetManager am = this.getAssets();
            InputStream is = am.open("007FRAMESUPERIOR.jpg"); // get the encrypted image from assets folder
            Log.v("Size","Size of inputstream "+is.available());


            ByteArrayOutputStream baos = new ByteArrayOutputStream();  
            byte[] b = new byte[IO_BUFFER_SIZE];  

            int read;  
            while ((read = is.read(b)) != -1) {  //convert inputstream to bytearrayoutputstream
                baos.write(b, 0, read);
            }
            Log.v("Size","Size of b "+b.length);

            aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");     // Create the cipher            
            aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);    // Initialize the cipher for encryption                         
            byte[] ciphertext = aesCipher.doFinal(b);   // Encrypt the cleartext
            Log.v("Size","Size of image encrypted "+ciphertext.length);


            aesCipherDec =  Cipher.getInstance("AES/ECB/PKCS5Padding");
            aesCipherDec.init(Cipher.DECRYPT_MODE, aesKey); // Initialize the same cipher for decryption                        
            byte[] cleartext1 = aesCipher.doFinal(ciphertext);  // Decrypt the ciphertext                   

            //Bitmap bitmap = BitmapFactory.decodeByteArray(cleartext1 , 0,  cleartext1.length);    //decoding bytearrayoutputstream to bitmap
            Log.v("Size","Size of image decrypted "+cleartext1.length);

        } catch (Exception e) {
            e.printStackTrace();
            Log.v("Error", "Error Occured "+e);
        }

    }
}

实际上,我在想如何设置 private int IO_BUFFER_SIZE; 的大小,这样我就可以将所有输入流复制到输出流而不会丢失任何数据。非常感谢任何帮助!

最佳答案

我认为这是一个错误:你只加密了缓冲区而不是整个文件的内容。

在阅读循环之后你必须调用

b = baos.tobyteArray();

之后您可以将 IO_BUFFER_SIZE 减少到您想要的任何数字。通常 4094 是一个不错的数字。

此外,我会使用您需要的确切大小来初始化 byteArrayOutputStream:

ByteArrayOutputStream baos = new ByteArrayOutputStream(is.available());  

关于Android AES加密/解密——输入流&字节数组输出流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6845419/

相关文章:

Android 6.0.1 - 权限问题 = wifiManager.getScanResults() 返回 0

javascript - 从 JavaScript 应用程序发送和接收加密数据

c# - Azure 网站上的数据保护/加密?

.net - .Net 和 iPhone 之间的 AES 互操作性?

java - Java AES/CBC 解密后的初始字节不正确

encryption - Golang 在不同的机器上生成相同的加密

java - 在聊天应用程序中如何使用 Firebase 实现打字指示器

android - 为什么android允许删除正在使用的文件......?

Android AlertDialog.Builder 和软键盘

javascript - 如何使用 JavaScript 加密 XML?