Skip to content

Instantly share code, notes, and snippets.

@cdecl
Created December 25, 2016 23:02
Show Gist options
  • Save cdecl/f8b25e753367cfb6be6b89fa75b086fb to your computer and use it in GitHub Desktop.
Save cdecl/f8b25e753367cfb6be6b89fa75b086fb to your computer and use it in GitHub Desktop.

암호화 알고리즘 사용

블록 알고리즘 고려사항

  • 대칭형 vs 비대칭형
  • 알고리즘 종류
  • 알고리즘 운영 모드
  • 패딩종류
  • 인코딩 (텍스트 암호화의 경우)

대칭형 vs 비대칭형

  • 대칭형 : 암호화 할때 사용하는 키와 복호화 할때 사용하는 키가 동일한 암호화 기법
  • 비대칭형 : 암호화 키와 복호화 키가 다르다, 대칭형 암호에 비해 현저하게 느리다는 문제점 (예,공개키 기반)

대칭형 블록 알고리즘

블록 단위로 암호화 하는 대칭키 암호 시스템

대칭형 블록 알고리즘 종류

DES

56비트 키
가장 오래되고, 세계적으로 가장 널리 사용되는 고전적 암호화 알고리즘이다. 파일이나 패킷을 암호화할 때 많이 사용된다. 하지만, 64비트 입력 블록과 56비트 짧은 비밀키를 사용하기 때문에, 더 이상 안전하지 않다고 간주하고 있다. 그러나, 국가 기밀을 다룰 정도로 극히 중요한 보안이 아니라면, 여전히 가장 널리 사용되는 알고리즘이다.

3-DES

2키를 사용하는 경우 112비트, 3키를 사용하는 경우 168비트의 키 길이
DES를 3번 반복해서 암호화한다. 보안성이 향상되고, 그 만큼 성능은 떨어진다.

AES

128/192/256비트 키
미국 NIST에서 공모해서 표준화한 새로운 알고리즘이다. 128비트 입력 블록을 도입함으로써, 보안성을 향상했으며, 최근에 세계적으로 널리 사용되는 알고리즘이다.

SEED

128비트
KISA 주관으로 ETRI와 함께 국내에서 만들어진 알고리즘이다.
128비트 입력 블록을 사용하고 있고, 국제 표준에 부합하는 알고리즘이다.

대칭형 블록 알고리즘 운영 모드

ECB(Electronic codebook)

평문을 일정 크기의 블록으로 나누어서 처리, 각 블록은 동일한 키로 암호

CBC(Cipher-block chaining)

평문 블록과 바로 직전의 암호블록을 XOR한 것. 첫번째 암호 블록을 위해 초기 벡터 IV 값 사용

기타
- PCBC(Propagating cipher-block chaining)
- CFB(Cipher feedback)
- OFB(Output feedback)
- CTR(Counter)

대칭형 블록 알고리즘 : 패딩(Padding) 종류

  • NO_PADDING : 패딩 없음
  • ZEROS_PADDING : NULL(0) 으로 패딩
  • PKCS_PADDING : 패딩되는 바이트의 수의 같은 값으로 모두 패딩
  • ONE_AND_ZEROS_PADDING : ONE_AND_ZEROS_PADDING to use 0x80 instead 0x01 as padding
DEFAULT_PADDING : DEFAULT_PADDING means PKCS_PADDING 
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


public class AES {
	public static void main(String[] args) {
		try{
			/* 16바이트 암호화 키 */
			int[] arrkey = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; 
			int[] arriv = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

			byte[] key = new byte[16];
			byte[] iv = new byte[16];

			for (int i = 0; i < 16; ++i) {
				key[i] = (byte)arrkey[i];
				iv[i] = (byte)arriv[i];
			}


			if (args.length != 1)
			{
				System.out.println("ASE [암호화문자열]");
				return;
			}

			String text = args[0];
			String encrypted = encrypt(text, iv, key);
			System.out.println("Java");
			System.out.println(encrypted );
			String decrypted = decrypt(encrypted,iv,key);
			System.out.println(decrypted );

		}
		catch (Exception e){
			e.printStackTrace();
		}
	}

	public static String encrypt(String text, byte[] iv, byte[] key) throws Exception{
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

		SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
		IvParameterSpec ivSpec = new IvParameterSpec(iv);

		cipher.init(Cipher.ENCRYPT_MODE,keySpec,ivSpec);
		byte [] results = cipher.doFinal(text.getBytes("euc-kr"));
		BASE64Encoder encoder = new BASE64Encoder();
		return encoder.encode(results);
	}

	public static String decrypt(String text, byte[] iv, byte[] key) throws Exception{
		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");

		SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
		IvParameterSpec ivSpec = new IvParameterSpec(iv);
		cipher.init(Cipher.DECRYPT_MODE,keySpec,ivSpec);

		BASE64Decoder decoder = new BASE64Decoder();
		byte [] results = cipher.doFinal(decoder.decodeBuffer(text));
		return new String(results,"euc-kr");

	}

}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment