암호 및 비용에 관한 학사 학위 논문을 작성하고 있습니다.Java에서 CipherOutputStream을 사용하면 암호화 된 파일이 손상됩니다.
그 중 일부는 런타임 및 리소스 비용면에서 서로 다른 암호화 알고리즘 및 암호 모드를 비교하는 것입니다. 이를 위해 나는 네 단계로 작동합니다 작은 도구 썼다 :
- 읽기 입력 파일
- 암호화 입력 파일을 새 파일에 기록.
- 방금 작성한 암호화 된 파일을 읽고 해독합니다.
- 해독 된 파일의 다른 복사본을 파일 시스템에 씁니다.
- 초기 입력 파일과 암호 해독 된 파일을 비교하여 파일이 동일한 지 확인하십시오.
작은 .txt 입력 파일로 잘 작동합니다. 하지만 어떤 이유로 다른 파일과는 작동하지 않습니다. 이미지를 입력 파일로 사용하면 처음 몇 픽셀이 좋고 나머지는 손상됩니다. 그래서 내가 암호를 초기화하거나 스트림을 사용할 때 문제가 어떻게 든 이해해야합니다. 필자는 줄의 암호화와 해독에 대해 주석을 달아 봤지만 똑같은 입력 파일의 일반 복사본을 만들 때도 작동합니다.
제안 사항은 언제든지 환영하며, 가능한 빨리 테스트하고 결과가 나타나는지 다시보고하려고합니다. "헝가리 표기법"에 사과드립니다. p는 공용으로 사용하고 l은 로컬로 사용합니다. 그것은 우리 회사에서하는 방식입니다. 실수
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Date;
import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
public class AES_Cipher_Test {
public String pLocalRef = "E:\\Test.txt";
public String pLocalRefOutput = "E:\\Test-crypted.txt";
public String pLocalCopyOutput = "E:\\Test-Neu.txt";
public Key pKeyAES = null;
public int pBitKey = 128;
public Cipher pCipher;
public FileOutputStream pFos;
public FileInputStream pFis;
public CipherOutputStream pCos;
public CipherInputStream pCis;
public File pInputFile = new File(this.pLocalRef);
public File pOutputFile = new File(this.pLocalRefOutput);
public File pGeneratedFile = new File(this.pLocalCopyOutput);
public AES_Cipher_Test() {
crypt_decrypt_write_File();
}
public void crypt_decrypt_write_File() {
byte[] lLoadedFile = null;
byte[] lGeneratedFileByte = null;
try {
// generate new random AES Key
KeyGenerator lKeygen = KeyGenerator.getInstance("AES");
lKeygen.init(this.pBitKey);
this.pKeyAES = lKeygen.generateKey();
// read input File
this.pFis = new FileInputStream(this.pInputFile);
FileInputStream tempStream = new FileInputStream(this.pInputFile);
int count = 0;
while (tempStream.read() != -1){
count ++;
}
lLoadedFile = new byte[count]; // new byte[this.pFis.available()]
this.pFis.read(lLoadedFile);
System.err.println("lLoadedFile.legth " + lLoadedFile.length);
this.pFis.close();
//init Cipher with AES Encrypt Mode CFB8 oder CTR
this.pCipher = Cipher.getInstance("AES/CTR/PKCS5Padding");
this.pCipher.init(Cipher.ENCRYPT_MODE, this.pKeyAES);
// build cipher stream from FileOutputStream
this.pFos = new FileOutputStream(this.pOutputFile);
this.pCos = new CipherOutputStream(this.pFos, this.pCipher);
//write encrypted Data to stream
this.pCos.write(lLoadedFile);
this.pCos.close();
this.pFos.close();
// init Cipher for decrypt Mode
this.pCipher.init(Cipher.DECRYPT_MODE, this.pKeyAES, new IvParameterSpec(this.pCipher.getIV()));
// read just written localFile and decrypt
this.pFis = new FileInputStream(this.pOutputFile);
tempStream = new FileInputStream(this.pOutputFile);
count = 0;
while (tempStream.read() != -1){
count ++;
}
byte[] lBytes = new byte[count];// new byte[this.pFis.available()]
this.pCis = new CipherInputStream(this.pFis, this.pCipher);
int lBytesRead = this.pCis.read(lBytes);
while (lBytesRead > -1) {
lBytesRead = this.pCis.read(lBytes);
}
this.pCis.close();
this.pFis.close();
System.err.println("lBytes.length " + lBytes.length);
// write new not crypted File to see if procedure works
this.pFos = new FileOutputStream(this.pLocalCopyOutput);
this.pFos.write(lBytes);
this.pFos.close();
//compare Input File and Output File
this.pFis = new FileInputStream(this.pGeneratedFile);
tempStream = new FileInputStream(this.pGeneratedFile);
count = 0;
while (tempStream.read() != -1){
count ++;
}
lGeneratedFileByte = new byte[count]; // new byte[this.pFis.available()]
int i = this.pFis.read(lGeneratedFileByte);
this.pFis.close();
System.err.println("lGeneratedFileByte.length " + i);
System.err.println("Test if initial File and new File are identical = " + Arrays.equals(lGeneratedFileByte, lLoadedFile));
} catch (FileNotFoundException e) {
throw new RuntimeException("FILE_DOES_NOT_EXIST", e);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[]) {
System.err.println("Start AES_Cipher_Test");
long start = new Date().getTime();
new AES_Cipher_Test();
long runningTime = new Date().getTime() - start;
System.err.println("End AES_Cipher_Test");
System.err.println("Runtime: " + runningTime);
}
}
Java에서는 헝가리 표기법을 사용하지 않아야합니다. 그것은 완전히 불필요합니다. Java 식별자의 유형은 선언을 읽음으로써 판별 할 수 있습니다. 자바는 스타일 가이드를 가지고 있습니다. 다른 사람들이 코드를 읽으려면 스타일 가이드를 따라야합니다. –
'while (lBytesRead <= 0)'루프에 대한 편집이 원본보다 훨씬 더 적합합니다. 'read()'는 길이가 0 인 버퍼를 제공하면 0을 리턴 할 수 있고, 스트림의 끝에서는 -1을 리턴 할 수 있습니다. 어떤 경우에도 루프를 만드는 것이 의미가 없으며 어떤 경우도'read()'가 버퍼를 채우지 못하는 경우를 보완하지 못합니다. 귀하의 성명서 "버퍼 크기와 읽기/쓰기가 문제가되지 않는 것만 큼 잘 작동하는 파일을 복사하지 않는 것"이 * 비 연속입니다.* 당신이 여기에 오는 대답에 대해 조금이라도주의를 기울이지 않으면, 나는 게시 지점을 전혀 보지 못합니다. – EJP
@StephenC 표기법에 대해 유감스럽게 생각하지만, 회사 표준을 사용하도록 요구되었습니다 ... – jonny