본문 바로가기

Java & SpringFramework

Seed128 파일 암호화/복호화

SEED 암호화 할 때 0x00 갯수를 맞춰줘야한다.


FileStream으로 파일을 읽어왔을 때 바이트 사이즈에 맞춰 뒤에 0x00이 붙어 들어온다. (스트림에서 읽어올 byte 사이즈가 16배수면 OK.)


제일 마지막 읽어들인 것을 저장하고서 뒤에 0x00을 붙인 갯수를 저장한다. (1byte = 256까지표현가능)


복호화 할 때 파일사이즈를 스트림을 읽어올 byte 사이즈로 나눠 0x00 갯수를 저장한 바이트 전까지 읽어온다.


하나씩 읽어와 파일의 끝이 나올 때 까지 0x00 갯수를 센다.


마지막 읽어온 스트림에서 0x00의 갯수만큼 제외하고 write한다.



SeedFile Class


package seed;


import java.io.File;

import java.io.FileInputStream;

import java.io.FileOutputStream;

import java.util.Arrays;


public class SeedFile extends Seed {

private int BYTE_SIZE = 1024;

private byte[] buffer = new byte[BYTE_SIZE];


/**

* <pre>

* Seed128 암호화

* </pre>

* @param sbuffer

* @param szKey

* @return

*/

private byte[] encrypt(byte[] sbuffer, byte szKey[]) {

int sRoundKey[] = new int[Seed.NoRoundKeys];

Seed.SeedRoundKey(sRoundKey, szKey);


byte[] byteIV = { (byte) 0x26, (byte) 0x8D, (byte) 0x66, (byte) 0xA7, (byte) 0x35, (byte) 0xA8, (byte) 0x1A, (byte) 0x81, (byte) 0x6F, (byte) 0xBA, (byte) 0xD9, (byte) 0xFA, (byte) 0x36, (byte) 0x16, (byte) 0x25, (byte) 0x01 };


byte[] inDataBuffer = sbuffer;

byte[] encryptBytes = new byte[inDataBuffer.length];


byte sSource[] = new byte[Seed.SeedBlockSize];

byte sTarget[] = new byte[Seed.SeedBlockSize];


int rt = inDataBuffer.length / Seed.SeedBlockSize;

for (int j = 0; j < rt; j++) {

System.arraycopy(inDataBuffer, (j * Seed.SeedBlockSize), sSource, 0, Seed.SeedBlockSize);


// CBC 운영모드

Seed.exclusiveOR(sSource, byteIV);

Seed.SeedEncrypt(sSource, sRoundKey, sTarget);

byteIV = sTarget;


System.arraycopy(sTarget, 0, encryptBytes, (j * Seed.SeedBlockSize), sTarget.length);

}


return encryptBytes;

}


/**

* <pre>

* Seed128 복호화

* </pre>

* @param encryptBytes

* @param szKey

* @return

*/

private byte[] decrypt(byte[] encryptBytes, byte[] szKey) {

byte[] byteIV = { (byte) 0x26, (byte) 0x8D, (byte) 0x66, (byte) 0xA7, (byte) 0x35, (byte) 0xA8, (byte) 0x1A, (byte) 0x81, (byte) 0x6F, (byte) 0xBA, (byte) 0xD9, (byte) 0xFA, (byte) 0x36, (byte) 0x16, (byte) 0x25, (byte) 0x01 };


int sRoundKey[] = new int[Seed.NoRoundKeys];

Seed.SeedRoundKey(sRoundKey, szKey);


byte[] decryptBytes = new byte[encryptBytes.length];


byte sSource[] = new byte[Seed.SeedBlockSize];

byte sTarget[] = new byte[Seed.SeedBlockSize];


int rt = encryptBytes.length / Seed.SeedBlockSize;

for (int j = 0; j < rt; j++) {

System.arraycopy(encryptBytes, (j * Seed.SeedBlockSize), sSource, 0, Seed.SeedBlockSize);


Seed.SeedDecrypt(sSource, sRoundKey, sTarget);

// CBC 운영모드

Seed.exclusiveOR(sTarget, byteIV);

System.arraycopy(sSource, 0, byteIV, 0, Seed.SeedBlockSize);


System.arraycopy(sTarget, 0, decryptBytes, (j * Seed.SeedBlockSize), Seed.SeedBlockSize);

}


return decryptBytes;

}


/**

* <pre>

* Seed128 파일 암호화

* (지정한 경로에 암호화된 파일로 저장됨)

* </pre>

*

* @param file (암호화할 파일 객체)

* @param encryptionPath (암호화할 경로 [ex:"C:\\encriptionPath.dat"])

*/

public void encryptFile(File file, String encryptionPath) {


try {

FileInputStream in = new FileInputStream(file);


File wFile = new File(encryptionPath);

if (wFile.exists()) {

throw new Exception("File already exist.");

} else {

wFile.createNewFile();

}

FileOutputStream out = new FileOutputStream(wFile);


while (in.read(buffer) != -1) {

byte[] outBytes = encrypt(buffer, Seed.key);

out.write(outBytes);

}

int paddingCnt = (BYTE_SIZE - (int) (file.length() % BYTE_SIZE));

int setByteCnt = paddingCnt / 256;

for (int i = 0; i < setByteCnt; i++) {

out.write(256);

}

out.write(paddingCnt);


if (out != null) {

out.close();

}

if (in != null) {

in.close();

}

} catch (Exception e) {

e.printStackTrace();

}

}


/**

* <pre>

* Seed128 파일 복호화

* (지정한 경로에 복호화된 파일로 저장됨)

* </pre>

*

* @param file (복호화할 파일 객체)

* @param decryptionPath (복호화할 경로 [ex:"C:\\decriptionPath.txt"])

*/

public void decryptFile(File file, String decryptionPath) {


try {

FileInputStream in = new FileInputStream(file);


File wFile = new File(decryptionPath);

if (wFile.exists()) {

throw new Exception("File already exist.");

} else {

wFile.createNewFile();

}

FileOutputStream out = new FileOutputStream(wFile);

int cnt = (int) (file.length() / buffer.length);

int eof = 0;

byte[] outBytes = null;

for (int i = 0; i < cnt; i++) {

eof = in.read(buffer);

outBytes = decrypt(buffer, Seed.key);

if (i != cnt - 1) {

out.write(outBytes);

}

}

int paddingCnt = 0;

while ((eof = in.read()) != -1) {

if (eof == 0) {

paddingCnt += 256;

} else {

paddingCnt += eof;

}

}

byte[] lastBytes = new byte[buffer.length - paddingCnt];

lastBytes = Arrays.copyOfRange(outBytes, 0, buffer.length - paddingCnt);


out.write(lastBytes);


if (out != null) {

out.close();

}

if (in != null) {

in.close();

}


} catch (Exception e) {

e.printStackTrace();

}


}


}






Main


public static void main(String[] args) {

SeedFile seed = new SeedFile();

seed.setKey(new String("inbin_inbin_seed").getBytes());


File rFile = new File("E:\\download\\test.xlsx");

seed.encryptFile(rFile, "E:\\download\\test");


File rFile2 = new File("E:\\download\\test");

seed.decryptFile(rFile2, "E:\\download\\test_2.xlsx");

  }