2021년 1월 9일 개발 일지
전자동의서 및 서명 파일을 전송하는 클라이언트와 서버 통신 과정
화면에 전자 동의서를 이미지 파일을 보여주고 서명란에 사용자가 터치패드로 직접 서명할 수 있도록 한 후 서명 사진을 저장하여 서버로 전송할 때 정보 보호를 위해 클라이언트와 서버 간에 해시 값 검증 및 사진 파일 암호화를 하는 클라이언트 구현 작업을 했다. 작업 순서는 아래와 같다.
- 클라이언트에서 전자동의서 정보 요청
- 서버에서 전자동의서 이미지 목록 제공 (동시에 암호화 키 제공)
- 클라이언트에서 전자동의서 이미지를 순서대로 보여주고 사용자의 서명이 필요한 마지막 장에 서명할 수 있는 터치 패드 컴포넌트 넣기
- 사용자가 터치 패드에서 서명한 사진 저장하기
- 서명된 사진을 해시하여 사진 파일을 서버에서 제공한 암호화 키로 암호화하여 서버로 전송
- 서버에서 해시 값을 검증하는 과정을 거친 후 서명 사진을 저장
MD5 해시 및 암호화 하는 방법
클라이언트에서 서명 파일을 저장하여 MD5 해시 값을 만들고 서버에서 제공 받은 암호화된 퍼블릭 키(publicKeyEncoded)로 MD5 해시를 암호화하여 해시 값과 이미지 파일을 서버로 전송하는 과정은 아래와 같다.
-
CryptoJS 라이브러리를 설치한 후
npm install crypto-js
npm install --save @types/crypto-js
-
이미지 파일을 MD5 해시하여 해시 값을 추출한다.
let CryptoJS = require("crypto-js");
const getMd5Hash = (dataUrl: string) => {
const hash = CryptoJS.MD5(CryptoJS.enc.Latin1.parse(dataUrl));
const md5 = hash.toString(CryptoJS.enc.Hex)
console.log(md5);
return md5
}
-
프로젝트 폴더에 /public/assets/ 폴더에
jsencrypt.min.js
를 추가한다. -
Index.html
에 스크립트를 추가한다.<script src=“%PUBLIC_URL%/assets/jsencrypt.min.js”></script>
-
서버에서 받은 암호화된 퍼블릭 키(publicKeyEncoded)로 MD5 해시를 암호화하여 해시 값을 추출한다.
const rsaEncrypt = (publicKey: string, md5: string) => {
//전자동의서 파일 조회 API 에서 받은 "publicKeyEncoded"
let jsEncrypt = new JSEncrypt();
jsEncrypt.setPublicKey(publicKey);
let fileHash = jsEncrypt.encrypt(md5);
console.log("이미지 파일 hash값 RSA 암호화 : " + fileHash);
return fileHash
}
- 암호화한 해시 값과 이미지 파일을 서버로 전송한다.
const md5 = Utils.getMd5Hash(signDataUrl)
const fileHash = Utils.rsaEncrypt(data.publicKeyEncoded, md5)
let formData = new FormData()
formData.append('signatureCaptureFileBase64', signDataUrl)
formData.append('signatureCaptureFileHashRsa', fileHash)
const res = await API.sendMyTrialSign(formData)
if (res && res.success) {
setAlert(true, '서명을 제출하였습니다.')
close()
}
파일 암호화 하는 과정에서 발생한 문제점
클라이언트에서 추출한 해시 값과 서버에서 재검증하는 해시 값이 달라서 계속 해시 인증에 실패하게 되었다. 백엔드 개발자와 이야기 해보니 클라이언트와 서버에서 해시할 때 각각 사용하는 파일 타입이 달랐던게 문제가 되었다. 서명 이미지 파일의 데이터 방식이 클라이언트에서는 base64 로 해시 값을 추출하였고 서버에서는 bytes array 파일을 해시 값으로 재검증 하여 같은 파일임에도 불구하고 해시 값이 달라 서버에서 해시 검증을 하지 못하였다. 따라서 파일 타입을 base64 로 통일하여 클라이언트와 서버 간의 이미지 전송 및 파일 해시 검증에 성공하게 되었다.