다양한 관심 :)

Java - 암호화 (양방향) 본문

프로그래밍 공부/JAVA

Java - 암호화 (양방향)

뚜뚜:) 2020. 11. 23. 19:23

초기화 벡터(Initial Vector , IV) --> IV는 암호문이 패턴화 되지 않도록 사용되는 데이터를 말한다.
--> 첫 블록을 암호화 할 때 사용되는 값 --> CBC모드에서 사용된다.
--> 암호화를 할 때 다른 랜덤 비트열을 이용하는 것이 보통이다. (예시에서는 키값을 이용하여 만든다) 

// 양방향 암호화 알고리즘인 AES256 암호화 방식을 지원하는 클래스


// 초기화 벡터값이 저장 될 변수 
		private String iv;
		
		private Key keySpec;
		
		private static final String key = "a1b2c3d4e5f6g7h8";	//암호화 키값( 16글자 이상)
		
		//생성자
		// 16자리의 키 값을 이용하여 비밀키 객체를 생성한다.
		
		public AES256Utill() throws UnsupportedEncodingException {
			this.iv = key.substring(0,16);	//문자 16자리로 한다 
			
			byte[] keyBytes = new byte[16];	//암호화 키 값에 바이트 배열로 저장 
			byte[] b = key.getBytes("utf-8");	//인코딩 설정 
			int len = b.length;
			
			if(len>keyBytes.length) {
				len = keyBytes.length;
			}
			
			//앞에있는 b의 데이터에서 복사를 해와라 , len만큼 
            //-> 바이트 배열에서 0번째 부터 가져와서 keyBytes에 0번째 부터  붙여넣기
			System.arraycopy(b, 0, keyBytes, 0, len);
			
			//비밀 키 생성(SecretKeySpec)
			SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
			this.keySpec = keySpec;
			
		}
  •  Cipher라는 객체 생성 및 초기화 하기 
  •  "AES/CBC/PKCS5Pading" ==> "알고리즘/모드/패딩"
                
  •  CBC :  Cipher Block Chaining Mode  ==> 동일한 평문 블록과 암호문 블록 쌍이 발생하지 않도록 이전 단계의 복호화한 결과가 현 단계에 영향을 주는 운영 모드를 말한다.
     -  블록 암호화 운영모드 중 보안성이 가장 높은 암호화 방법으로 가장 많이 사용한다.
     -> 암호화가 병렬적으로 처리되는 것이 아니라 순차적으로 수행되어야 한다는 단점이 있다.

패딩 : Padding ==> 마지막 블록이 블록의 길이와 항상 딱 맞아 떨어지지 않을 수 있기 때문에 
족한 길이만큼을 '0'으로 채우거나 임의의 비트들로 채워넣는 것을 의미한다.
 예 ) 암호화를 했는데, 암호화를 해서 나오는 결과값이 100바이트로 나와야 한다 하면, 나머지의 값을 padding을 통하여 값을 채워넣는다

==>   알고리즘/모드/padding방식("AES/CBC/PKCS5Padding")

// AES256방식으로 암호화하는 메서드 
		
		// str 		==> 암호화 할 문자열 
		// 반환값 	==> 암호화 된 문자열 
		public String encrypt(String str) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
			
			
			Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
			
			byte[] ivBytes = new byte[16];
			System.arraycopy(iv.getBytes(), 0, ivBytes, 0, ivBytes.length);
		
			//옵션 종류 : ENCRYPT_MODE(암호화모드), DECRYPT_MODE(복호화모드)
			//		   WRAP_MODE(암호키를 캡슐화), UNWRAP_MODE(암호키 캡슐화 해제)
			
			
			// 암호를 옵션 종류에 맞게 초기화 한다.
			c.init(Cipher.ENCRYPT_MODE, keySpec, new IvParameterSpec(ivBytes));
			byte[] encrypted = c.doFinal(str.getBytes("utf-8"));	//암호문 생성 
			
			String enStr = Base64.getEncoder().encodeToString(encrypted);
			
			return enStr;
			}
// AES256방식으로 암호화된 문자열을 복호화하는 메서드
		// str  ==> 복호화 할 암호화된 문자열 
		// 반환값 ==> 복호화된 문자열 
        
public String decrypt(String str) throws NoSuchAlgorithmException, 
NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, 
UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
				
				//Cipher 객체 생성
				Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
				
				byte[] ivBytes = new byte[16];
				System.arraycopy(iv.getBytes(), 0, ivBytes, 0, ivBytes.length);
				
				c.init(Cipher.DECRYPT_MODE, keySpec, new IvParameterSpec(ivBytes));
				
				byte[] byteStr = Base64.getDecoder().decode(str);	//암호화된 데이터를 원래의 byte배열로 복원한다
				
				return new String(c.doFinal(byteStr), "utf-8");
			}
System.out.println("\n=========================================\n");
		System.out.println("양방향 암호화 ");
		AES256Utill aes256 = new AES256Utill();
		String str = aes256.encrypt(plainText);	//암호화를 하는것 
		System.out.println("원래의 데이터 : " + plainText );
		System.out.println("암호화 문자열 길이 : " + str.length()+"byte");
		System.out.println("AES256암호화 : " + str);
		System.out.println("AES256복호화 : " + aes256.decrypt(str));	//복호화 해주는 메서드 
		
		System.out.println("\n=========================================\n");

		String tmp = " ";
		for(int i=0; i<=9; i++) {
			for(int j=0; j<=9; j++) {
				tmp += j;
				str = aes256.encrypt(tmp);
				System.out.println("tmp ==> " + tmp);
				System.out.println("암호화 ==> " + str);
				System.out.println("암호화 길이 ==> " + str.length());
				String deStr = aes256.decrypt(str);
				System.out.println("복호화 ==> " + deStr);
				System.out.println();
			}
		}
		

encrypt() : 암호화를 하는것

decrypt() : 복호화를 하는것

'프로그래밍 공부 > JAVA' 카테고리의 다른 글

java - servlet ( 서블릿) 2  (0) 2020.11.26
java- servlet ( 서블릿 )  (0) 2020.11.26
Java - 암호화 (단방향)  (0) 2020.11.23
ibatis 환경 설정 - sqlMapConfig  (0) 2020.11.18
Java - iBatis  (0) 2020.11.18