Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

다양하게 활용 가능한 암호화 클래스 추가 #1650

Closed
wants to merge 3 commits into from
Closed

다양하게 활용 가능한 암호화 클래스 추가 #1650

wants to merge 3 commits into from

Conversation

kijin
Copy link
Contributor

@kijin kijin commented Jul 17, 2015

전반적인 보안 개선 PR 제3탄입니다. 아마 이게 마지막이 될 것 같네요 ^^

몇 달 전 비밀번호 암호화 개선 PR이 적용된 후, 패치에 포함된 난수생성기를 활용한 다양한 기능 개선이 있었습니다. 자동로그인 인증키, 아이디/비번찾기 인증키, 비공개 파일의 랜덤 파일명 등을 예측하기가 훨씬 어려워졌죠.

이 PR은 암호화 기능 강화의 연장선상에서, 흔히 사용되는 암호화 관련 기능들을 코어에 포함시키자는 제안입니다. 자료실에 서드파티 암호화 모듈이 있긴 하지만, 따로 설치해야 하고 설정 방법이 복잡해서 정작 강력한 보안이 필요한 코어 모듈에서는 사용하기 어려운 형편이거든요. 그래서 암호화 모듈을 과감하게 단순화하고, 다양하게 활용할 수 있는 디지털 서명 (digital signature) 기능을 추가했습니다.

개요

이 PR의 목표는 아래와 같습니다.

  • 자타공인 모범답안이라고 할 수 있는 defuse/php-encryption 라이브러리와 100% 호환되는 AES 알고리듬을 사용하되, PHP 5.4 미만인 서버와 openssl 대신 mcrypt 모듈이 설치된 서버에서도 사용 가능하도록 구현함
  • 마찬가지로 defuse/php-encryption 라이브러리에서 사용하는 SHA-256 기반의 HMAC 알고리듬을 사용하여 디지털 서명 기능 제공
  • 모든 암호화 키는 자동으로 생성 및 관리하여 코어의 다른 클래스나 최종 사용자는 전혀 신경쓸 필요가 없도록 함

조금 더 설명드리자면

  • 암호화(encryption)는 데이터를 읽을 수 없도록 숨기는 방법입니다. 암호화할 때 사용한 키를 갖고 있는 사람만 복호화(decryption)하여 읽을 수 있습니다. 키를 갖고 있지 않은 사람은 데이터를 읽을 수도 없고 위변조할 수도 없습니다.
  • 디지털 서명(digital signature)은 데이터를 숨기지는 않지만 위변조를 막을 수 있는 방법입니다. 예를 들어 어떤 변수를 폼에 넣었다가 다시 받을 때, 디지털 서명을 함께 넣으면 사용자가 브라우저의 개발자도구 등을 사용해서 해당 변수를 위변조하더라도 쉽게 파악할 수 있습니다.

이걸 어디다 쓰냐고요?

  • 장기적으로 서드파티 모듈에 의존하지 않고도 코어 자체에서 개인정보 암호화 등의 기능을 구현할 수 있게 됩니다.
  • 폼을 통해 전달하는 데이터의 위변조 방지를 위해 현재 세션에 의존하고 있는 부분을 암호화 또는 디지털 서명 방식으로 바꾸면 더이상 세션에 대량의 데이터를 저장할 필요가 없어져서 상당한 성능 향상을 기대할 수 있습니다. 예를 들어 지금은 에디터/업로더가 포함된 페이지를 읽을 때마다 세션에 upload_info가 무지막지하게 쌓이는데, 디지털 서명을 하면 이렇게 쌓아둘 필요가 없게 됩니다.
  • 그 밖에도 인증키를 메일로 전달한다든지, SSO와 같은 부분의 보안 향상이 가능합니다.

코드 예제

이 PR에 포함된 Crypto 클래스는 아래와 같은 기능을 제공합니다.

암호화

$oCrypto = new Crypto();
$original_text = 'Meet me at the clock tower at 4:30.';
$encrypted_text = $oCrypto->encrypt($original_text);

복호화

$oCrypto = new Crypto();
$original_text = $oCrypto->decrypt($encrypted_text);
if ($original_text === false)
{
    // 복호화 실패! 위변조가 의심됨
}
else
{
    // 정상
}

서명 작성 ($data를 폼에 넣기 전에)

$oCrypto = new Crypto();
$data = 'foo=1&bar=2&monkeybutt=red';
$signature = $oCrypto->createSignature($data);

서명 확인 ($data$signature를 폼에서 돌려받은 후)

$oCrypto = new Crypto();
if (!$oCrypto->verifySignature($signature, $data))
{
    // 서명이 틀림! $data가 위변조되었음
}
else
{
    // 정상
}

현재 세션에서만 유효한 암호화 또는 서명 작성 (암호화 키의 일부를 세션에 저장하여, 다른 세션에서는 복호화 또는 서명 확인이 불가능하도록 만듬)

$oCrypto->currentSessionOnly();

그 밖의 기술적 정보

현재 세션에서만 유효한 암호화 키는 각 세션에 저장됩니다. 세션과 무관하게 사이트 전체에서 유효한 암호화 키는 files/config/crypto.config.php에 저장됩니다.

암호화 키와 암호화 결과는 base64 인코딩하여 반환합니다. 이것을 base64_decode()하면 defuse/php-encryption 라이브러리에서도 복호화가 가능합니다. 마찬가지로, defuse/php-encryption 라이브러리에서 암호화한 결과도 base64_encode()만 해주면 이 PR의 Crypto 클래스에서 복호화가 가능합니다. 즉, 사실상의 표준인 defuse/php-encryption 라이브러리를 추후 적용하더라도 아무 문제가 없을 예정입니다.

서버에 openssl 모듈이 설치되어 있는 경우 성능이 훨씬 향상됩니다. 그러나 mcrypt 모듈로도 동일한 결과를 얻을 수 있습니다. 두 모듈 중 아무 것도 설치되어 있지 않은 경우에는 암호화 클래스 사용이 불가능합니다.

@dorami
Copy link
Contributor

dorami commented Jul 17, 2015

Travis CI에 문제가 있었나요?

@kijin
Copy link
Contributor Author

kijin commented Jul 17, 2015

@dorami 네, Travis CI가 오늘따라 말썽인 것 같습니다. 바로 위의 PR도 똑같네요.

@dorami
Copy link
Contributor

dorami commented Jul 17, 2015

@kijin 님이 오류를 낼 분이 아닌데 .. Error 표시가 돼있어서..

@kijin
Copy link
Contributor Author

kijin commented Jul 17, 2015

@dorami 저 너무 믿지 마세요. 지난번(#1590)에도 사고 쳤어요 ㅎㅎ

물론 이번에는 훨씬 꼼꼼하게 테스트를 했고, defuse/php-encryption을 사용하여 검증했기 때문에 큰 문제가 생길 가능성은 희박합니다 ^^

@kijin
Copy link
Contributor Author

kijin commented Aug 9, 2015

@qw5414 관련없는 PR과 관련된 질문은 해당 PR에 달아주시기 바랍니다. 닫혔어도 댓글을 달면 원래 작성자에게 알림이 갑니다.

@bjrambo
Copy link
Contributor

bjrambo commented Aug 10, 2015

@kijin 헛관련 없던 내용이였나보군요 죄송합니다 ( _ _)

@kijin kijin closed this Sep 3, 2015
@kijin kijin deleted the feature/crypto-in-core branch August 12, 2016 05:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants