在SD卡Android上加密和解密图像
我已经使用下面的图像加密代码。我不明白我的编码或解码代码是否有效。当我用它来编码图像时,它会生成加密图像,但当我解密它时,它不起作用。我无法理解编码错误或解密有错误。我只在布局中使用了两个按钮。 以下是在SD卡Android上加密和解密图像,android,image,encryption,cryptography,android-sdcard,Android,Image,Encryption,Cryptography,Android Sdcard,我已经使用下面的图像加密代码。我不明白我的编码或解码代码是否有效。当我用它来编码图像时,它会生成加密图像,但当我解密它时,它不起作用。我无法理解编码错误或解密有错误。我只在布局中使用了两个按钮。 以下是MainActivity.java的代码 package demo.encryptionanddecryption; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream
MainActivity.java
的代码
package demo.encryptionanddecryption;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import android.Manifest;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
AppPermissions permissions;
private static final int PERMISSION_ALL = 1;
private static final String[] PERMISSIONS = {Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE};
byte[] key, iv;
Button encryption,decryption;
static final String AB = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static SecureRandom rnd = new SecureRandom();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
encryption = (Button)findViewById(R.id.encryption);
decryption = (Button)findViewById(R.id.decryption);
permissions = new AppPermissions();
if (!permissions.hasPermissions(MainActivity.this, PERMISSIONS)) {
ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS, PERMISSION_ALL);
Log.i("logCat", "Permission Granted");
} else {
Log.i("logCat", "Permission Rejected");
}
// Get key
key = getKey();
// Get IV
iv = getIV();
encryption.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//File file = new File(Environment.getExternalStorageDirectory() + File.separator + "test", "test.txt");
try {
encryptFile();
} catch (Exception e) {
e.printStackTrace();
}
}
});
decryption.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
decryptFile();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public void encryptFile(){
Bitmap bitmap= BitmapFactory.decodeFile(new File(Environment.getExternalStorageDirectory()+ File.separator + "img.png").toString());
// Write image data to ByteArrayOutputStream
ByteArrayOutputStream baos=new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100,baos);
// Encrypt and save the image
saveFile(encrypt(key,baos.toByteArray()),"enimg.png");
}
public void decryptFile(){
try {
// Create FileInputStream to read from the encrypted image file
FileInputStream fis = new FileInputStream(new File(Environment.getExternalStorageDirectory() + File.separator + "enimg.png").toString());
// Save the decrypted image
saveFile(decrypt(key, fis),"deimg.png");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public void saveFile(byte[] data, String outFileName){
FileOutputStream fos=null;
try {
fos=new FileOutputStream(new File(Environment.getExternalStorageDirectory() + File.separator + outFileName).toString());
fos.write(data);
} catch (Exception e) {
e.printStackTrace();
}
finally{
try {
fos.close();
} catch (NullPointerException | IOException e) {
e.printStackTrace();
}
}
}
private byte[] encrypt(byte[] skey, byte[] data){
SecretKeySpec skeySpec = new SecretKeySpec(skey, "AES");
Cipher cipher;
byte[] encrypted=null;
try {
// Get Cipher instance for AES algorithm
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// Initialize cipher
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
// Encrypt the image byte data
encrypted = cipher.doFinal(data);
}catch(Exception e){
e.printStackTrace();
}
return encrypted;
}
private byte[] decrypt(byte[] skey, FileInputStream fis){
SecretKeySpec skeySpec = new SecretKeySpec(skey, "AES");
Cipher cipher;
byte[] decryptedData=null;
CipherInputStream cis=null;
try {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(iv));
// Create CipherInputStream to read and decrypt the image data
cis = new CipherInputStream(fis, cipher);
// Write encrypted image data to ByteArrayOutputStream
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] data = new byte[2048];
while ((cis.read(data)) != -1) {
buffer.write(data);
}
buffer.flush();
decryptedData=buffer.toByteArray();
}catch(Exception e){
e.printStackTrace();
}
finally{
try {
fis.close();
cis.close();
} catch (IOException | NullPointerException e) {
e.printStackTrace();
}
}
return decryptedData;
}
private static byte[] getKey(){
KeyGenerator keyGen;
byte[] dataKey=null;
try {
// Generate 256-bit key
keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
SecretKey secretKey = keyGen.generateKey();
dataKey=secretKey.getEncoded();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return dataKey;
}
private static byte[] getIV(){
SecureRandom random = new SecureRandom();
byte[] iv = random.generateSeed(16);
return iv;
}
}
解密文件时,请使用以下命令:
int read;
while ((read = cis.read(data)) != -1) {
buffer.write(data, 0, read);
}
因为不确定last cis.read()是否会返回完整的缓冲区,最终会将垃圾字节写入文件。有点晚,但可以帮助其他人 在onCreate方法之前使用此方法
ByteArrayOutputStream-baos,缓冲区代码>
方法
public void encryptFile(){…
replace
ByteArrayOutputStream baos=new ByteArrayOutputStream();
with
baos=newbytearrayoutputstream();
在方法private byte[]decrypt(byte[]skey,FileInputStream fis)中,…
将ByteArrayOutputStream buffer=newbytearrayoutputstream();
替换为
buffer=baos;
您加密的图像将被解密我不清楚问题是什么。解密失败了吗?如果是,它是如何失败的?请通过编辑您的问题来发布任何相关的stacktrace信息。看起来您使用默认IV进行加密,但使用随机IV进行解密。这不起作用。@詹姆斯的问题在于解密。加密该图像时生成的加密图像,但解密后输出的图像已损坏。@詹姆斯,你能帮我为其编写解密代码吗?