2016-06-02 2 views
0

CipherInputStream 및 CipherOutputStream을 사용하여 파일을 암호화 및 암호 해독하는 동안 해독 된 파일은 원본과 다릅니다. 실행 중에는 오류가 발생하지 않지만 원본과 결과에는 다른 해시가 있습니다. 원본과 결과도 정확히 같은 크기입니다. 파일 충돌/덮어 쓰기가 진행되지 않습니다. 지금까지 내 생각 엔 문자 인코딩입니다. Java 암호 해독은 원본과 다른 결과를 제공합니다.

public void fileTest(File source, File output, String key) throws Exception { 
    Log.write("Starting file encryption/decryption test!"); 
    Util.charset = CharsetToolkit.guessEncoding(source, 4096, StandardCharsets.UTF_8); 
    Log.write("Using charset " + Util.charset.name()); 
    Log.write("Using key: " + key); 
    String oHash = Util.checksum(source); 
    Log.write("Original hash: " + oHash); 

    //Cipher setup 

    SecretKeySpec sks = Util.padKey(key); 
    Cipher eCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    Cipher dCipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    eCipher.init(Cipher.ENCRYPT_MODE, sks, new IvParameterSpec(new byte[16])); 
    dCipher.init(Cipher.DECRYPT_MODE, sks, new IvParameterSpec(new byte[16])); 

    //IO setup 
    File tmpEncrypt = new File(source.getParent() + "/" + source.getName() + "-tmp"); 
    tmpEncrypt.createNewFile(); 
    output.createNewFile(); 
    Log.write("Encrypting to: " + tmpEncrypt.getAbsolutePath()); 
    InputStream fis = new FileInputStream(source); 
    InputStream enIn = new FileInputStream(tmpEncrypt); 
    OutputStream fos = new FileOutputStream(tmpEncrypt); 
    OutputStream clearOut = new FileOutputStream(output); 
    CipherInputStream cis = new CipherInputStream(enIn, dCipher); 
    CipherOutputStream cos = new CipherOutputStream(fos, eCipher); 

    //Encrypt 
    Log.write("Starting encryption process"); 
    int numRead = 0; 
    byte[] buffer = new byte[1024]; 
    while ((numRead = fis.read(buffer)) >= 0) { 
     cos.write(buffer, 0, numRead); 
    } 

    cos.close(); 
    fos.close(); 
    Log.write("Done!"); 

    Log.write("Encrypted hash: " + Util.checksum(output)); 

    //Decrypt 
    Log.write("Starting decryption process"); 
    int nr = 0; 
    byte[] b = new byte[1024]; 
    while ((nr = cis.read(b)) >= 0) { 
     clearOut.write(buffer, 0, nr); 
    } 
    clearOut.close(); 
    cis.close(); 
    fis.close(); 
    Log.write("Done!"); 

    String fHash = Util.checksum(output); 
    Log.write("Final hash: " + fHash); 

    if(fHash.equals(oHash)) { 
     Log.write("Success! The hashes are equal!"); 
    } else { 
     Log.write("Failure! Hashes are different!"); 
    } 
} 

편집

: 나는 당신의 조언 @zaph했다, 지금은/쓰기에 문제가 파일을 읽을 것 같다. 파일의 길이는 정확히 40 바이트입니다. 16 진수 덤프는 다음과 같습니다.

Key hex: 000074657374696e676b65797364617767313233 
IV hex: 0000000000000000000000000000000000000000 
Data IN: Lorem ipsum dolor sit amet orci aliquam. 
Data OUT: Lorem ipsum dolor sit amet orci Lorem ip. 

이상한 것은 처음 8 바이트를 반복하여 마지막 8 바이트를 덮어 쓰는 것 같습니다. 내 버퍼 크기를 1024 바이트에서 8 바이트로 조정 해 보았는데, 낯선 사람이 있습니다./

Key hex: 000074657374696e676b65797364617767313233 
IV hex: 0000000000000000000000000000000000000000 
Data IN: Lorem ipsum dolor sit amet orci aliquam. 
Data OUT: aliquam.aliquam.aliquam.aliquam.aliquam. 

뭔가 첫 번째 읽고있는 방식에 분명히 잘못 썼다, 그러나 나는 무슨 일이 일어나고 있는지 단서를 가지고 있지 않습니다 진수 8 바이트 시험에서 덤프. 미리 감사드립니다.

+0

원래 파일과 해독 된 파일을 비교 했습니까? 첫 번째 해시는 원본 파일이 아니라 빈 대상 파일임을 유의하십시오. –

+0

길이가 최소 40 바이트 인 짧은 파일 인 최소 테스트 케이스를 만듭니다. 16 진수로 암호화, 암호 해독을 위해 키, iv 및 데이터를 덤프합니다. 불일치를 비교합니다. 문제를 찾을 수없는 경우 질문에 모두 추가하십시오. – zaph

+0

질문을 업데이트했습니다. 지금까지 도움을 주셔서 감사합니다. – user13356

답변

2

해결했습니다! while 루프에 문제가 발생했습니다. 이와 같이 :

그래서 대신 for 루프로 바꾸면 모든 것이 작동합니다.

int segs = (int) (source.length()/4); 
for (int i = 0; i < segs; i++) { 
    fis.read(buffer); 
    cos.write(buffer, 0, buffer.length); 
} 
관련 문제