2015-01-23 23 views
11

Vì vậy, tôi đang làm việc trên một dự án cá nhân cho bản thân mình và tôi đang cố mã hóa các tệp trên điện thoại của mình. Những tệp này có thể là bất kỳ thứ gì, ví dụ: Tài liệu, ảnh, v.v. Ngay bây giờ, tôi đang cố gắng làm việc này đúng cách. Khi bao giờ tôi chạy mã hóa nó có vẻ hoạt động đúng và mã hóa các tập tin. Khi tôi chạy các giải mã, đôi khi nó hoạt động và thời gian khác nó không. Khi nó không thành công tôi thường nhận được một lỗi "Lỗi trong khi hoàn tất mật mã, khối pad bị hỏng". Tôi cũng không sử dụng các tệp thử nghiệm khác nhau, vì vậy nó không giống như một số tệp hoạt động và những tệp khác thì không. Đó là hai tập tin giống nhau tôi thử mỗi lần.Mã hóa các tệp bằng AES trên Android

public static void encryptfile(String path,String Pass) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { 
    FileInputStream fis = new FileInputStream(path); 
    FileOutputStream fos = new FileOutputStream(path.concat(".crypt")); 
    byte[] key = (salt + Pass).getBytes("UTF-8"); 
    MessageDigest sha = MessageDigest.getInstance("SHA-1"); 
    key = sha.digest(key); 
    key = Arrays.copyOf(key,16); 
    SecretKeySpec sks = new SecretKeySpec(key, "AES"); 
    Cipher cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.ENCRYPT_MODE, sks); 
    CipherOutputStream cos = new CipherOutputStream(fos, cipher); 
    int b; 
    byte[] d = new byte[8]; 
    while((b = fis.read(d)) != -1) { 
     cos.write(d, 0, b); 
    } 
    cos.flush(); 
    cos.close(); 
    fis.close(); 
} 

public static void decrypt(String path,String Pass) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { 
    FileInputStream fis = new FileInputStream(path); 
    FileOutputStream fos = new FileOutputStream(path.replace(".crypt","")); 
    byte[] key = (salt + Pass).getBytes("UTF-8"); 
    MessageDigest sha = MessageDigest.getInstance("SHA-1"); 
    key = sha.digest(key); 
    key = Arrays.copyOf(key,16); 
    SecretKeySpec sks = new SecretKeySpec(key, "AES"); 
    Cipher cipher = Cipher.getInstance("AES"); 
    cipher.init(Cipher.DECRYPT_MODE, sks); 
    CipherInputStream cis = new CipherInputStream(fis, cipher); 
    int b; 
    byte[] d = new byte[8]; 
    while((b = cis.read(d)) != -1) { 
     fos.write(d, 0, b); 
    } 
    fos.flush(); 
    fos.close(); 
    cis.close(); 
} 

Hiện tại, Muối và Mật khẩu là tĩnh và không thay đổi cho mục đích thử nghiệm. Vẫn gặp lỗi khoảng một nửa thời gian.

Có ai có bất kỳ ý tưởng nào về lý do điều này xảy ra không? Tôi đã được tìm kiếm xung quanh và tôi đã tìm thấy một vài điều để thử, không ai trong số đó làm việc. Tôi đã xem xét thông qua một số câu hỏi sau đây cho các giải pháp:

Android decryption: Error while finalizing cipher

last block incomplete with CipherInputStream/CipherOutputStream, even with padding AES/CBC/PKCS5Padding

Encryption error on Android 4.2

Decrypting error : "no iv set when one expected"

How to handle "last block incomplete in decryption"

Encryption and decryption of image file

Tips on encryption/decryption of images in java using AES

Any help is appreciated rất nhiều! Tôi nghĩ rằng tôi chỉ thiếu một cái gì đó đơn giản ...

Cập nhật!

Mọi người đã đúng khi là muối. Khi tôi loại bỏ muối, vấn đề đã được giải quyết ... Đã đào nhiều hơn một chút, hóa ra muối + Vượt qua là vấn đề, nhưng vì muối là một byte [] và Pass là một chuỗi. Tôi đã thay đổi muối thành String và sau đó sử dụng salt.concat (Pass) và vấn đề đã được giải quyết!

+0

Cá nhân tôi sẽ được quan tâm để xem những gì bạn đã cố gắng để thực hiện. Nó cũng có thể giúp đỡ người khác vì họ có thể thấy các tùy chọn nào đã được thử (ngay cả khi chúng đã được triển khai không chính xác). – Bono

