대칭키 암호화 알고리즘은 비트나 바이트, 워드 단위로 암호화하는 스트림(stream) 암호와 일정한 크기의 블럭을 단위로
암호화하는 블럭 암호 알고리즘으로 구분된다.
앞에서 예제로 보인 DES, SEED, AES와 같은 알고리즘은 블럭 단위로 암호화하는 알고리즘이다.
몇블럭씩 암호화할 것인지에 대해서는 알고리즘별로 차이를 보이는데 SEED와 같은 알고리즙은 128비트(16바이트) 단위로 암호화를 하게 된다.
다행히 암호화를 할 데이터가 16바이트 단위로 나눠진다면 몰라도 데이터는 항상 15바이트나 17바이트처럼 모자라거나 넘치기 마련이다. 블럭 암호화 알고리즘에서는 이렇게 모자라거나 넘치는 문제를 해결하기 위하여 16바이트 단위로 만들기 위해 임의의 숫자를 암호화할 데이터에 추가하게 되는데 이를 Padding이라고 한다. 따라서 15바이트 데이터는 1바이트를 Padding하여 16바이트 블럭으로 만들것이며, 17바이트처럼 넘치는 데이터는 15바이트를 Padding하여 32바이트를 만들게 된다.
앞의 예제에서 PaddedBufferedBlockCipher 라고 선언한 부분은 바로 블럭 암호화 알고리즘이면서 Padding까지 하겠다는 의미이다.
Padding을 하지 않을 경우라면 16바이트 단위로 암호화할 데이터를 인위적으로 가공을 개발을 해주어야 한다.
블럭암호화 알고리즘은 Padding이라는 절차의 문제로 평문보다 최대 16바이트 길이가 늘어날 수 있다는 것을 감안해야 한다.
스트림사이퍼의 경우는 블럭단위가 아니라 비트 단위 XOR 연산을 수행하기 때문에 별도의 Padding 절차가 필요없으며 따라서 평문이나 이를 암호화한 암호문이나 데이터의 길이가 동일하고 키 길이를 마음대로 지정할 수 있다는 장점이 있다.
아래는 대표적인 스트림 암호화 알고리즘인 RC4에 대한 예제이다.
import org.bouncycastle.crypto.StreamCipher;
import org.bouncycastle.crypto.engines.RC4Engine;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Base64;
...(중략)...
//스트림 암호화에서 키길이는 반드시 16바이트를 고집할 필요는 없지만...
byte[] key = {(byte)0x01,(byte)0x02,(byte)0x03,(byte)0x04,(byte)0x05,(byte)0x06,(byte)0x07,(byte)0x08,
(byte)0x09,(byte)0x10,(byte)0x11,(byte)0x12,(byte)0x13,(byte)0x14,(byte)0x15,(byte)0x16};
byte[] data = "12345대한민국asdddddddddddddddddddddddddd".getBytes();
//스트림 암호화 시작
StreamCipher cipher = new RC4Engine();
cipher.init(true, new KeyParameter(key));
byte[] out = new byte[data.length];
try {
cipher.processBytes(data, 0, data.length, out, 0);
} catch (Exception e) {
throw new Exception("암호화 오류가 발생하였습니다.올바른 키로 암호화하였는지 확인하십시오");
}
System.out.println("암호화된 데이터의 길이 ="+out.length);
System.out.println(new String(Base64.encode(out)));
//스트림 복호화 시작
cipher.init(false, new KeyParameter(key));
byte[] out2 = new byte[out.length];
try {
cipher.processBytes(out, 0, out.length, out2, 0);
} catch (Exception e) {
throw new Exception("복호화 오류가 발생하였습니다.올바른 키로 복호화하였는지 확인하십시오");
}
System.out.println("복호화된 데이터의 길이 ="+out2.length);
System.out.println(new String(out2));
...(중략)...
스크랩:http://blog.paran.com/blog/detail/postBoard.kth?blogDataId=35205253&pmcId=javacipher&totalCount=13&preViewPage=0&ajaxPage=1&preFBlogId=35385570&preLBlogId=27788506&pageStyle=null&myCateId=0&yearMonth=null&rDay=null&style=Board&p_eye=