Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 파이썬 철저 입문
- Cluster
- wil
- 프로그래머스
- 스파르타코딩
- 웹 스크랩핑
- 파이썬
- R
- 내일배움
- 프로젝트
- 파이썬 철저입문
- SQL
- MySQL
- 미세먼지
- 파이썬 완벽 가이드
- 실전 데이터 분석 프로젝트
- hackerrank
- harkerrank
- 파이썬 머신러닝 완벽 가이드
- 내일배움캠프
- 오블완
- 티스토리챌린지
- 텍스트 분석
- TiL
- 스파르타 코딩
- 파이썬 머신러닝 완벽가이드
- 중회귀모형
- 회귀분석
- 내일배움카드
- 스파르타
Archives
- Today
- Total
OkBublewrap
🔒 암호화 본문
정규 표현식
- 정규표현식은 복잡한 문자열을 처리할 때 사용하는 기법으로 문자열을 처리해야 하는 다양한 상황에서 활용됨
- 파이썬 정규 표현식은
re
표준 라이브러리를 사용
import re
pattern = r"패턴"
re.search(pattern, string) # 일치하는 첫 부분을 찾음
re.match(pattern, string) # 문자열 시작부터 일치하는지 확인
re.findall(pattern, string) # 일치하는 모든 부분을 리스트로 반환
re.sub(pattern, repl, string) # 일치하는 부분을 치환
패턴 | 설명 | 예시 |
---|---|---|
. |
임의의 한 문자 | a.c → abc, acc |
^ |
문자열의 시작 | ^a → abc에서 a로 시작하는 것 |
$ |
문자열의 끝 | z$ → xyz에서 z로 끝나는 것 |
* |
0회 이상 반복 | bo* → b, bo, boo, booo |
+ |
1회 이상 반복 | bo+ → bo, boo (b는 X) |
? |
0회 또는 1회 | ab?c → ac, abc |
{m} |
정확히 m회 반복 | a{3} → aaa |
{m,n} |
m~n회 반복 | a{2,4} → aa, aaa, aaaa |
[] |
문자 집합 | [abc] → a, b, 또는 c |
[^abc] |
제외 문자 집합 | a, b, c 제외 |
\d |
숫자 [0-9] |
\d+ → 숫자 하나 이상 |
\D |
숫자가 아닌 것 | |
\w |
단어 문자 (알파벳+숫자+_) | |
\W |
단어 문자가 아닌 것 | |
\s |
공백 문자 | |
\S |
공백이 아닌 문자 | |
` | ` | OR 조건 |
() |
그룹핑 | (ab)+ → ab, abab, ababab |
숫자만 추출
numbers = re.findall(r"\\d+", text)
print(numbers) # ['010', '1234', '5678']
전화번호 패턴 찾기
match = re.search(r"\\d{3}-\\d{4}-\\d{4}", text)
if match:
print(match.group()) # 010-1234-5678
이메일 치환
email = "[user@example.com](mailto:user@example.com)"
masked = re.sub(r"@.\*", "@****", email)
print(masked) # user@****
### 예제2
개인정보가 포함된 문서에서 주민번호 뒷자리를 `*******` 로 마스킹하고자 할 때
# 개인 정보 목록
personal_info = '''
김미키 010-3344-5566 Mike@google.com 800905-1033451
김소은 010-5032-1111 Soeun@naver.com 700905-2134567
유한슬 010-2789-1476 Lyu@school.ac.com 931222-1234567
박민철 010 4040 1313 Zoe@school.ac.com 830810-1234567
이민아 010-7777-2222 Kate@google.com 960711-2434567
방법1: 정규 표현식을 사용하지 않을 경우
- 공백 문자를 기준으로 전체 텍스트를 나눈다(split() 함수 사용)
- 나눈 단어가 주민 등록 번호 형식인지 조사한다.
- 주민 등록 번호 형식이라면 뒷자리를 ***로 마스킹한다
- 나눈 단어를 다시 조립한다.
result = []
for line in personal_info.split("\n"): # 텍스트를 줄 단위로 분리
word_result = []
for word in line.split(" "): # 각 줄을 단어 단위로 분리
if len(word) == 14 and word[:6].isdigit() and word[7:].isdigit():
# 조건: 총 14자이고, 앞 6자리 숫자 + 뒤 7자리 숫자인 경우 (00000000000000)
word = word[:6] + "-" + "*******" # → 000000-*******
word_result.append(word)
result.append(" ".join(word_result)) # 마스킹한 단어들 다시 줄로 합침
print("\n".join(result)) # 전체 줄 출력
방법2: 정규 표현식을 사용할 경우
import re
pat = re.compile("(\d{6})[-]\d{7}")
print(pat.sub("\g<1>-*******", personal_info)) # g<1> : 주민번호 앞부분 그룹을 의미
비밀번호 감추기
getpass
getpass
는 사용자가 비밀번호를 입력할 때 이를 화면에 노출하지 않도록 해주는 모듈
비밀번호 잠금 해제 예제
# 원본 비밀번호
passwd = 'abcdefg1234'
# 사용자 입력 비밀번호
user_input = input("비밀번호를 입력하세요 >>> ")
while user_input != passwd:
# 비밀번호 불일치 메세지
user_input = input("잘못된 비밀번호 입니다! 다시 입력해주세요 >>>")
print('잠금이 해제되었습니다 !')
print('''
▒▒▒▒▒▒▒▒▒▒▒▒
▒▒▒▒▓▒▒▓▒▒▒▒
▒▒▒▒▓▒▒▓▒▒▒▒
▒▒▒▒▒▒▒▒▒▒▒▒
▒▓▒▒▒▒▒▒▒▒▓▒
▒▒▓▓▓▓▓▓▓▓▒▒
▒▒▒▒▒▒▒▒▒▒▒▒''')
비밀번호 감추기
import getpass
# 사용자 입력 비밀번호
user_input = getpass.getpass("비밀번호를 입력하세요 >> ")
while user_input != passwd:
# 비밀번호 불일치 메세지
user_input = getpass.getpass("잘못된 비밀번호입니다! 다시 입력해주세요 >>>")
print("잠금이 해제되었습니다!")
비밀번호 암호화
hashlib
hashlib
은 문자열을 해싱할 때 사용하는 모듈이다.- 해싱이란 원본 문자열을 알아볼 수 없는 난해한 문자열로 정의하는 방법으로
- 해시값을 조사하여 데이터 변조 여부를 확인하는 것이 주된 목적
- 단방향 해시 함수는 수학적 연산에 의해 원본 데이터를 완전히 다른 암호화된 데이터로 변환
- 변환된 데이터는 다시 원본 데이터로 복호화가 불가능
- 안전하게 관리되어야 하는 정보를 암호화 할 때 주로 사용
예제
import hashlib
import getpass
# 원본 비밀번호
passwd = 'fastcampus123!'
# 비밀번호 해싱
h = hashlib.sha256()
h.update(passwd.encode('utf-8'))
# 해싱된 비밀번호
h_passwd = h.digest()
print(h_passwd)
# b'T\xec\x92\x01P\x7f\xd6\xd9\xd0h\x9a<]\x83\xc59\xd2\xdd\x84\x06\x84\xa6\x11\xd1\x9b\xb9\x85\xf7\xc2:U\x9e'
방법1: 해싱을 사용하지 않은 경우
# 사용자 입력 비밀번호
user_input = getpass.getpass("비밀번호를 입력하세요 >>> ")
while user_input != passwd:
# 비밀번호 불일치 메세지
user_input = getpass.getpass("잘못된 비밀번호입니다! 다시 입력해주세요 >>>")
print("방금 입력하신 비밀번호는 ...: {}".format(user_input))
print("잠금이 해제되었습니다 !")
# 비밀번호를 입력하세요 >>> ········
# 잘못된 비밀번호입니다! 다시 입력해주세요 >>> ········
# 방금 입력하신 비밀번호는 ... : fastcampus!
# 잘못된 비밀번호입니다! 다시 입력해주세요 >>> ········
# 방금 입력하신 비밀번호는 ... : fastcampus123!
# 잠금이 해제되었습니다 !
방법2: 해싱을 사용한 경우
# 비밀번호 해싱 함수
def passwd_hash(original_passwd):
h = hashlib.sha256()
h.update(original_passwd.encode('utf-8'))
hashed_passwd = h.digest()
return hashed_passwd
# 사용자 입력 비밀번호
user_input = passwd_hash(getpass.getpass("비밀번호를 입력하세요 >>> "))
while user_input != h_passwd:
# 비밀번호 불일치 메세지
user_input = passwd_hash(getpass.getpass("잘못된 비밀번호입니다! 다시 입력해주세요 >>> "))
print("방금 입력하신 비밀번호는 ...: {}".format(user_input))
print('잠금이 해제되었습니다 !')
메세지 변조 확인
hmac
hmac
은 비밀 키와 해싱 기술을 사용하여 송수신자 간 메세지 변조를 확인할 수 있도록 하는 모듈- 송수신자 간 약속한 비밀키를 사용해서 해싱된 데이터 내용이 같은지 대조하는 원리
- 만약 해커 등 제 3자가 메세지를 변조했을 경우, 비밀키로 해싱한 결과가 달라짐
# 비밀 키 설정
SECRET_KEY = 'FASTCAMPUS'
import hmac
import hashlib
# 송신 메세지 입력
important_message = '아주 중요한 메시지'
# 원본 파일
with open('message.txt', 'w') as f:
f.write(important_message)
# 비밀 키 암호화 파일
with open('message_encrypted.txt', 'w') as f:
m = hmac.new(SECRET_KEY.encode('utf-8'), iportant_message.encode('utf-8'), hashlib.sha256)
f.write(m.hexdigest())
[수신] 복호화 및 변조 확인
with open('message_encrypted.txt') as f:
message_encrypted = f.read()
with open('message.txt') as f:
message = f.read()
m = hmac.new(SECRET_KEY.encode('utf-8'), message.encocde('utf-8'),
hashlib.sha256)
if m.hexidigest() == message_encrypted:
print("메세지가 변조되지 않았습니다! 안전합니다.")
else:
print("변조된 메세지 입니다! 위헙합니다.")
난수 생성
secrets
- 난수란 정의된 범위 내에서 무작위로 추출된 수
- 가장 널리 사용되는 난수 생성 함수인
random
은 보안이나 암호를 목적으로 사용되기에 위험함 secrets.token-hex(nbytes)
: nbytes는 바이트 수
import secrets
# 8 바이트 난수 (16자리)
rand8 = secrets.token_hex(8)
print(rand8)
# 16 바이트 난수 (32자리)
rnad16 = secrets.token_hex(16)
print(rand16)
OTP 비밀번호 생성기
import secrets
import string
string.digits
# '0123456789'
OTP = ''
digit = string.digits
for i in range(6):
OTP += str(''.join(secrets.choice(digit)))
print(OTP)
비밀번호 일치 여부 확인 (내부 해싱)
- 타이밍 공격을 방지할 수 있는 기능
print(secrets.compare_digest('password123', 'password123'))
보안 URL 생성
url = 'https://mywebsite.com/reset=' + secrets.token_urlsafe(7)
print(url)
'Python > 학습용' 카테고리의 다른 글
📅 달력 만들기 (0) | 2025.04.13 |
---|---|
🐍 Python 파일 및 디렉터리 처리 완전 정복 (0) | 2025.04.12 |
LLM - Fine-Tuning (0) | 2025.03.21 |
추천시스템 (3): 협업필터링 실습 (0) | 2025.03.21 |
추천시스템 (2): 협업필터링 (0) | 2025.03.21 |