암호화 알고리즘은 데이터 기밀성과 무결성을 보장하기 위해 적절한 경우 보안 모드와 패딩 체계를 사용해야 합니다.
- 블록 암호 암호화 알고리즘(예: AES)의 경우:
- ECB(Electronic Codebook) 암호화 모드는 주어진 키 아래에서 주어진 일반 텍스트 블록이 항상 동일한 암호 텍스트 블록으로 암호화되므로 메시지 기밀성을 제대로 제공하지 못합니다. 이 모드는 절대로 사용해서는 안 됩니다.
- CBC(Cipher Block Chaining) 모드는 그 자체로 데이터 기밀성만 제공합니다. 이 암호화 모드는 패딩과 함께 사용할 경우 패딩 오라클 공격에 취약합니다. 메시지 인증 코드와 함께 CBC를 사용하면 데이터 무결성을 제공할 수 있으며 이러한 공격을 방지할 수 있습니다. 실제로 구현에는 많은 함정이 있으므로 패딩과 함께 CBC를 완전히 피하는 것이 좋습니다.
- 내부적으로 패딩이 없거나 패딩이 있는 방식으로 작동하는 GCM(Galois Counter Mode) 모드는 데이터 신뢰성(무결성)과 기밀성을 모두 제공하도록 설계되었으므로 권장됩니다. 다른 유사한 모드로는 CCM, CWC, EAX, IAPM 및 OCB가 있습니다.
- RSA 암호화 알고리즘의 경우, 권장 패딩 체계는 OAEP입니다.
규칙을 어긴 코드
pycryptodomex 라이브러리:
from Cryptodome.Cipher import AES, PKCS1_OAEP, PKCS1_v1_5
from Cryptodome.Random import get_random_bytes
from Cryptodome.PublicKey import RSA
# 대칭 암호의 예시: AES
AES.new(key, AES.MODE_ECB) # 규칙을 어긴 코드
AES.new(key, AES.MODE_CBC) # 규칙을 어긴 코드
# 비대칭 암호의 예시: RSA
cipher = PKCS1_v1_5.new(key) # 규칙을 어긴 코드
pyca 라이브러리:
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes
# 대칭 암호의 예시: AES
aes = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) # 규칙을 어긴 코드
aes = Cipher(algorithms.AES(key), modes.ECB(), backend=default_backend()) # 규칙을 어긴 코드
# 비대칭 암호의 예시: RSA
ciphertext = public_key.encrypt(
message,
padding.PKCS1v15() # 규칙을 어긴 코드
)
plaintext = private_key.decrypt(
ciphertext,
padding.PKCS1v15() # 규칙을 어긴 코드
)
pydes 라이브러리:
# DES 암호의 경우
des = pyDes.des('ChangeIt') # 규칙을 어긴 코드
des = pyDes.des('ChangeIt', pyDes.CBC, "\0\0\0\0\0\0\0\0", pad=None, padmode=pyDes.PAD_PKCS5) # 규칙을 어긴 코드
des = pyDes.des('ChangeIt', pyDes.ECB, "\0\0\0\0\0\0\0\0", pad=None, padmode=pyDes.PAD_PKCS5) # 규칙을 어긴 코드
pycrypto 라이브러리는 유지보수되고 있지 않기 때문에 사용해서는 안됩니다:
# https://pycrypto.readthedocs.io/en/latest/
from Crypto.Cipher import *
from Crypto.Random import get_random_bytes
from Crypto.Util import Counter
from Crypto.PublicKey import RSA
# 대칭 암호의 예시: AES
AES.new(key, AES.MODE_ECB) # 규칙을 어긴 코드
AES.new(key, AES.MODE_CBC, IV=iv) # 규칙을 어긴 코드
# 비대칭 암호의 예시: RSA
cipher = PKCS1_v1_5.new(key) # 규칙을 어긴 코드
규칙을 준수한 해결책
pycryptodomex 라이브러리:
from Cryptodome.Cipher import AES
from Cryptodome.Random import get_random_bytes
from Cryptodome.PublicKey import RSA
# AES는 GCM 모드에서 권장되는 대칭형 암호입니다
AES.new(key, AES.MODE_GCM) # 규칙을 준수한 해결책
# RSA는 OAEP 패딩이 있는 권장 비대칭 암호입니다
cipher = PKCS1_OAEP.new(key) # 규칙을 준수한 해결책
pyca 라이브러리:
import os
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa, padding
from cryptography.hazmat.primitives import hashes
# AES는 GCM 모드에서 권장되는 대칭형 암호입니다
aes = Cipher(algorithms.AES(key), modes.GCM(iv), backend=default_backend()) # 규칙을 준수한 해결책
# RSA는 OAEP 패딩이 있는 권장 비대칭 암호입니다
ciphertext = public_key.encrypt(
message,
padding.OAEP( # 규칙을 준수한 해결책
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
plaintext = private_key.decrypt(
ciphertext,
padding.OAEP( # 규칙을 준수한 해결책
mgf=padding.MGF1(algorithm=hashes.SHA256()),
algorithm=hashes.SHA256(),
label=None
)
)
같이보면 좋은 자료
- OWASP Top 10 2021 Category A2 - 암호화 실패
- OWASP Top 10 2017 Category A6 - 보안 구성 오류
- MITRE, CWE-327 - 깨지거나 위험한 암호화 알고리즘 사용
-
SANS Top 25 - 다공성 방어
If you like SONARKUBE, don’t forget to give me a star.