2014-09-26 180 views
1

编辑:::问题中的代码工作,但一旦图像在相机中拍摄后,需要大约10秒才能恢复活动。我放弃了这种方法,并使用Facebook的隐藏库来加密和解密图像。链接到Facebook的解决方案:Facebook Conceal - Image Encryption and Decryption使用AES加密和解密图像的正确方法


我已经看过很多例子,但还是没能想出一个办法来获得加密和解密的权利。当我在互联网上使用一些随机代码时,我以为我知道它是正确的,但在解码时,我得到了BadPadding异常。

所以,我正在努力解决它。正如大多数人所建议的那样,我遵循以下问题(但是此代码显示如何加密字符串)。有人能帮我加密和解密图像吗?问题中的代码是否适用于图像?

链接到一个问题:Java 256-bit AES Password-Based Encryption

这里是我做了什么至今:

//全球ArrayList中存储IV和密码

static ArrayList<byte[]> ivandcipher = new ArrayList<byte[]>(); 

//生成键

public static SecretKey generateKey() throws NoSuchAlgorithmException { 

    char[] password = { 'a', 'b', 'c', 'd', 'e' }; 
    byte[] salt = { 1, 2, 3, 4, 5 }; 

    SecretKeyFactory factory = SecretKeyFactory 
      .getInstance("PBKDF2WithHmacSHA1"); 
    KeySpec spec = new PBEKeySpec(password, salt, 65536, 256); 
    SecretKey tmp = null; 
    try { 
     tmp = factory.generateSecret(spec); 
    } catch (InvalidKeySpecException e) { 
     e.printStackTrace(); 
    } 

    yourKey = new SecretKeySpec(tmp.getEncoded(), "AES"); 

    return yourKey; 
} 

//编码文件

//字节[] FILEDATA,包含位图(图像)转换成字节[]

public static ArrayList<byte[]> encodeFile(SecretKey yourKey, byte[] fileData) 
     throws Exception { 

    byte[] encrypted = null; 

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    cipher.init(Cipher.ENCRYPT_MODE, yourKey); 
    AlgorithmParameters params = cipher.getParameters(); 
    byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV(); 
    encrypted = cipher.doFinal(fileData); 

    ivandcipher.clear(); 
    ivandcipher.add(iv); 
    ivandcipher.add(encrypted); 

    return ivandcipher; 
} 

为何我添加IV和加密的字节[] s到ivandcipher。因为,正如链接中的答案所暗示的,我应该在解密时使用相同的iv。

//解码文件

//我把这个方法里面重载decodeFile方法。请注意

