한때 하이브리드 앱이 유행했지만 성능문제로 어느 이상을 커지지는 못했습니다. 그러던 와중에 React Native가 나오면서 다시 하나의 코드로 여러 플랫폼을 지원하는 방식이 탄력을 받고 있습니다.
저도 React Native등을 써서 한번의 코딩으로 iOS와 안드로이드 모두를 지원하고 싶은 생각은 간절하지만, 같이 일하는 기획자가 그렇게 만들어진 앱의 느낌에 만족하지 못하는 고로, 더 많은 발전이 있기 전에는 React Native로 넘어가지 못할 것 같습니다.
그렇지만 현재 만들고 있는 앱을 네이티브(Swift, Java등)로만 작성하고 있는 것은 아닙니다. UI/UX에 상관이 없고 자주 갱신되어야 하는 부분은 JavaScript로 작성해서 앱 업데이트 없이도 갱신할 수 있도록 하고 있습니다.
그런데 이 스크립트가 나름 앱의 핵심 노하우라고 여기고 있기에 외부에서 보지 못하도록 하고 싶었습니다. 물론 난독화(uglify)만으로도 분석이 어려워지긴 합니다. 그래도 간단한 암호화라도 추가 하고 싶어서 조금 찾아봤습니다.
암호화 종류를 살펴보기에 앞서 짚어볼 가장 중요한 점은 ‘100% 안전한 방법은 없다’ 입니다. 당연한 것이 이 스크립트는 언젠가 JavaScript 엔진이 이해할 수 있는 형태로 변환되어야 하기 때문입니다. 다만 적어도 단순히 ipa, apk를 푸는 것만으로 스크립트를 가져가는 것은 방지하고 싶었습니다.
암호화는 일단 크게 대칭 방식과 비대칭 방식이 있습니다.
대칭 방식은 암호화화 해독화를 같은 키로 하는 것입니다. 속도가 빠른 대신 키를 양측이 모두 알고 있어야 하기에 키가 노출될 가능성이 높습니다. 주요 알고리즘으로 AES가 있습니다.
비대칭 방식은 암호화화 해독화를 다른 키로 하는 것입니다. 속도가 느린 대신 해독화 키(비밀 키)를 나만 가지고 있기 때문에 노출될 가능성이 적어집니다. 주요 알고리즘으로 RSA가 있습니다.
반면 보안에 관련된 얘기에서 종종 나오곤 하는 MD5, SHA, HMAC등은 해시를 만들어내는 것으로, 원문이 변형되지 않았는지(무결성) 검사하기 위함이지 그 자체로 원문을 복원하지는 못합니다. 다만 ‘암호가 MD5로 저장되어서 원래 암호를 얻어냈다’ 같은 뉴스가 있는 것은 원문(암호)의 크기가 작기 때문에 높은 확률로 원문이라고 짐작되는 글을 알아냈다라는 것이지, 원문을 복원했다는 것은 아닙니다.
처음에는 내 키가 노출되는게 꺼려져서 RSA를 알아봤습니다. 그런데 RSA는 암호화하려는 데이터가 키보다 작아야 한다는 것을 알게 됐습니다. 그렇기에 원문 암호화는 AES로 하지만 그 키는 RSA로 암호화하는 방식등을 사용하는 것 같습니다.
그래서 스크립트는 AES로 암호화하기로 했습니다. 암호화 키는 RSA로 암호화를 하려다가 키를 얻기 위해 앱을 해킹한다면 어떻게 하든 알아낼 수 있을 것으로 판단해서, 암호화 키는 문자열로 바로 노출되는 것만 막는 정도로 처리하기로 했습니다.
다음에는 실제로 AES로 암호화 하는 방법에 대해서 알아보겠습니다.