Tistory View
이전에 포스트한 (C/C++)버전의 PHP버전이다.
하지만 이글을 바로 읽는 독자가 있을 수 있으니...
명령줄에서 다음과 같이 암호화 작업을 했다면
openssl enc -e -aes-256-cbc -in plain.txt -out encrypted.data -k "my_password"
이렇게 생성된 파일을 복호화하는 코드를 작성해 보자.
실제 위의 명령줄은 문제가 많지만, 처음 openssl을 접하는 사용자는 위의 명령을 통해 암호화작업을 많이 하게 될 것이다. 그러다 보니, 이 문제많은 방식에서 다른 방식으로 변경할 경우 일단 복호화작업을 해야 하니, 복호화 프로그래밍도 익힐 겸 복호화하는 코드를 생성해보자.
저장된 파일의 구조는 이전 포스트에서도 언급했듯이 다음의 구조를 가진다.
검은색 부분에 "Salt__"(8bytes)가 있으며, 이어서 실제 Salt값(노란색)이 8bytes가 따라온다.
그 다음 빨간색부분이 암호화된 데이터이다.
문제는 PHP에는 EVP_BytesToKey함수가 없다. 어쩔 수 없이, 온 세상을 뒤져보았지만, 찾긴 찾았는데... 그냥 만들어 쓰기로 했다.
PHP용 EVP_BytesToKey
function EVP_BytesToKey( $digest, $salt, $pass, $count, $keySize, $ivSize )
{
$reqSize = $keySize + $ivSize;
if( !$salt ) {
$salt = '';
}
$mall = '';
$pass .= $salt;
$mi = hash($digest, $pass, true);
for( $i = 1 ; $i < $count ; $i++ ) {
$mi = hash( $digest, $mi . $pass, true );
}
$mall = $mi;
while( strlen( $mall) < $reqSize )
{
$m2 = hash( $digest, $mi . $pass, true );
for( $i = 1 ; $i < $count ; $i++ ) {
$m2 = hash( $digest, $m2 . $pass, true );
}
$mall .= $m2;
$mi = $m2;
}
return array( 'key' => substr( $mall, 0, $keySize ), 'iv' => substr( $mall, $keySize, $ivSize ) );
}
나름 필자가 열심히 만들었는데.. 테스트를 하긴 했는 데, 솔직히 자신은없다..;;;;
이 함수를 호출하는 예제코드는 다음과 같다.
$keyiv = EVP_BytesToKey( 'sha256', $salt, "password", 1, 32, 16 );
echo 'key =', bin2hex( $keyiv['key'] ), "\n";
echo 'iv =', bin2hex( $keyiv['iv'] ), "\n";
aes-256-cbc를 이용하기 때문에 key길이는 32, iv길이는 16을 넘겨 주었다.
다음의 함수는 이 암호화된 파일의 내용(파일이 아니고)을 복호화하는 함수이다.
리턴값은 성공시 복호화된 데이터이며, 실패시에는 NULL을 반환한다.
function decrypt_def_openssl_encoded_content( $encrypted, $password, $iter )
{
$salt = '';
// salt때문에 크기는 16바이트보다 클 수밖에 없다.
if( strlen( $encrypted ) < 16 ) {
echo "file is too short < 16 bytes\n";
return NULL;
}
// salt값을 빼온다.
// "Salt__"라는 signature를 체크하는 부분은 생략했다.
$salt = substr( $encrypted, 8, 8 );
// salt와 넘어온 비밀번호로 key와 iv를 추출한다.
// 여기서는 md(message digest)로 sha256을 사용하지만, 구버전에서 만들어진 파일을 풀려면, md5를 넘겨야한다.
$keyiv = EVP_BytesToKey( 'sha256', salt, $password, $iter, 32,16 ) );
if( !$keyiv ) {
echo "extract key and iv failure\n";
return NULL;
}
return openssl_decrypt( substr( $encrypted, 16), 'AES-256-CBC', $keyiv['key'], OPENSSL_RAW_DATA, $keyiv['iv'] );
}
파일을 복호화
// count 값으로 1을 넣었는 데, 이는 openssl명령이 이 값을 1로 처리하고 있어서다.
echo decrypt_def_openssl_encoded_content( file_get_contents('파일이름'), '비밀번호', 1 );
만약 -iter 나 -pbkdf2 를 지정하였다면 위의 EVP_BytesToKey함수 대신에 다음과 같이 적절히 교체해서 사용하면 된다.
$keyiv = openssl_pbkdf2 ( $password , $salt , 32 + 16, $iter, 'sha256' );
$key = substr( $keyiv, 0, 32 );
$iv = substr( $keyiv, 32, 16 );
기본 openssl명령은 openssl_pbkdf2함수를 이용해서 한번에 key와 iv를 만들어 나눠서 사용하고 있다.
'openssl' 카테고리의 다른 글
복호화(C/C++) : aes256 cbc openssl (0) | 2020.03.23 |
---|---|
명령줄 : aes256 cbc openssl (2) | 2020.03.23 |
- Total
- Today
- Yesterday
- gpgpu
- TTS
- 컴퓨트쉐이더
- 재태크
- 에어컨
- 금리
- 전기요금
- choreographer
- 텍스처
- 안드로이드
- 경제보복
- Android
- 전기세
- 애드핏
- 에어콘
- 전기료
- 컴퓨트셰이더
- 애드센스
- OpenGLes
- OpenGL ES
- 재테크
- texture
- 블로그
- 공유 컨텍스트
- 사용료
- 적금
- 아끼는 법
- 예금
- 티스토리
- ComputeShader
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 | 29 |
30 | 31 |