private Bitmap decodeFile(String filename) { 

    try { 
     yourKey = generateKey(); 
    } catch (NoSuchAlgorithmException e1) { 
     e1.printStackTrace(); 
    } 

    try { 
     byte[] decodedData = decodeFile(yourKey, readFile(filename)); 
     Bitmap bitmap = bytesToBitmap(decodedData); 

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

    return null; 
} 

//重载decodeFile方法

public static byte[] decodeFile(SecretKey yourKey, byte[] fileData) 
     throws Exception { 

    byte[] decrypted = null; 
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    cipher.init(Cipher.DECRYPT_MODE, yourKey, new IvParameterSpec(ivandcipher.get(0))); 
    decrypted = cipher.doFinal(fileData); 
    return decrypted; 
} 

我想这个问题与fileData []一起,我无法正确加密和解​​密。对于字符串显示在上述链路的答案,即

byte[] ciphertext = cipher.doFinal("Hello, World!".getBytes("UTF-8"));

什么应该被给定为参数cipher.doFinal()?

让我知道你是否需要任何其他代码。

+0

downvote的任何理由?我明白这已被问了很多次,但我无法对我的图像进行适当的加密和解密。 – 2014-09-26 11:51:17

+0

原因基本上是你复制了“在互联网上的一些随机代码”,没有得到它的工作,现在我们应该修复它。 – ntoskrnl 2014-09-26 11:57:55

+0

@ntoskrnl,我不是要求任何人修复它。我在请求你的帮助,理解它并使之发挥作用。顺便说一下,我在问题中发布的代码不是随机的,而是来自我在问题中发布的链接。 – 2014-09-26 11:58:48

回答

0

问题中的代码有效,但一旦图像在相机中拍摄,回到活动时间大约需要10秒。我放弃了这种方法,并使用Facebook的隐藏库来加密和解密图像。链接到Facebook的解决方案:Facebook Conceal - Image Encryption and Decryption

+0

我相信你的问题是你试图在UI线程中加密和解密,这可能解释为10秒的延迟。 – 2014-10-10 14:16:13

1

你试图一次做得太多,并且迷失在所有细节中。

开始简化你的代码所需要的加密和解密的最低限度:

byte[] key = { 1, 2, 3, ... 14, 15, 16 }; 
byte[] IV = { 5, 5, 5, ... 5, 5, 5 }; 
String plaintext = "This is a secret message." 

现在减少你的代码进行加密和解密明文消息回可读的文本字符串。

当你有一个小程序正常工作时,一次添加一个其他并发症。在每个阶段,再次检查您的代码是否可以成功加密和解密。我建议你首先加回SecretKeyFactory部分,然后完成文件读写部分。

通过将程序拆分成更小的部分,您将更容易理解程序的每个部分在做什么,并使您更容易识别出错地点。

4

使用Java库可以轻松加密和解密图像。我使用两种不同的加密和解密方法向您展示两个独立的代码。以下代码也可以扩展为用于PDF文件。

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.security.Key; 
import java.security.NoSuchAlgorithmException; 

import javax.crypto.Cipher; 
import javax.crypto.KeyGenerator; 

public class ImageEncDec { 

    public static byte[] getFile() { 

     File f = new File("/home/bridgeit/Desktop/Olympics.jpg"); 
     InputStream is = null; 
     try { 
      is = new FileInputStream(f); 
     } catch (FileNotFoundException e2) { 
      // TODO Auto-generated catch block 
      e2.printStackTrace(); 
     } 
     byte[] content = null; 
     try { 
      content = new byte[is.available()]; 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
     try { 
      is.read(content); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return content; 
    } 

    public static byte[] encryptPdfFile(Key key, byte[] content) { 
     Cipher cipher; 
     byte[] encrypted = null; 
     try { 
      cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
      cipher.init(Cipher.ENCRYPT_MODE, key); 
      encrypted = cipher.doFinal(content); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     return encrypted; 

    } 

    public static byte[] decryptPdfFile(Key key, byte[] textCryp) { 
     Cipher cipher; 
     byte[] decrypted = null; 
     try { 
      cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 
      cipher.init(Cipher.DECRYPT_MODE, key); 
      decrypted = cipher.doFinal(textCryp); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return decrypted; 
    } 

    public static void saveFile(byte[] bytes) throws IOException { 

     FileOutputStream fos = new FileOutputStream("/home/bridgeit/Desktop/Olympics-new.jpg"); 
     fos.write(bytes); 
     fos.close(); 

    } 

    public static void main(String args[]) 
      throws NoSuchAlgorithmException, InstantiationException, IllegalAccessException, IOException { 

     KeyGenerator keyGenerator = KeyGenerator.getInstance("AES"); 
     keyGenerator.init(128); 
     Key key = keyGenerator.generateKey(); 
     System.out.println(key); 

     byte[] content = getFile(); 
     System.out.println(content); 

     byte[] encrypted = encryptPdfFile(key, content); 
     System.out.println(encrypted); 

     byte[] decrypted = decryptPdfFile(key, encrypted); 
     System.out.println(decrypted); 

     saveFile(decrypted); 
     System.out.println("Done"); 

    } 

} 

` 这是产生相同输出,但只用一次又一次生成相同的密钥之外的第二码。

import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.util.Arrays; 

import javax.crypto.Cipher; 
import javax.crypto.SecretKey; 
import javax.crypto.spec.SecretKeySpec; 

import org.apache.commons.codec.binary.Base64; 

public class Trial { 

    public static byte[] getFile() { 

     File f = new File("/home/bridgeit/Desktop/Olympics.jpg"); 
     InputStream is = null; 
     try { 
      is = new FileInputStream(f); 
     } catch (FileNotFoundException e2) { 
      // TODO Auto-generated catch block 
      e2.printStackTrace(); 
     } 
     byte[] content = null; 
     try { 
      content = new byte[is.available()]; 
     } catch (IOException e1) { 
      // TODO Auto-generated catch block 
      e1.printStackTrace(); 
     } 
     try { 
      is.read(content); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return content; 
    } 

    public static byte[] encryptPdfFile(SecretKey secretKey, byte[] content) { 
     Cipher cipher; 
     byte[] encrypted = null; 
     try { 
      cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); 

      cipher.init(Cipher.ENCRYPT_MODE, secretKey); 

      encrypted = Base64.encodeBase64(cipher.doFinal(content)); 

     } catch (Exception e) { 

      System.out.println("Error while encrypting: " + e.toString()); 
     } 
     return encrypted; 

    } 

    public static byte[] decryptPdfFile(SecretKey secretKey, byte[] textCryp) { 
     Cipher cipher; 
     byte[] decrypted = null; 
     try { 
      cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING"); 

      cipher.init(Cipher.DECRYPT_MODE, secretKey); 
      decrypted = cipher.doFinal(Base64.decodeBase64(textCryp)); 

     } catch (Exception e) { 

      System.out.println("Error while decrypting: " + e.toString()); 
     } 
     return decrypted; 
    } 

    public static void saveFile(byte[] bytes) throws IOException { 

     FileOutputStream fos = new FileOutputStream("/home/bridgeit/Desktop/Olympics-new.jpg"); 
     fos.write(bytes); 
     fos.close(); 

    } 

    public static void main(String args[]) 
      throws NoSuchAlgorithmException, InstantiationException, IllegalAccessException, IOException { 

     SecretKeySpec secretKey; 
     byte[] key; 
     String myKey = "ThisIsAStrongPasswordForEncryptionAndDecryption"; 

     MessageDigest sha = null; 
     key = myKey.getBytes("UTF-8"); 
     System.out.println(key.length); 
     sha = MessageDigest.getInstance("SHA-1"); 
     key = sha.digest(key); 
     key = Arrays.copyOf(key, 16); // use only first 128 bit 
     System.out.println(key.length); 
     System.out.println(new String(key, "UTF-8")); 
     secretKey = new SecretKeySpec(key, "AES"); 

     byte[] content = getFile(); 
     System.out.println(content); 

     byte[] encrypted = encryptPdfFile(secretKey, content); 
     System.out.println(encrypted); 

     byte[] decrypted = decryptPdfFile(secretKey, encrypted); 
     System.out.println(decrypted); 

     saveFile(decrypted); 
     System.out.println("Done"); 

    } 

}