E2EE(E2EE, End to End Encryption)란, 메시지를 보내는 곳부터 받는 곳까지 모든 과정에서 암호화된 상태로 메시지를 전달하는 것을 의미하며 '종단간 암호화'라고도 합니다.
MKFacePro에서는 E2EE에서 사용하는 암호화에 TOTP를 사용합니다. 공유된 키와 시간정보를 활용하여 매번 암호화키가 변경됨으로서 높은 보안성을 가집니다. TOTP를 통한 암호화의 장점은 다음과 같습니다.
MKFacePro에서는 시간정보를 통해 TOTP(6자리 숫자)를 생성하고, 해당 TOTP를 암호화키로 사용하여 전송할 전문을 암호화 후 전송합니다. 수신 측에서는 공유된 키와 시간정보를 통해 TOTP를 생성하여 전문을 복호화합니다.
먼저 암호화를 위해서는 TOTP를 생성해야 합니다. TOTP 생성을 위해서는 키가 필요합니다. 해당 키는 양 단말이 공유하고 있어야 합니다.
TOTP 키는 WORKING_ID + 16자리 랜덤값으로 이루어집니다. 해당 키를 통해 TOTP를 6자리를 생성합니다. 데이터 수신자도 키를 공유해야 복호화가 가능합니다. WORKING_ID는 공유된 상태에서 사용하며 16자리 랜덤값은 데이터 전송시마다 TLV 데이터에 삽입하여 수신단말측에서 사용할 수 있도록 합니다.
TOTP 키를 통해 6자리 TOTP를 생성합니다. TOTP 생성은 복잡한 계산과정을 가지고 있습니다. 상세한 TOTP 알고리즘은 다음 문서를 참조하십시오.
TOTP 값을 사용하여 최종적인 E2EE 암호화 키를 생성합니다. 고정된 32bytes 키 테이블에 TOTP 값을 중간에 분산 삽입하여 최종 암호화 키를 생성하고 암호화를 진행합니다. 키 생성 로직은 다음과 같습니다.
void getSessionKey(unsigned char *otpValue, unsigned char *sessionKey)
{
static unsigned char tmpK[32] = {
0x31, 0x7f, 0x8b, 0x6d, 0xd3, 0xcc, 0x6f, 0x80,
0x71, 0x37, 0xcf, 0x8a, 0x03, 0xc4, 0xbc, 0x9b,
0x23, 0x5e, 0x5a, 0x97, 0x07, 0x93, 0x0a, 0x53,
0x70, 0x23, 0xdb, 0xdc, 0x4c, 0x6b, 0x1c, 0x04
};
tmpK[ 0] = otpValue[0];
tmpK[ 5] = otpValue[1];
tmpK[ 8] = otpValue[2];
tmpK[13] = otpValue[3];
tmpK[18] = otpValue[4];
tmpK[23] = otpValue[5];
memcpy(sessionKey, tmpK, 32);
}
수신측 단말에서는 이미 공유된 WORKING_ID + 전달받은 덤값을 통해 TOTP Key를 준비하고, 현재 시각 정보를 통해 TOTP를 동일하게 생성합니다. 공유된 키를 알고 있고 사전 정의된 유효시간 내에 TOTP를 생성한다면 복호화 키가 생성될 것이고, 유효시간이 경과했다면 잘못된 값이 생성되어 복호화에 실패할 것입니다.