2014-09-26 39 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"); 

    } 

}