{"action":"created","issue":{"url":"https://api.github.com/repos/xpressengine/xe-core/issues/1650","labels_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1650/labels{/name}","comments_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1650/comments","events_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1650/events","html_url":"https://github.com/xpressengine/xe-core/pull/1650","id":95573963,"number":1650,"title":"다양하게 활용 가능한 암호화 클래스 추가","user":{"login":"kijin","id":164058,"avatar_url":"https://avatars.githubusercontent.com/u/164058?v=3","gravatar_id":"","url":"https://api.github.com/users/kijin","html_url":"https://github.com/kijin","followers_url":"https://api.github.com/users/kijin/followers","following_url":"https://api.github.com/users/kijin/following{/other_user}","gists_url":"https://api.github.com/users/kijin/gists{/gist_id}","starred_url":"https://api.github.com/users/kijin/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kijin/subscriptions","organizations_url":"https://api.github.com/users/kijin/orgs","repos_url":"https://api.github.com/users/kijin/repos","events_url":"https://api.github.com/users/kijin/events{/privacy}","received_events_url":"https://api.github.com/users/kijin/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":7,"created_at":"2015-07-17T02:58:19Z","updated_at":"2015-08-10T00:59:55Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/xpressengine/xe-core/pulls/1650","html_url":"https://github.com/xpressengine/xe-core/pull/1650","diff_url":"https://github.com/xpressengine/xe-core/pull/1650.diff","patch_url":"https://github.com/xpressengine/xe-core/pull/1650.patch"},"body":"전반적인 보안 개선 PR 제3탄입니다. 아마 이게 마지막이 될 것 같네요 ^^\r\n\r\n몇 달 전 비밀번호 암호화 개선 PR이 적용된 후, 패치에 포함된 난수생성기를 활용한 다양한 기능 개선이 있었습니다. 자동로그인 인증키, 아이디/비번찾기 인증키, 비공개 파일의 랜덤 파일명 등을 예측하기가 훨씬 어려워졌죠.\r\n\r\n이 PR은 암호화 기능 강화의 연장선상에서, 흔히 사용되는 암호화 관련 기능들을 코어에 포함시키자는 제안입니다. 자료실에 서드파티 [암호화 모듈](https://www.xpressengine.com/index.php?mid=download&package_id=22753617)이 있긴 하지만, 따로 설치해야 하고 설정 방법이 복잡해서 정작 강력한 보안이 필요한 코어 모듈에서는 사용하기 어려운 형편이거든요. 그래서 암호화 모듈을 과감하게 단순화하고, 다양하게 활용할 수 있는 디지털 서명 (digital signature) 기능을 추가했습니다.\r\n\r\n개요\r\n------\r\n\r\n이 PR의 목표는 아래와 같습니다.\r\n\r\n- 자타공인 모범답안이라고 할 수 있는 [defuse/php-encryption](https://github.com/defuse/php-encryption) 라이브러리와 100% 호환되는 AES 알고리듬을 사용하되, PHP 5.4 미만인 서버와 `openssl` 대신 `mcrypt` 모듈이 설치된 서버에서도 사용 가능하도록 구현함\r\n- 마찬가지로 defuse/php-encryption 라이브러리에서 사용하는 SHA-256 기반의 HMAC 알고리듬을 사용하여 디지털 서명 기능 제공\r\n- 모든 암호화 키는 자동으로 생성 및 관리하여 코어의 다른 클래스나 최종 사용자는 전혀 신경쓸 필요가 없도록 함\r\n\r\n조금 더 설명드리자면\r\n\r\n- 암호화(encryption)는 데이터를 읽을 수 없도록 숨기는 방법입니다. 암호화할 때 사용한 키를 갖고 있는 사람만 복호화(decryption)하여 읽을 수 있습니다. 키를 갖고 있지 않은 사람은 데이터를 읽을 수도 없고 위변조할 수도 없습니다.\r\n- 디지털 서명(digital signature)은 데이터를 숨기지는 않지만 위변조를 막을 수 있는 방법입니다. 예를 들어 어떤 변수를 폼에 넣었다가 다시 받을 때, 디지털 서명을 함께 넣으면 사용자가 브라우저의 개발자도구 등을 사용해서 해당 변수를 위변조하더라도 쉽게 파악할 수 있습니다.\r\n\r\n이걸 어디다 쓰냐고요?\r\n\r\n- 장기적으로 서드파티 모듈에 의존하지 않고도 코어 자체에서 개인정보 암호화 등의 기능을 구현할 수 있게 됩니다.\r\n- 폼을 통해 전달하는 데이터의 위변조 방지를 위해 현재 세션에 의존하고 있는 부분을 암호화 또는 디지털 서명 방식으로 바꾸면 더이상 세션에 대량의 데이터를 저장할 필요가 없어져서 상당한 성능 향상을 기대할 수 있습니다. 예를 들어 지금은 에디터/업로더가 포함된 페이지를 읽을 때마다 세션에 `upload_info`가 무지막지하게 쌓이는데, 디지털 서명을 하면 이렇게 쌓아둘 필요가 없게 됩니다.\r\n- 그 밖에도 인증키를 메일로 전달한다든지, SSO와 같은 부분의 보안 향상이 가능합니다.\r\n\r\n코드 예제\r\n------------\r\n\r\n이 PR에 포함된 `Crypto` 클래스는 아래와 같은 기능을 제공합니다.\r\n\r\n암호화\r\n\r\n    $oCrypto = new Crypto();\r\n    $original_text = 'Meet me at the clock tower at 4:30.';\r\n    $encrypted_text = $oCrypto->encrypt($original_text);\r\n\r\n복호화\r\n\r\n    $oCrypto = new Crypto();\r\n    $original_text = $oCrypto->decrypt($encrypted_text);\r\n    if ($original_text === false)\r\n    {\r\n        // 복호화 실패! 위변조가 의심됨\r\n    }\r\n    else\r\n    {\r\n        // 정상\r\n    }\r\n\r\n서명 작성 (`$data`를 폼에 넣기 전에)\r\n\r\n    $oCrypto = new Crypto();\r\n    $data = 'foo=1&bar=2&monkeybutt=red';\r\n    $signature = $oCrypto->createSignature($data);\r\n\r\n서명 확인 (`$data`와 `$signature`를 폼에서 돌려받은 후)\r\n\r\n    $oCrypto = new Crypto();\r\n    if (!$oCrypto->verifySignature($signature, $data))\r\n    {\r\n        // 서명이 틀림! $data가 위변조되었음\r\n    }\r\n    else\r\n    {\r\n        // 정상\r\n    }\r\n\r\n현재 세션에서만 유효한 암호화 또는 서명 작성 (암호화 키의 일부를 세션에 저장하여, 다른 세션에서는 복호화 또는 서명 확인이 불가능하도록 만듬)\r\n\r\n    $oCrypto->currentSessionOnly();\r\n\r\n그 밖의 기술적 정보\r\n-------------------------\r\n\r\n현재 세션에서만 유효한 암호화 키는 각 세션에 저장됩니다. 세션과 무관하게 사이트 전체에서 유효한 암호화 키는 `files/config/crypto.config.php`에 저장됩니다.\r\n\r\n암호화 키와 암호화 결과는 base64 인코딩하여 반환합니다. 이것을 `base64_decode()`하면 defuse/php-encryption 라이브러리에서도 복호화가 가능합니다. 마찬가지로, defuse/php-encryption 라이브러리에서 암호화한 결과도 `base64_encode()`만 해주면 이 PR의 `Crypto` 클래스에서 복호화가 가능합니다. **즉, 사실상의 표준인 defuse/php-encryption 라이브러리를 추후 적용하더라도 아무 문제가 없을 예정입니다.**\r\n\r\n서버에 `openssl` 모듈이 설치되어 있는 경우 성능이 훨씬 향상됩니다. 그러나 `mcrypt` 모듈로도 동일한 결과를 얻을 수 있습니다. 두 모듈 중 아무 것도 설치되어 있지 않은 경우에는 암호화 클래스 사용이 불가능합니다.\r\n"},"comment":{"url":"https://api.github.com/repos/xpressengine/xe-core/issues/comments/129265508","html_url":"https://github.com/xpressengine/xe-core/pull/1650#issuecomment-129265508","issue_url":"https://api.github.com/repos/xpressengine/xe-core/issues/1650","id":129265508,"user":{"login":"qw5414","id":4381756,"avatar_url":"https://avatars.githubusercontent.com/u/4381756?v=3","gravatar_id":"","url":"https://api.github.com/users/qw5414","html_url":"https://github.com/qw5414","followers_url":"https://api.github.com/users/qw5414/followers","following_url":"https://api.github.com/users/qw5414/following{/other_user}","gists_url":"https://api.github.com/users/qw5414/gists{/gist_id}","starred_url":"https://api.github.com/users/qw5414/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/qw5414/subscriptions","organizations_url":"https://api.github.com/users/qw5414/orgs","repos_url":"https://api.github.com/users/qw5414/repos","events_url":"https://api.github.com/users/qw5414/events{/privacy}","received_events_url":"https://api.github.com/users/qw5414/received_events","type":"User","site_admin":false},"created_at":"2015-08-10T00:59:55Z","updated_at":"2015-08-10T00:59:55Z","body":"@kijin 헛관련 없던 내용이였나보군요 죄송합니다 ( _ _) "}}