{"componentChunkName":"component---src-templates-post-template-js","path":"/posts/6","result":{"data":{"markdownRemark":{"id":"762a616d-537f-5aeb-a29e-da2aecace349","html":"<h2 id=\"python으로-password-만들기\"><a href=\"#python%EC%9C%BC%EB%A1%9C-password-%EB%A7%8C%EB%93%A4%EA%B8%B0\" aria-label=\"python으로 password 만들기 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>python으로 password 만들기</h2>\n<p>적어도 하나의 소문자, 적어도 하나의 대문자 및 적어도 3개의 숫자가 있는 10자의 영숫자 암호를 생성한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">import</span> string\n<span class=\"token keyword\">import</span> secrets\nalphabet <span class=\"token operator\">=</span> string<span class=\"token punctuation\">.</span>ascii_letters <span class=\"token operator\">+</span> string<span class=\"token punctuation\">.</span>digits\n<span class=\"token keyword\">while</span> <span class=\"token boolean\">True</span><span class=\"token punctuation\">:</span>\n    password <span class=\"token operator\">=</span> <span class=\"token string\">''</span><span class=\"token punctuation\">.</span>join<span class=\"token punctuation\">(</span>secrets<span class=\"token punctuation\">.</span>choice<span class=\"token punctuation\">(</span>alphabet<span class=\"token punctuation\">)</span> <span class=\"token keyword\">for</span> i <span class=\"token keyword\">in</span> <span class=\"token builtin\">range</span><span class=\"token punctuation\">(</span><span class=\"token number\">20</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> <span class=\"token punctuation\">(</span><span class=\"token builtin\">any</span><span class=\"token punctuation\">(</span>c<span class=\"token punctuation\">.</span>islower<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">for</span> c <span class=\"token keyword\">in</span> password<span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">and</span> <span class=\"token builtin\">any</span><span class=\"token punctuation\">(</span>c<span class=\"token punctuation\">.</span>isupper<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">for</span> c <span class=\"token keyword\">in</span> password<span class=\"token punctuation\">)</span>\n            <span class=\"token keyword\">and</span> <span class=\"token builtin\">sum</span><span class=\"token punctuation\">(</span>c<span class=\"token punctuation\">.</span>isdigit<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">for</span> c <span class=\"token keyword\">in</span> password<span class=\"token punctuation\">)</span> <span class=\"token operator\">>=</span> <span class=\"token number\">3</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">break</span></code></pre></div>\n<h3 id=\"python-tokenbytes-tokenhex\"><a href=\"#python-tokenbytes-tokenhex\" aria-label=\"python tokenbytes tokenhex permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>python token<em>bytes, token</em>hex</h3>\n<p><code class=\"language-text\">secrets.token_bytes([nbytes=None])</code></p>\n<p>: nbytes 바이트를 포함하는 임의의 바이트열을 반환합니다. nbytes가 None이거나 제공되지 않으면, 적절한 기본값이 사용됩니다.</p>\n<p><code class=\"language-text\">secrets.token_hex([nbytes=None])</code></p>\n<p>: 무작위 16진수 텍스트 문자열을 돌려줍니다. 이 문자열에는 nbytes 무작위 바이트가 있으며, 각 바이트는 두 자리 16진수로 변환됩니다. nbytes가 None이거나 제공되지 않으면, 적절한 기본값이 사용됩니다.</p>\n<ul>\n<li>출처: <a href=\"https://docs.python.org/ko/3.8/library/secrets.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://docs.python.org/ko/3.8/library/secrets.html</a></li>\n<li>secrets 라이브러리는 python 3.6 버젼 이상부터 지원한다.</li>\n</ul>\n<h3 id=\"bit-byte-16진수-관계-정리\"><a href=\"#bit-byte-16%EC%A7%84%EC%88%98-%EA%B4%80%EA%B3%84-%EC%A0%95%EB%A6%AC\" aria-label=\"bit byte 16진수 관계 정리 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>bit, byte, 16진수 관계 정리</h3>\n<ul>\n<li>bit 는 2 진수 한 자리를 말하며 표현가능한 가짓수는 2 개이다. 숫자로 치면 0 ~ 1.</li>\n<li>byte 는 8 bit 를 말하며 2 진수 8 자리에 해당하고 표현가능한 가짓수는 2^8 개인 256 개이며 숫자로 치면 0 ~ 255.</li>\n</ul>\n<p>bit 는 전기의 on / off 이며 이것을 2진수의 1 / 0 에 대응시킨 것이다.\n2진수와 16진수의 변환이 헷갈릴 수 있다.\n수학에서 하듯 2진수를 10진수로 바꾸고 이것을 다시 16진수로 바꾸는 식으로 해도 되지만 2진수 네 자리가 16진수 한 자리와 같다는 것만 기억하면 훨씬 쉽게 변환이 가능하다.</p>\n<p>설명하자면, 16진수 한 자리는 16가지의 수의 표현이 가능하고, 이는 2^4(4 * 4 = 2^2 * 2^2 = 2^4) 가지이고, 이것은 2진수 4자리가 표현가능한 수의 가짓수와 같다. 즉, “2진수 4자리 = 16진수 1 자리” 인 셈이다. 참고로 16진수 한 자리에 해당하는 4 bit 를 니블(nibble)이라고 말한다.</p>\n<p>방금 말한 4 bit 단위로 읽으면 2진수와 16진수의 변환을 쉽게 할 수 있다. 2 byte 에 해당하는 16 bit 의 수를 예로 들어보자.</p>\n<p>0110 1001 1101 0010</p>\n<p>위와 같은 2진수를 4 bit 씩 끊어서 변환하면, 6 9 13 2 가 되고, 컴퓨터의 16진수로 표현하면 0x69D2 가 되는 것이다.</p>\n<p>기억하기에는 <strong>1 byte = 8 bit = 16진수 2자리</strong>\n정도만 기억하면 단위가 헷갈리는 경우는 없을 것 같다.</p>\n<p>출처: <a href=\"https://m.blog.naver.com/PostView.nhn?blogId=herbbread&#x26;logNo=220692723391&#x26;proxyReferer=https%3A%2F%2Fwww.google.com%2F\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://m.blog.naver.com/PostView.nhn?blogId=herbbread&#x26;logNo=220692723391&#x26;proxyReferer=https%3A%2F%2Fwww.google.com%2F</a></p>\n<h2 id=\"암호화encryption\"><a href=\"#%EC%95%94%ED%98%B8%ED%99%94encryption\" aria-label=\"암호화encryption permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>암호화(encryption)</h2>\n<blockquote>\n<p>암호화(暗號化) 또는 엔크립션(encryption)은 특별한 지식을 소유한 사람들을 제외하고는 누구든지 읽어볼 수 없도록 알고리즘을 이용하여 정보(평문을 가리킴)를 전달하는 과정이다. 이러한 과정을 통해 암호화된 정보(암호문)를 낳는다. 이에 역행하는 과정을 해독 또는 디크립션(decryption)이라고 하며 이로써 암호화된 정보를 다시 읽을 수 있다.</p>\n</blockquote>\n<p>출처 : <a href=\"https://ko.wikipedia.org/wiki/%EC%95%94%ED%98%B8%ED%99%94\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://ko.wikipedia.org/wiki/%EC%95%94%ED%98%B8%ED%99%94</a></p>\n<h2 id=\"대칭키-알고리즘\"><a href=\"#%EB%8C%80%EC%B9%AD%ED%82%A4-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98\" aria-label=\"대칭키 알고리즘 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>대칭키 알고리즘</h2>\n<p>출처 : <a href=\"https://lesstif.gitbooks.io/web-service-hardening/content/encryption.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://lesstif.gitbooks.io/web-service-hardening/content/encryption.html</a></p>\n<p>대칭키(Symmetric key) 방식은 암호문을 생성(암호화)할 때 사용하는 키와 암호문으로부터 평문을 복원(복호화)할 때 사용하는 키가 동일한 암호 시스템으로 일반적으로 알고 있는 암호 시스템입니다.</p>\n<p>하나의 키로 암호화와 복호화를 수행하므로 대칭키(Symmetric key) 또는 비밀키(Secret Key) 방식의 암호화라고 합니다. 대칭키 방식의 암호화는 데이타를 블록(Block) 단위로 처리하는 Block cipher 와 연속된 스트림으로 처리하는 Stream cipher 가 있으며 일반적으로 대칭키 암호화라고 하면 블록 방식의 암호화를 의미합니다.</p>\n<p>블록 방식의 주요 알고리즘으로는 예전에 유닉스의 패스워드 파일을 암호화하는데 사용했지만 오래전에 뚫려서 이제는 절대 사용하면 안 되는 DES(Data Encryption Standard)와 현재 미국의 표준 암호 알고리즘인 AES가 있으며 국내에서 개발한 SEED와 ARIA , 그리고 유럽에서 개발한 IDEA 알고리즘 등이 있습니다.</p>\n<p>블록 암호화는 정해진 길이, 또는 가변 길이의 암/복호화 키를 사용하며 알고리즘마다 다릅니다.\n예로 AES 는 128, 192, 256 비트의 키를 사용할 수 있으며 SEED 는 128를 OpenBSD 에서 많이 사용하는 Blowfish 는 32 ~ 448 비트의 키 길이를 사용합니다.\n대칭키 암호는 공개키 방식에 대비하여 구현이 용이하고 CPU/메모리를 적게 사용하고 매우 빠른 암/복호화 속도를 장점으로 갖고 있으며 Windows의 BitLocker 와 OS X 의 FileVault 같이 디스크 전체를 암호화할 때도 대칭키 방식(AES) 을 사용합니다.\n하지만 대칭키 방식은 하나의 키만 사용하므로 상대방과 대칭키 기반으로 암호화 통신을 할 경우 상대방도 사전에 같은 키를 갖고 있어야 합니다.</p>\n<hr>\n<h4 id=\"aesadvanced-encryption-standard\"><a href=\"#aesadvanced-encryption-standard\" aria-label=\"aesadvanced encryption standard permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>AES(Advanced Encryption Standard)</h4>\n<p>AES는 2001년 미국 표준 기술 연구소(NIST)에 의해 제정된 암호화 방식이다. AES는 미국 정부가 채택한 이후 전 세계적으로 널리 사용되고 있다.\nAES는 Block으로 나눠어서 암호화를 하는데 128, 192, 256비트로 나눌 수가 있다.\nBlock으로 암호화를 할때는 아래와 같이 4가지 모드가 있다.</p>\n<ol>\n<li>ECB ( Electric Code Book )</li>\n<li>CBC ( Cipher Block Chaining )</li>\n<li>OFB ( Output Feed Back )</li>\n<li>CFB ( Cipher Feed Back )</li>\n</ol>\n<p>출처 : <a href=\"http://jo.centis1504.net/?p=137\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">http://jo.centis1504.net/?p=137</a></p>\n<hr>\n<p>이처럼 대칭키 방식의 최대 단점은 암호화 통신을 위한 키 전달과 관리가 어려운 점입니다.\n가령 대칭키를 보내는 중간에 유출될 우려가 있고 이로 인해 암호화 통신을 도감청 당할 수 있으며 여러 상대방과 통신할 경우 각각의 대칭키를 관리하기(생성, 전달, 유출시 폐기)가 어렵고 여러 상대방과 같은 키를 사용할 경우 키가 노출되면 모든 채널과 새로 키를 전달해야 하는 치명적인 단점이 있습니다.</p>\n<h3 id=\"블록-암호-패딩padding\"><a href=\"#%EB%B8%94%EB%A1%9D-%EC%95%94%ED%98%B8-%ED%8C%A8%EB%94%A9padding\" aria-label=\"블록 암호 패딩padding permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>블록 암호 패딩(Padding)</h3>\n<p>블록 알고리즘은 입력 데이타를 정해진 블록으로 잘라서 암/복호화를 수행하며 블록의 크기는 알고리즘마다 다릅니다. 예로 AES 는 128 bit(16 byte)를 하나의 블록으로 처리합니다.\n하지만 입력 데이타가 항상 블록의 배수일리는 없으므로 입력데이타를 블록 크기에 맞춰주는 작업이 필요하며 이를 패딩이라고 합니다.\n즉 AES 를 사용할 경우 암호화할 데이타가 19 바이트일 경우 최소 공배수인 32 byte 로 맞춰주어야 하며 이 작업을 패딩이라고 지칭하며 여러 가지 패딩 방법이 있습니다.</p>\n<h3 id=\"cbccipher-block-chaining\"><a href=\"#cbccipher-block-chaining\" aria-label=\"cbccipher block chaining permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>CBC(cipher-block chaining)</h3>\n<p>CBC 는 ECB 의 단점을 해결하기 위한 방법으로 각 블록은 암호화되기 전에 이전 블록과 XOR 연산을 거치며 유추가 힘들도록 최초의 입력은 IV(initial vector) 라는 데이타와 연산을 하게 됩니다.\n이때문에 CBC 암호화를 사용할 경우 대칭키와 IV 가 필요합니다.</p>\n<p><img src=\"https://upload.wikimedia.org/wikipedia/commons/d/d3/Cbc_encryption.png\"></p>\n<h3 id=\"데이타-암호화-프로세스\"><a href=\"#%EB%8D%B0%EC%9D%B4%ED%83%80-%EC%95%94%ED%98%B8%ED%99%94-%ED%94%84%EB%A1%9C%EC%84%B8%EC%8A%A4\" aria-label=\"데이타 암호화 프로세스 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>데이타 암호화 프로세스</h3>\n<p>데이타 암호화와 복호화 작업을 누가 수행하는지에 따라 암호화 프로세스가 달라져야 합니다.</p>\n<h4 id=\"사용자가-복호화\"><a href=\"#%EC%82%AC%EC%9A%A9%EC%9E%90%EA%B0%80-%EB%B3%B5%ED%98%B8%ED%99%94\" aria-label=\"사용자가 복호화 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>사용자가 복호화</h4>\n<p>예로 사이트 로그인 정보를 관리해 주는 lastpass.com 서비스를 생각해 봅시다. 로그인 정보는 lastpass 서버에 암호화해서 보관되며 lastpass가 복호화를 하면 안 됩니다.\n이때 필요한 방법은 PBKDF2같이 비밀번호 기반으로 암호화하는 방법으로 사용자로부터 마스터 암호를 입력받고 PBKDF2 함수를 수행해서 안전한 대칭키와 Initial Vector 를 생성해서 복호화합니다.\n암호화와 복호화는 사용자의 비밀번호를 기반으로 이루어지며 사용자만 수행해야 합니다..\n이 방법은 암호화된 사용자 데이타마다 비밀번호가 다르므로 서버는 키 관리가 힘들지 않고 실제 데이타/암복호화는 사용자 PC에서 이루어지는 경우가 많으므로 서버의 부담이 적습니다.</p>\n<h4 id=\"서버에서-복호화\"><a href=\"#%EC%84%9C%EB%B2%84%EC%97%90%EC%84%9C-%EB%B3%B5%ED%98%B8%ED%99%94\" aria-label=\"서버에서 복호화 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>서버에서 복호화</h4>\n<p>사용자의 신용 카드 정보를 보관하고 매 달마다 결제한다고 생각해 봅시다.\n서버는 정보를 암호화하여 안전하게 보관해야 하며 매달 결제일마다 복호화하여 카드 정보를 알아내야 합니다.\n데이타의 암호화/복호화가 서버에서 이루어지므로 보안에 매우 신경써야 하며 특히 암호화 키를 잘 관리해야 합니다.\n이 모델을 사용할 경우 HSM을 도입하여 안전하게 키 관리하는것이 좋습니다.</p>\n<h4 id=\"출처--httpslesstifgitbooksioweb-service-hardeningcontentencryptionhtml\"><a href=\"#%EC%B6%9C%EC%B2%98--httpslesstifgitbooksioweb-service-hardeningcontentencryptionhtml\" aria-label=\"출처  httpslesstifgitbooksioweb service hardeningcontentencryptionhtml permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>출처 : <a href=\"https://lesstif.gitbooks.io/web-service-hardening/content/encryption.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://lesstif.gitbooks.io/web-service-hardening/content/encryption.html</a></h4>\n<h3 id=\"aes-128-cbc-대칭키-test\"><a href=\"#aes-128-cbc-%EB%8C%80%EC%B9%AD%ED%82%A4-test\" aria-label=\"aes 128 cbc 대칭키 test permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>AES-128-CBC 대칭키 test</h3>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">class</span> <span class=\"token class-name\">AESCryptoCBC</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token triple-quoted-string string\">'''\n    * iv or key generator *\n    from Crypto import Random\n    iv = Random.new().read(AES.block_size)  # binary code\n    import secrets\n    iv = secrets.token_hex(8)\n    '''</span>\n\n    <span class=\"token keyword\">def</span> <span class=\"token function\">__init__</span><span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">from</span> Crypto<span class=\"token punctuation\">.</span>Cipher <span class=\"token keyword\">import</span> AES\n        key <span class=\"token operator\">=</span> <span class=\"token string\">b'1234567891234567'</span>\n        iv <span class=\"token operator\">=</span> <span class=\"token string\">b'1234567891234567'</span>\n        self<span class=\"token punctuation\">.</span>crypto <span class=\"token operator\">=</span> AES<span class=\"token punctuation\">.</span>new<span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">,</span> AES<span class=\"token punctuation\">.</span>MODE_CBC<span class=\"token punctuation\">,</span> iv<span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">def</span> <span class=\"token function\">encrypt</span><span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">,</span> <span class=\"token builtin\">input</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">import</span> base64\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">'input :: '</span><span class=\"token punctuation\">,</span> <span class=\"token builtin\">input</span><span class=\"token punctuation\">)</span>\n        encrypted <span class=\"token operator\">=</span> self<span class=\"token punctuation\">.</span>crypto<span class=\"token punctuation\">.</span>encrypt<span class=\"token punctuation\">(</span><span class=\"token builtin\">input</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">'encrypted :: '</span><span class=\"token punctuation\">,</span> encrypted<span class=\"token punctuation\">)</span>\n        encoded_encrypted <span class=\"token operator\">=</span> base64<span class=\"token punctuation\">.</span>b64encode<span class=\"token punctuation\">(</span>encrypted<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> encoded_encrypted\n\n    <span class=\"token keyword\">def</span> <span class=\"token function\">decrypt</span><span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">,</span> encrypted<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">import</span> base64\n        decoded_data <span class=\"token operator\">=</span> base64<span class=\"token punctuation\">.</span>b64decode<span class=\"token punctuation\">(</span>encrypted<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">'decoded_data :: '</span><span class=\"token punctuation\">,</span> decoded_data<span class=\"token punctuation\">)</span>\n        decrypted <span class=\"token operator\">=</span> self<span class=\"token punctuation\">.</span>crypto<span class=\"token punctuation\">.</span>decrypt<span class=\"token punctuation\">(</span>decoded_data<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> decrypted<span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token string\">'utf-8'</span><span class=\"token punctuation\">)</span>\n\n\n<span class=\"token keyword\">def</span> <span class=\"token function\">aes_test</span><span class=\"token punctuation\">(</span>request<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    data <span class=\"token operator\">=</span> <span class=\"token string\">'1234567891234567'</span>\n\n    enc <span class=\"token operator\">=</span> AESCryptoCBC<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>encrypt<span class=\"token punctuation\">(</span>data<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"The encoded_encrypted value is\"</span><span class=\"token punctuation\">,</span> <span class=\"token builtin\">type</span><span class=\"token punctuation\">(</span>enc<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> enc<span class=\"token punctuation\">)</span>\n\n    dec <span class=\"token operator\">=</span> AESCryptoCBC<span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span>decrypt<span class=\"token punctuation\">(</span>enc<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">print</span><span class=\"token punctuation\">(</span><span class=\"token string\">\"The decrypted value is\"</span><span class=\"token punctuation\">,</span> <span class=\"token builtin\">type</span><span class=\"token punctuation\">(</span>dec<span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span> dec<span class=\"token punctuation\">)</span>\n\n<span class=\"token comment\"># 결과물</span>\n<span class=\"token comment\"># input ::  1234567891234567</span>\n<span class=\"token comment\"># encrypted ::  b'\\x1aa\\x03\\x97\\x14|\\xc0DKT\\xf7e\\x06\\xca@\\xa6'</span>\n<span class=\"token comment\"># The encoded_encrypted value is &lt;class 'bytes'> b'GmEDlxR8wERLVPdlBspApg=='</span>\n<span class=\"token comment\"># decoded_data ::  b'\\x1aa\\x03\\x97\\x14|\\xc0DKT\\xf7e\\x06\\xca@\\xa6'</span>\n<span class=\"token comment\"># The decrypted value is &lt;class 'str'> 1234567891234567</span></code></pre></div>\n<h3 id=\"블록-암호-패딩padding-작업을-해보자\"><a href=\"#%EB%B8%94%EB%A1%9D-%EC%95%94%ED%98%B8-%ED%8C%A8%EB%94%A9padding-%EC%9E%91%EC%97%85%EC%9D%84-%ED%95%B4%EB%B3%B4%EC%9E%90\" aria-label=\"블록 암호 패딩padding 작업을 해보자 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>블록 암호 패딩(Padding) 작업을 해보자</h3>\n<p>python의 AES.MODE_CBC 모듈에서\nkey는 16, 24, or 32 bytes로, IV는 16 bytes 값으로 선언하지 않을 경우 발생하는 에러는 다음과 같다.</p>\n<ol>\n<li><code class=\"language-text\">AES key must be either 16, 24, or 32 bytes long</code></li>\n<li><code class=\"language-text\">IV must be 16 bytes long</code></li>\n</ol>\n<p>또한 암호화할 데이터가 16의 배수가 아니여도 아래와 같은 에러가 발생한다.</p>\n<p><code class=\"language-text\">Input strings must be a multiple of 16 in length</code></p>\n<p>이 에러들을 해결하기 위해 사용한 파이썬의 <code class=\"language-text\">struct</code> 모듈을 사용했다.</p>\n<p>This module performs conversions between Python values and C structs represented as Python bytes objects.\nThis can be used in handling binary data stored in files or from network connections, among other sources</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token keyword\">import</span> struct\n\n<span class=\"token keyword\">class</span> <span class=\"token class-name\">AESCryptoCBC</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">def</span> <span class=\"token function\">__init__</span><span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">from</span> Crypto<span class=\"token punctuation\">.</span>Cipher <span class=\"token keyword\">import</span> AES\n        key <span class=\"token operator\">=</span> <span class=\"token string\">'samplekey'</span>\n        iv <span class=\"token operator\">=</span> <span class=\"token string\">'sampleIV'</span>\n        encoded_key <span class=\"token operator\">=</span> struct<span class=\"token punctuation\">.</span>pack<span class=\"token punctuation\">(</span><span class=\"token string\">'16s'</span><span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">.</span>encode<span class=\"token punctuation\">(</span><span class=\"token string\">'utf-8'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        encoded_iv <span class=\"token operator\">=</span> struct<span class=\"token punctuation\">.</span>pack<span class=\"token punctuation\">(</span><span class=\"token string\">'16s'</span><span class=\"token punctuation\">,</span> iv<span class=\"token punctuation\">.</span>encode<span class=\"token punctuation\">(</span><span class=\"token string\">'utf-8'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        self<span class=\"token punctuation\">.</span>crypto <span class=\"token operator\">=</span> AES<span class=\"token punctuation\">.</span>new<span class=\"token punctuation\">(</span>encoded_key<span class=\"token punctuation\">,</span> AES<span class=\"token punctuation\">.</span>MODE_CBC<span class=\"token punctuation\">,</span> encoded_iv<span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">def</span> <span class=\"token function\">encrypt</span><span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">,</span> <span class=\"token builtin\">input</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        encoded_input <span class=\"token operator\">=</span> struct<span class=\"token punctuation\">.</span>pack<span class=\"token punctuation\">(</span><span class=\"token string\">'16s'</span><span class=\"token punctuation\">,</span> <span class=\"token builtin\">input</span><span class=\"token punctuation\">.</span>encode<span class=\"token punctuation\">(</span><span class=\"token string\">'utf-8'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n        encrypted <span class=\"token operator\">=</span> self<span class=\"token punctuation\">.</span>crypto<span class=\"token punctuation\">.</span>encrypt<span class=\"token punctuation\">(</span>encoded_input<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> base64<span class=\"token punctuation\">.</span>b64encode<span class=\"token punctuation\">(</span>encrypted<span class=\"token punctuation\">)</span>\n\n    <span class=\"token keyword\">def</span> <span class=\"token function\">decrypt</span><span class=\"token punctuation\">(</span>self<span class=\"token punctuation\">,</span> encrypted<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n        decoded_data <span class=\"token operator\">=</span> base64<span class=\"token punctuation\">.</span>b64decode<span class=\"token punctuation\">(</span>encrypted<span class=\"token punctuation\">)</span>\n        decrypted <span class=\"token operator\">=</span> self<span class=\"token punctuation\">.</span>crypto<span class=\"token punctuation\">.</span>decrypt<span class=\"token punctuation\">(</span>decoded_data<span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> decrypted<span class=\"token punctuation\">.</span>decode<span class=\"token punctuation\">(</span><span class=\"token string\">'utf-8'</span><span class=\"token punctuation\">)</span></code></pre></div>\n<p><code class=\"language-text\">struct.pack(fmt, v1, v2, ...)</code> : Return a bytes object containing the values v1, v2, … packed according to the format string fmt.\nThe arguments must match the values required by the format exactly.</p>\n<p><code class=\"language-text\">pack()</code> 함수를 사용하면 16 bytes에 모자란 부분을 <code class=\"language-text\">b&#39;samplekey\\x00\\x00\\x00\\x00\\x00\\x00\\x00&#39;</code> 와 같이 <code class=\"language-text\">\\x00</code>로 채워준다.\n만약 value가 16bytes 이상일 경우, 17자리부터 절삭한다.</p>\n<div class=\"gatsby-highlight\" data-language=\"python\"><pre class=\"language-python\"><code class=\"language-python\"><span class=\"token operator\">>></span><span class=\"token operator\">></span> key <span class=\"token operator\">=</span> <span class=\"token string\">'samplekey01234567890'</span>\n<span class=\"token operator\">>></span><span class=\"token operator\">></span> encoded_key <span class=\"token operator\">=</span> struct<span class=\"token punctuation\">.</span>pack<span class=\"token punctuation\">(</span><span class=\"token string\">'16s'</span><span class=\"token punctuation\">,</span> key<span class=\"token punctuation\">.</span>encode<span class=\"token punctuation\">(</span><span class=\"token string\">'utf-8'</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span>\n<span class=\"token operator\">>></span><span class=\"token operator\">></span> encoded_key\n<span class=\"token string\">b'samplekey0123456'</span></code></pre></div>\n<h4 id=\"참고\"><a href=\"#%EC%B0%B8%EA%B3%A0\" aria-label=\"참고 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>&#x3C;참고></h4>\n<ul>\n<li><a href=\"http://blog.naver.com/PostView.nhn?blogId=s2kiess&#x26;logNo=220243476924\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">http://blog.naver.com/PostView.nhn?blogId=s2kiess&#x26;logNo=220243476924</a></li>\n<li><a href=\"https://docs.python.org/ko/3.6/library/struct.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">https://docs.python.org/ko/3.6/library/struct.html</a></li>\n</ul>","fields":{"slug":"/posts/6","tagSlugs":null},"frontmatter":{"date":"2019-11-13","description":"","tags":null,"title":"암호화 복호화 AES-128-CBC in python"}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"slug":"/posts/6"}}}