인코딩, 해싱, 암호화의 차이

참고
https://www.udemy.com/course/spring-boot-and-spring-framework-korean/learn/lecture

인코딩

인코딩은 데이터를 원래 형식에서 다른 형식으로 변환하는 것이다. 인코딩에서는 키(key)를 사용하지 않으며 가역적이다. 인코딩 알고리즘으로 인코딩된 텍스트를 생성하고 디코딩 알고리즘을 통해 인코딩된 텍스트에서 실제 텍스트를 해독한다. 텍스트를 인코딩한 후 실제 텍스트로 다시 바꿀 수 있다.
일반적으로 인코딩은 데이터 보안에 사용되지 않는다. 데이터를 압축하거나 스트리밍하여 효율적으로 전송하거나 저장하는 것이 목적이다. 그 예로 Base 64, Wav, MP3 등이 있다.

해싱

해싱은 고유한 해싱 알고리즘을 기반으로 데이터를 해시 문자열로 변환한다. 해싱은 단방향 프로세스이고 비가역적이어서 해시로 변환하고 나면 원래 데이터를 구할 수 없다.
해싱은 데이터 무결성을 검증하는 것이 목적이다. 일반적으로 데이터와 해시를 모두 저장하고 데이터 전송이 필요한 경우에는 데이터와 해시를 함께 전송한다. 수신 측에서도 데이터를 해싱한 후 이 해시가 데이터와 일치하는지 확인한다.
해시를 이용하는 대표적인 활용 사례는 패스워드를 저장할 때이다. 데이터와 데이터의 해시를 함께 전송하면 수신 측에서는 데이터를 받고 해싱한 후 계산한 해시와 원래 메시지의 해시가 일치하는지 확인한다. 이를 통해 메시지가 전송한 시점 그대로인지 확인할 수 있다. 대표적인 해싱 알고리즘으로 bcrypt와 scrypt가 있다.
예를 들어 데이터베이스에 패스워드를 저장할 때, 평문 그대로 저장할 경우 누군가 데이터베이스에 액세스해서 평문 암호를 획득할 수 있다. 그래서 패스워드를 저장할 때 해싱을 이용한다. 해싱 알고리즘으로 패스워드를 해싱한 후 데이터베이스에 저장하는 것이다. 예를 들어, Henry라는 사용자의 경우 패스워드는 12345678이지만 데이터베이스에 저장된 것은 해싱된 값인 hd23dd23이다. 그럼 인증은 어떻게 이루어질까? Henry가 로그인을 시도하면 패스워드를 확인해 해싱한다. 그리고 이 해싱된 값을 데이터베이스에 저장된 해시와 비교한다. 즉, 전송받은 데이터를 해싱하여 데이터베이스에 저장된 패스워드 해시키와 일치하는지 확인하는 것이다. 두 값이 일치하면 Henry의 로그인이 허용된다.

암호화

암호화는 특정한 암호화키와 암호화 알고리즘을 사용해 암호화된 데이터를 생성한다. 암호화된 데이터는 암호화키와 복호화 알고리즘이 있어야 원래 데이터를 얻어낼 수 있다.
암호화는 데이터 보호하는 것이 목적이다. 인코딩과는 달리 특정한 키가 필요하다. 암호화의 예로 RSA가 있다.

권장

최근 보안에 대해 중요한 문제 중 하나는 최신 시스템이 매우 강력해져서 짧은 시간 동안 방대한 양의 계산을 수행할 수 있다는 것이다. 그래서 SHA-256 같은 해싱 알고리즘은 더 이상 안전하지 않다. 왜냐하면 최신 시스템들은 SHA-256을 이용해 1초도 안 되는 시간에 수십억 개의 해시 계산을 수행할 수 있기 때문이다.

Spring Security에서는 패스워드를 저장할 때, 워크 팩터를 적용해 적응형 단방향 함수를 사용하는 것이 권장된다.
단방향 함수는 해싱 알고리즘과 같이 데이터에서 해시를 생성하지만 해시에서는 데이터를 구할 수 없는 것과 같이 한 방향으로 작동하는 함수이다.
워크 팩터는 시스템에서 패스워드를 확인하는 데 걸리는 시간을 의미한다. 패스워드를 해싱하고 이것을 저장된 값과 비교하는 데 걸리는 시간이다. 여기에 상당한 양의 작업이 필요하기 때문에 시스템에서 패스워드를 확인하는 데 최소 1초가 소요된다.

일반적인 알고리즘은 빠를수록 성능이 좋다고 하지만, 패스워드 저장의 경우 해싱이 매우 빠르게 이루어진다면 다른 사람이 해싱을 수행하고 브루트 포스 알고리즘을 적용할 수 있기 때문에 해싱 알고리즘이 너무 빨리 작동하는 것은 바람직하지 않다.