+0

@Bono Tôi đã thêm các liên kết mà tôi nghĩ sẽ hữu ích cho tôi, nhưng cuối cùng không giúp tôi nhiều. Tôi đã thử những thứ như làm cho nó không có padding, sử dụng CBC thay vì EBC (mà tôi muốn làm anyways). Tại một thời điểm tôi thậm chí đã có nó chuyển đổi Base64: P – Linux4Hope

+0

Có vẻ như muối rất có thể là vấn đề, như một muối bao gồm các byte ngẫu nhiên, nhưng nó được đưa ra như là một chuỗi. Bạn đã tạo ra muối như thế nào? –

Trả lời

5

có thể tôi đang thiếu điều gì đó nhưng về phía tôi, nó hoạt động mà không có vấn đề gì. Bạn có thể thử lớp sau chỉ đơn giản là thay đổi các biến fileToBeCrypted, fileToBeDecrypted và fileDecryptedOutput?

package test; 

import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.security.InvalidKeyException; 
import java.security.MessageDigest; 
import java.security.NoSuchAlgorithmException; 
import java.util.Arrays; 

import javax.crypto.Cipher; 
import javax.crypto.CipherInputStream; 
import javax.crypto.CipherOutputStream; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.spec.SecretKeySpec; 

public class TestCrypt{ 

    private static final String salt = "t784"; 
    private static final String cryptPassword = "873147cbn9x5'2 79'79314"; 
    private static final String fileToBeCrypted = "c:\\Temp\\sampleFile.conf"; 
    private static final String fileToBeDecrypted = "c:\\Temp\\sampleFile.conf.crypt"; 
    private static final String fileDecryptedOutput = "c:\\Temp\\sampleFile.conf.decrypted"; 

    public static void main(String[] args) throws Exception 
    { 
     for (int i=0; i<100; i++) 
     { 
      encryptfile(fileToBeCrypted, cryptPassword); 
      decrypt(fileToBeDecrypted, cryptPassword, fileDecryptedOutput); 
      System.out.println(i); 
     } 
    } 

    public static void encryptfile(String path,String password) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { 
     FileInputStream fis = new FileInputStream(path); 
     FileOutputStream fos = new FileOutputStream(path.concat(".crypt")); 
     byte[] key = (salt + password).getBytes("UTF-8"); 
     MessageDigest sha = MessageDigest.getInstance("SHA-1"); 
     key = sha.digest(key); 
     key = Arrays.copyOf(key,16); 
     SecretKeySpec sks = new SecretKeySpec(key, "AES"); 
     Cipher cipher = Cipher.getInstance("AES"); 
     cipher.init(Cipher.ENCRYPT_MODE, sks); 
     CipherOutputStream cos = new CipherOutputStream(fos, cipher); 
     int b; 
     byte[] d = new byte[8]; 
     while((b = fis.read(d)) != -1) { 
      cos.write(d, 0, b); 
     } 
     cos.flush(); 
     cos.close(); 
     fis.close(); 
    } 

    public static void decrypt(String path,String password, String outPath) throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException { 
     FileInputStream fis = new FileInputStream(path); 
     FileOutputStream fos = new FileOutputStream(outPath); 
     byte[] key = (salt + password).getBytes("UTF-8"); 
     MessageDigest sha = MessageDigest.getInstance("SHA-1"); 
     key = sha.digest(key); 
     key = Arrays.copyOf(key,16); 
     SecretKeySpec sks = new SecretKeySpec(key, "AES"); 
     Cipher cipher = Cipher.getInstance("AES"); 
     cipher.init(Cipher.DECRYPT_MODE, sks); 
     CipherInputStream cis = new CipherInputStream(fis, cipher); 
     int b; 
     byte[] d = new byte[8]; 
     while((b = cis.read(d)) != -1) { 
      fos.write(d, 0, b); 
     } 
     fos.flush(); 
     fos.close(); 
     cis.close(); 
    } 

} 

Tôi có thể lặp lại nhiều lần mà không gặp lỗi! Tôi đang sử dụng Oracle JDK 1.8 nhưng chạy ở chế độ tương thích 1.7.

Hy vọng điều này sẽ giúp bạn.

Bye Piero

+0

Hóa ra đó là muối .... Chỉ có vấn đề là tôi không chắc chắn tại sao. Tôi đang đào nhiều hơn :) – Linux4Hope

+0

Đồng ý với Linux, muối không thể chứa các ký tự đặc biệt. – Michalsx

Các vấn đề liên quan