암호화cryptography는 웹 개발자가 이용할 수 있는 가장 강력한 보안 도구 중 하나입니다. 암호화는 기본적으로 어떤 의미가 있는 정보를, 특정한 의도가 없다면 읽을 수 없는 잡음 같은 것으로 바꾸는 일입니다. 비교적 최근까지, 정부에서는 암호화 소프트웨어를 강하게 규제해 왔습니다. 그렇지만 암호화는 수학 연산일 뿐이며, 막겠다고 해서 막히는 것도 아닙니다. 형편없는 성능의 넷북 하나만 있어도, 정부 기관에서 겨우겨우 상상만 하던 수준의 암호화 시스템을 이용할 수 있습니다.
One of the most powerful security tools available to web developers is cryptography—essentially a process by which meaningful information is turned into random noise, unreadable except where specifically intended. Many governments tightly regulated cryptographic software until relatively recently. But cryptography is simply applied math, and it’s proved impossible to suppress. A web developer working on an underpowered netbook in his basement now has access to cryptosystems that major governments could only have dreamed of a few decades ago.
간단한 웹 어플리케이션이고, 신용카드 번호같이 해커들이 탐낼만한 정보는 다루지 않으니 높은 수준의 보안은 필요하지 않다고 생각하기 쉽습니다. 불행히도, 사람들은 여러 사이트에서 같은 비밀번호를 쓰는 경향이 있습니다. 이용하는 사이트 중 보안이 가장 취약한 곳 하나만 뚫려도, 나머지 사이트 다 뚫린 거나 마찬가지란 뜻이죠. 2009년에는, 트위터 관리직원 중 한 명의 이메일 계정을 알아내서 트위터 내부 시스템 상당수에 접근한 해커도 있었습니다.
It’s tempting to think that a simple web application doesn’t require industrial-strength security because it’s not going to contain any information worth stealing, like credit card numbers. Unfortunately, people’s tendency to reuse passwords across many different systems means that a compromise of the weakest one can often give access to the rest. In 2009, a hacker famously gained access to a number of internal systems at Twitter by compromising the email account of a single administrative assistant.
훌륭한 장인이 되려면 자신이 쓰는 도구와 자신이 다루는 재료에 대해 잘 알아야 합니다. 마찬가지로, 웹 개발자는 특정 상황에 걸맞은 암호화 방법에 대해 알아야 합니다 - 비록 그 암호화 알고리즘에 사용된 수학까지 자세히 알지는 못하더라도 말입니다. 암호화를 서툴게 적용하면 안 한 것이나 마찬가지고, 보안에 대한 잘못된 인식을 낳을 위험도 있습니다.
Just as any artisan must know his tools and materials to achieve excellence, it’s important for web developers to understand what types of cryptography work in specific contexts, even if we don’t need to grasp the details of the math involved. Poorly applied cryptography provides no benefit and might even be dangerous by creating a false sense of security.
암호화 시스템에는 여러 가지가 있지만, 웹 어플리케이션에 적용되는 것은 크게 세 가지로 나눌 수 있습니다.
There are many different types of cryptosystems, but three broad categories commonly relate to web applications.
일단 소시지를 만들면, 거기서 밀가루와 돼지고기를 추출하는 건 불가능합니다. 마찬가지로, 암호화에 사용하는 해시는 데이터를 받아서 엉망진창으로 흩트려 놓도록 고안되었습니다. 즉, 해시를 거친 데이터는 결코 인식할 수 없습니다. 절대로 그렇습니다. 여기까지 들으면 전혀 어려울것도 없고 쓸모도 없을 것 같지만 잘 디자인한 해시는 복잡하면서도 유용한 두 가지 특징이 있습니다.
You can’t start with a sausage and work backwards to produce the raw ingredients that went into it. In the same way, a cryptographic hash is designed to take in data and mangle it, so that what comes out the other end is unrecognizable—irreversibly so. Described this way, it doesn’t sound like a particularly difficult or useful operation. But well-designed hashes have two properties that make them both complex and useful.
먼저, 입력하는 데이터에 미미한 차이만 있어도 결과는 엄청나게 차이가 납니다. 달리 말하자면, 입력에서 한 글자를 바꾸면 해시 결과는 수십 글자가 바뀌는 거죠. 해시를 거친 데이터는 종종 일정한(그리고 비교적 짧은) 크기가 됩니다. 이런 특징 때문에, 종종 A를 넣어도 C가 나오고, B를 넣어도 C가 나옵니다. 따라서 어떤 해커도 해시의 결과만 가지고 원래 데이터를 알 수는 없습니다.
First, a small change in the input should make a drastic change in the output. In other words, changing one character in the data being hashed will change a lot more than one character of the output. Usually, hashes produce an output of fixed (and relatively short) length, regardless of the input size. This means that multiple inputs could theoretically produce the same result, making it impossible to know what the original data was if an attacker only has the hashed result to work with.
다음, 해시에 넣은 것이 같다면 나오는 것도 항상 같습니다. 해시를 가장 많이 쓰는 분야는 비밀번호 저장입니다. 사실은, 웹 어플리케이션은 사용자의 비밀번호 자체는 몰라도 됩니다 - 사용자가 비밀번호를 알고 있는지 확인할 뿐입니다. 비밀번호를 만들 때 해시를 거친 결과를 저장합니다. 로그인하려고 하면, 입력한 비밀번호를 똑같은 해시를 거치게 한 다음 비교합니다. 따라서, 설령 사용자 데이터베이스가 털려도, 해커가 그것만 가지고 끔찍스런 일을 할 수는 없습니다... 일단은 그렇게 생각할 수 있다는 얘기입니다만.
Second, a hash will always produce the same output when given the same input. The most obvious application for hashes is in the storage of passwords. A web application doesn’t really need to know a user’s password—it just needs to verify that the person requesting access knows the password. If we hash passwords the same way at the time of creation and login, we only have to store and compare the result of the hash operation to know that the originals are the same. Then, even if a user database is exposed, the attacker doesn’t have anything terribly useful to work with. At least, that’s the conventional wisdom.
현실은 그렇게 만만하지 않습니다. 첫째, 모든 해시 알고리즘이 같은 수준인 건 아닙니다. 한때 널리 쓰였던 MD5 알고리즘은 전반적으로 취약하다고 알려졌습니다. (비밀번호 암호화 정도라면 쓸만합니다.) 둘째, 흔한 비밀번호를 쓰는 사람이 너무 많습니다. 즉, 해커가 해시값 "123456" 이란 것이 몇 가지 널리 쓰이는 알고리즘 중 하나의 결과인 걸 알게 되면, 이건 뚫린 거나 마찬가지인 겁니다. 해시값을 미리 계산해 둔 테이블을 어디서든 쉽게 구할 수 있고, 보안 업계에서는 이걸레인보우 테이블이라 부릅니다.
In reality, it’s not quite that simple. First, not all hashing algorithms are created equal. The once-popular MD5 algorithm, for example, is now known to be cryptographically weak in general (although it’s still usable for passwords). Second, we know that a lot of people choose the same common passwords. This means that if an attacker knows the hash value of “123456” as produced by a few popular algorithms, he can easily recognize it in a database. Lists of pre-computed hashes are widely available and known in the security industry as rainbow tables.
이런 취약점을 보완하기 위해, 해시에 "소금을 칠" 수 있습니다. 위에서 설명한, 좋은 해시의 두 가지 특징을 생각해 보면, 서버에서 약간의 데이터를 사용자가 입력한 비밀번호에 덧붙인 다음 해시를 거치게 하는 겁니다. 이렇게 하면 아주 다른 결과를 얻게 됩니다.
To counter this weakness, a hash can be “salted.” Given the two properties of good hash algorithms described above, we can simply append a little data of our own to the user’s password and store the hash of that combined text rather than the password itself. This will create a completely different result that’s still easily verifiable.
다음을 비교해 보십시오:
Compare the following:
sha1('password')
=> 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
sha1('x5T1password')
=> e1f9530af9bde38db0eef386c4d22ec2ba10d2fe
원래의 단어에 단지 네 글자를 덧붙였을 뿐인데, 결과는 95%가 다릅니다. 여기 사용한 SHA-1 알고리즘은 미국 국립 보안국에서 개발한 것이고 현재까지는 최선의 해시 알고리즘입니다. 널리 쓰이는 프로그래밍 언어 대부분이 SHA-1을 지원합니다.
In this example, adding four random characters to the beginning of the word changes 95% of the resulting output. The SHA-1 algorithm, developed by the US National Security Agency, is currently the best available hash function that enjoys broad support in most popular programming languages.
말할 필요도 없지만, 단방향 암호화의 사용 용도는 극히 제한됩니다. 대개, 정보를 암호화하는 이유는 "의도된" 곳 이외에서는 쓰지 못하게 하려는 것입니다. 그리고 그 "의도된" 곳 - 예를 들어 관리자가 보는 콘솔 - 에서는 암호화를 풀어서 정보를 이용할 수 있게 해야 합니다.
Of course, one-way functions have a fairly narrow use. In many cases, information is encrypted only to ensure that it can’t be read outside its intended context. But within that context—an administrative console, for example—the encryption needs to be reversible.
어플리케이션 개발자가 항상 되뇌어야 하는 질문이 있습니다: "이걸정말로수집하고 보관해야 하나?" 절대 필요한 최소한의 정보만 수집한다는 원칙을 지키면 사용자 경험이 좋아지고, 개발 과정이 단순해지며, 당연히 더 안전합니다. 어쨌든 간에, 없는 정보를 훔치거나 악용할 수는 없으니까요.
However, the first question an application developer should always ask is: “Do Ireallyneed to collect and store this information?” Keeping data collection to an absolute minimum usually contributes to an improved user experience, simplifies development, and is naturally more secure. After all, data that doesn’t exist can’t be stolen or exploited.
그렇지만, 민감한 정보가 반드시 필요할 때도 있기 마련입니다. 이럴 때 어떻게 해야 안전한지 답을 얻어야겠죠. 해독할 수 있는 암호화는 두 가지로 나뉩니다. 첫째, 하나의 비밀 "키"를 가지고 암호화도 하고, 해독도 하는 방법입니다. 여기서 키는 말하자면 비밀번호 같은 건데, 이건 사람이 아니라 프로그램이 쓰는 것이니 더 길어도 되고(길어야 합니다), 무작위로 아무 글자나 막 섞은 것이어도 됩니다(섞어야 합니다).
But assuming that sensitive information is really crucial to an application’s function, we have to consider how to handle it securely. Reversible encryption falls into two categories. In the first, a single secret “key” is used both for scrambling and unscrambling the data. A key is somewhat like a password, but since keys are more likely to be used by programs than people, they can (and should) be longer and completely random.
최근의 알고리즘을 쓰면, 대칭 암호화는 대단히 빨리 처리할 수 있습니다. 강력한 알고리즘 중 하나인 AES 알고리즘(리진데일 사이퍼Rijndael cipher라고도 합니다.)은 특별히 속도에 주안점을 두고 만들어졌으며, 데이터베이스 서버와 어플리케이션 프레임워크 모두에서 잘 지원합니다.역주예를 들어, MySQL 에서 데이터의 암호화와 해독을 이런 식으로 할 수 있습니다:
With modern algorithms, symmetric encryption has the advantage of being extremely fast. The strong AES algorithm (also known as the Rijndael cipher) was specifically designed for speed and is well supported, with implementations in both database servers and application frameworks. Encrypting and decrypting data in MySQL, for example, is as simple as the following:
INSERT INTO people (pet_name)
VALUES (AES_ENCRYPT('Schmoopie','my-secret-key'));
SELECT AES_DECRYPT(pet_name, 'my-secret-key') AS pet_name
FROM people;
이렇게 하더라도, 악의적인 사용자가 웹 어플리케이션의 제어권을 갖게 된 상황에서는 정보를 보호하지 못합니다 - 어플리케이션에 해독 방법이 다 들어있으니까요. 이 방법은 다른 상황의 사고에 대해서는 데이터를 보호해 줍니다. 예를 들면 데이터베이스 백업파일이 유출됐다거나, 데이터베이스 자체에 대한 공격 같은 것 말입니다.
This doesn’t protect the information from exposure if a malicious user gains access to the web application, since it knows how to decrypt the data. It does, however, protect against accidental disclosure in other contexts, like backup files or an attack on the database itself.
정보에 접근할 수 있는 경로가 한가지뿐이라면, 대칭 암호화로 충분합니다만, 이 암호화 방법은 키를 안전하게 보관할 수 있을 때만 안전합니다. 이러한 점은, 데이터를 다른 곳으로 옮겨야 하는 상황에서는 약점이 됩니다. 키를 공유해야 한다면, 특히 여럿이 공유한다면, 그건 더는 비밀이 아닌 거죠.
Symmetric encryption works well when we only need to access the information in a single context. However, all of its strength lies in the secrecy of the key. This becomes a challenge when we want to move the data from one place to another. If we have to share the key, especially with multiple recipients, it’s no longer a secret.
이런 약점을 보완하기 위해, 비대칭 암호화는 특별한 속성을 넣어서 만든 한 쌍의 키를 이용합니다. 한쪽의 키가 정보를 암호화하면, 반드시 그 짝인 키로만 해독할 수 있습니다. 이런 타입의 암호화를 공용 키 암호화라고도 합니다. 종종 한쪽의 키를 공용으로 사용하고, 그 짝은 개인적으로 보관하게끔 하니까요. (항상 이런 건 아닙니다만)
To meet this need, asymmetric algorithms rely upon a pair of linked keys that are generated with specific properties. When one key encrypts a piece of information, only the corresponding key in the pair can decrypt it. This type of encryption is also called public-key cryptography because often (not always), one key is made public while the other is kept private.
이렇게 짝을 만들어내는알고리즘도 꽤 재미있지만, 웹 개발자가 알아야 하는 것은 알고리즘이 아니라 이걸 언제 써야 하는지, 어느 정도 안전한지 하는 것입니다. 이 기술을 가장 흔히 접하는 분야는 SSL (요즘은 TLS이라 부릅니다.) 연결입니다. 웹 서버에서 브라우저로 공용 키를 보내면, 브라우저는 이 키를 가지고 데이터를 암호화합니다. 그러면 반대쪽 키를 가진 서버에서만 데이터를 해독할 수 있는 거죠. 이 방식은 암호화된 이메일을 보낼 때도 쓰입니다.
The math that makes this pairing possible is interesting, but what web developers need to understand is when to use it and what protection it provides. We most commonly encounter the technology in SSL (now called TLS) connections. A web server sends its public key to a web browser, which uses it to encrypt data that only the server can decrypt. It can also be used for sending encrypted e-mail.
비대칭 암호화는 대칭 암호화에 비해 느리고, 효과를 보려면 몇 배는 더 긴 키를 써야 합니다. TLS 연결에서는 임시로 대칭 키를 만들 때 단 한 번만 공용 키를 사용합니다. 그 이후의 데이터 교환 과정은 이 임시 키로 암호화합니다.
Compared with symmetric functions, asymmetric ones are slow and require keys that are several times longer to be effective. In TLS connections, the browser and server only use public-key cryptography to establish a temporary symmetric key that they can use to encrypt subsequent communication.
이러한 기능은 어플리케이션과 사용자 사이에 오가는 데이터를 보호함으로써 현대 웹의 치명적인 한 축을 담당합니다. 공개된 WiFi 네트워크가 널리 사용되면서 암호화의 중요성은 더 커졌습니다. 와이파이 네트워크에서는 사용자가 자신이 지금 뭘 하고 있는지, 사방으로 꽤 먼 거리까지 방송하는 거나 마찬가지입니다. 암호화를 하지 않으면, 노트북 하나 가지고 모든 데이터를 다 볼 수 있습니다.
2010년에, 이러한 위험을 보여주는 주목할만한 사건이 두 번 있었습니다. 하나는 구글이 거리 정보 수집 차량을 운행하다가, 암호화되지 않은 와이파이 트래픽을 수신해서 자신도 모르는 사이에 개인정보를 수집하고, 저장까지 한 사건입니다. 구글에서 발생한 사고를, 다른 이는 고의로 할 수도 있습니다. 같은 해 말, Firesheep플러그인은 오픈 네트워크에서 데이터를 엿듣는 것이 얼마나 쉬운지(얼마나 위험한지) 보여주면서 각 매체의 헤드라인을 장식했습니다.
These functions fulfill a crucial role in the modern web experience, however, by allowing us to protect data in transit between an application and its users. The prevalence of open WiFi makes this a very real concern. On open WiFi networks, users broadcast everything they’re doing in a 360-degree radius for a considerable distance. Without encryption, that data can be easily observed by anyone with a laptop. Two high-profile incidents highlighted this risk in 2010. First, Google ran afoul of privacy authorities by accidentally collecting and storing unencrypted WiFi traffic with its Street View cars. What Google did accidentally, others can do on purpose. Later the same year, the Firesheep plugin made headlines by showing just how simple (and damaging) it can be to eavesdrop on an open network.
웹 어플리케이션은 최소한 로그인 정보를 보낼 때만이라도 TLS 연결을 사용해야 합니다. 모든 송수신을 그렇게 한다면 더 좋겠지요.
At minimum, web applications should require TLS connections when transmitting login information. Using them for all traffic is even better.
요즘 사람들이 컴퓨터를 쓰는 걸 지켜보면, 웹 개발자에게도 이런 암호화 기술이 점점 더 중요해짐을 깨닫게 됩니다. 지난 몇 년의 경험을 통해 우리는 나쁜놈들이 웹에서 무슨 일을 저지를지 예측 불가함을 알게 되었습니다. "우리 어플리케이션은 표적이 될 만한 데이터를 갖고 있지 않아."라고 생각하시나요? 틀렸습니다. 해커들의 공격은 이제 특정 대상을 향한 것이 아니라, 무작위 대상을 무차별로 공격하게끔 자동화되었습니다. 우리는 이러한 위험과 그에 대응할 기술을 배우고, 다른 이들에게 알려줘야 합니다. 이러한 사실을 배우지 못하면, 사용자는 사이트나 어플리케이션에서 HTTPS 연결을 사용한다는 이유 하나만으로 “안전하다” 라고 생각하고, 자신의 비밀번호를 순수한 텍스트로 보내면 안된다는 걸 이해 못할 수도 있습니다.
Given the way people use computers today, all of these technologies will only become more important to web developers. The past few years have shown that the risk is not academic. It’s not enough to say “my application doesn’t have a high enough profile to be a target,” because attacks are frequently automated, not targeted. At the same time, we have to understand and educate others about specific risks and how we use technology to address them. Without that education, clients may consider a site or application “secure” simply because it accepts HTTPS connections, not understanding why it’s unable to e-mail a clear-text password to them.
완전한 보안은 존재할 수 없습니다. 하지만 최근의 암호화 기술을 잘 사용하면, 심각한 위협을 피해 갈 수는 있습니다. 이걸 사용하는 것은 우리의 몫입니다.
Security can never be absolute. But used properly, modern cryptography provides us with the tools to eliminate the biggest threats. It’s up to us to put them to use.
1. AES 알고리즘은 인텔 코어 i5, i7 제품군부터는 CPU 차원에서도 지원합니다.돌아가기
댓글 (8)