반응형
여승철
INTP 개발자
여승철
  • 분류 전체보기 (376)
    • CS (16)
      • 면접 준비 (7)
      • 운영체제 (0)
      • 네트워크 (2)
      • HTTP (6)
      • 스프링(Spring) IoC 컨테이너 (0)
      • 알고리즘 (1)
    • Web (13)
    • AWS (6)
    • Java (43)
    • JSP & Servlet (65)
      • 개념 (42)
      • 실습 (23)
    • Spring Framework (33)
    • Spring Boot (10)
    • Spring Data (22)
      • JPA (14)
      • Query DSL (7)
      • Redis (1)
    • Spring Security (9)
    • Spring Batch (4)
    • MyBatis (10)
    • Front-End (51)
      • JS (27)
      • Vue.js (17)
      • React (5)
      • JQuery (0)
      • d3.js (2)
    • DBMS (24)
      • SQL, RDBMS (16)
      • MongoDB (5)
      • Redis (3)
    • Kafka (3)
    • 리눅스 (Linux) (4)
    • 디자인 패턴 (3)
    • VCS (8)
    • API (0)
    • TOOL (3)
    • Reading Book (28)
      • 이펙티브 자바 (11)
      • Clean Code (10)
      • 1분 설명력 (4)
      • HOW TO 맥킨지 문제해결의 기술 (3)
    • C# (4)
    • NSIS (6)
    • ETC (11)

블로그 메뉴

  • 홈
  • 태그

인기 글

태그

  • HTTP
  • 디자인 패턴
  • mybatis
  • querydsl
  • JDBC
  • 게시판
  • 환경 세팅
  • 이펙티브 자바
  • controller
  • EC2
  • ubuntu
  • 로그인
  • 스트림
  • Spring Batch
  • JSTL
  • servlet
  • Dao
  • 회원 관리
  • 맥킨지
  • jsp

최근 댓글

최근 글

hELLO· Designed By 정상우.
여승철

INTP 개발자

RSA를 이용하여 페이로드(ex. 비밀번호) 암호화하기 (Vue.js / Spring Boot)
Web

RSA를 이용하여 페이로드(ex. 비밀번호) 암호화하기 (Vue.js / Spring Boot)

2024. 3. 12. 16:48
반응형

0. 상황

Vue.js에서 아이디(userId)와 비밀번호(userPassword)를 입력하여 로그인을 해봅니다.

개발자 모드(F12)를 켜서 페이로드를 살펴보면 다음과 같이 사용자가 입력한 아이디와 비밀번호를 바로 확인할 수 있습니다.

 

보안을 위해 비밀번호(userPassword)를 암호화하여 요청하고 싶습니다. 이때 우리는 바로 전 포스팅에서 생성한 비대칭 키 RSA를 사용할 것입니다. 

 

 

1. Vue.js에서 RSA 공개키로 암호화

JavaScript 라이브러리인 jsencrypt를 사용하여 암호화를 수행할 것입니다. 이를 위해 먼저 jsencrypt를 설치해줍니다.

npm install jsencrypt

그런 다음, Vue.js 컴포넌트에서 RSA 공개키로 암호화를 수행하는 코드를 작성합니다.

저는 해당 코드를 전역으로 사용하기 위해 main.js에 작성하였습니다.

function encryptData(data, publicKey) {
  var encryptor = new JSEncrypt();
  encryptor.setPublicKey(publicKey);
  return encryptor.encrypt(data).toString();
}

Vue.prototype.$encryptData = encryptData;

 

해당 코드를 통해 원래 평문으로 보내졌던 비밀번호가 다음과 같이 암호화됨을 확인할 수 있습니다.

 

 

2. Spring Boot에서 RSA 개인키로 복호화

RSA 공개키로 암호화된 비밀번호를 서버에서 받으면 RSA 개인키로 복호화 해주어야 합니다.

전 생성한 private_key_pkcs8.pem 파일을 resources 디렉토리 밑에 두었습니다. 예제 볼때 참고!!

@Value("${rsa.private-key.filename}")
private String privateKeyFile;

public String decryptData(String encryptedData) {
    try {

        // RSA 개인키의 문자열
        Resource privateKeyResource = new ClassPathResource(privateKeyFile);
        String privateKeyContent = new BufferedReader(new InputStreamReader(privateKeyResource.getInputStream()))
                .lines().collect(Collectors.joining("\n"))
        privateKeyContent = privateKeyContent
            .replace("-----BEGIN PRIVATE KEY-----", "")
            .replace("-----END PRIVATE KEY-----", "")
            .replaceAll("\\s+", "");
		
        // RSA 개인키를 PrivateKey 객체로 변환
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKeyContent);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey privateKey = keyFactory.generatePrivate(keySpec);

        // 암호문을 바이트 배열로 변환하고 복호화
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
        byte[] decryptedBytes = decryptEncryptedBytes(encryptedBytes, privateKey);

        // 복호화된 데이터 문자열로 변환
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    } catch (Exception e) {
        e.printStackTrace();
        throw new SSMAuthException(ErrorCode.FAIL_DECRYPT_DATA, e.getMessage());
    }
}

// 복호화를 위한 Cipher 객체 초기화
private byte[] decryptEncryptedBytes(byte[] data, PrivateKey privateKey) throws Exception {
    Cipher cipher = Cipher.getInstance("RSA");
    cipher.init(Cipher.DECRYPT_MODE, privateKey);
    return cipher.doFinal(data);
}
  • 헤더와 푸터(-----BEGIN PRIVATE KEY-----, -----END PRIVATE KEY-----)를 삭제해주었습니다.
  • 정규식에서 \s는 공백 문자를 나타냅니다. 공백 문자는 스페이스, 탭, 개행 등을 포함합니다. \s+을 매칭함으로 한 개 이상의 공백 문자들을 빈 문자열("")로 바꿔주었습니다. 위에 개행("\n")으로 문자열을 이어준 것이 의미가 없지만, 파일에 있는 private_key_pkcs8.pem 파일에 담긴 문자열을 그대로 가져와 확인하기 위해 작성해보았습니다.

 

지금까지 RSA 암호화를 통해 요청 시 데이터의 보안을 고려하는 방법을 살펴보았습니다. 각각의 데이터들을 암호화하거나, 객체를 통째로 암호화하거나, 각 데이터들을 암호화하여 하나의 필드에 두는 등 여러 방법을 고려하여 도입해봐야겠습니다.

 

 

 

반응형

'Web' 카테고리의 다른 글

OpenSSL을 통해 RSA 공개키, 개인키 생성하기  (0) 2024.03.12
웹 보안을 위한 XSS, CSRF 방어  (1) 2023.11.13
CORS(Cross-Origin Resource Sharing) 이해와 해결 방법  (0) 2023.09.18
웹 데이터 저장: 로컬 스토리지, 세션 스토리지, 쿠키  (0) 2023.09.18
Jar와 War의 차이(spring initializr packaging)  (0) 2023.09.01
    여승철
    여승철

    티스토리툴바