본문 바로가기

PHP

[PHP] AES128/ECB 복호화 하기

이전 쓰레드에서 Java와 MySQL에서 AES128/ECB의 암호화/복호화 개발을 진행했습니다.
이번에는 PHP로 복호화하는 방법을 소개합니다.

사전에 php-encrypt 확장 모듈 설치가 필요합니다.
관련 글은 http://seongtak-yoon.tistory.com/49를 참고해주세요.
참고로 암호화된 데이터는 AES128/ECB -> Base64로 암호화되었습니다. 복호화는 당연히 반대로 Base64 -> AES128/ECB의 과정이 되어야합니다.

PHP에서 복호화 함수를 제공하고 있습니다. - http://php.net/manual/kr/function.mcrypt-decrypt.php
참고) base64_decode($encode_data)를 통해서 base64를 복호화한 후 이 데이터를 파라메터로 전달합니다.

public static function decrypt($stringKey, $encode_data) {
	$decode_data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $stringKey, $encode_data, MCRYPT_MODE_ECB);

	return rtrim($decode_data, "\x00..\x1F");
}
- 객체의 상태(멤버)는 없고 기능(메서드)만 가질 객체이기 때문에 static으로 메서드를 생성합니다.
- 뭐.. 네이밍은 decrypt했는데 더 명확하게 하는게 낫겠죠 (decryptByAES128ECB) 아니면
주입하는 방식으로 변경해 암호화 알고리즘, 모드를 파라메터로 전달하는 것도 좋고 모델 객체를 만들어도 좋습니다.
- MCRYPT_RIJNDAEL_128은 AES128을 사용하겠다는 의미, 대칭키, 암호화된 데이터, 암호화 모드로 생각하면 됩니다.
- ECB모드로 복호화하면 Warning이 뜨는데 ECB는 IV를 사용하지 않으므로 신경 안쓰셔도 됩니다.

그런데...마지막에 이상한게 있죠?
rtrim($decode_data, "\x00..\x1F");
- 복호화한 문자열 오른쪽에 0 ~ 31번의 아스키 코드 데이터를 제거하는 함수입니다.
- 이 기능을 넣은 이유는 원본 평문과 복호화된 문자가 겉으로는 동일하게 보이지만 상세 정보는 다른 이슈가 있기 때문입니다.

더 자세히 설명하자면..
원본 문자 상세 정보
- 타입 : string
- 길이 : 10
- 문자열 일치 비교 : 1
- 문자 출력 : abcdefghij

복호화 후
- 타입 : string
- 길이 : 16
- 문자열 일치 비교(===) : 0
- 문자 출력 : abcdefghij
아니.. 타입과 출력이 동일한데 길이와 일치 비교(===)의 결과가 다릅니다.
결국 보이지 않는 문자가 복호화 후 붙어 있다는 이야기입니다.
NULL(\0)을 제거하면 된다는 글도 있는데 제 케이스는 아스키 코드 0 ~ 31번 범위의 문자를 제거하니 동일한 문자를 가지더군요..