문제 해결
react-native-aws-kms 사용 중 발생할 수 있는 오류와 해결 방법
문제 해결
자주 발생하는 오류
AccessDeniedException — 접근 거부
원인:
- IAM 사용자/역할에 KMS 권한이 없음
- 잘못된 KMS 키 ARN 사용
- 자격증명 만료
해결 방법:
-
IAM 정책에 필요한 권한이 있는지 확인합니다:
{"Action": ["kms:GenerateDataKey", "kms:Decrypt", "kms:Encrypt"],"Resource": "arn:aws:kms:REGION:ACCOUNT:key/KEY_ID"} -
KMS 키의 Key policy에서 해당 IAM 엔터티가 허용되어 있는지 확인합니다.
-
임시 자격증명이 만료된 경우
init()을 새 자격증명으로 재호출합니다:const newCreds = await fetchFreshCredentials();await AwsKmsExpoModule.init({ ...newCreds, keyId: KEY_ARN });
InvalidKeyUsageException — 잘못된 키 사용
원인: KMS 키의 사용 용도가 ENCRYPT_DECRYPT가 아님
해결 방법: AWS KMS 콘솔에서 키 설정을 확인합니다.
- Key type: Symmetric
- Key usage: Encrypt and decrypt
서명 전용(Sign and verify) 키로 암호화를 시도하면 이 오류가 발생합니다.
KMSInvalidStateException — KMS 키 상태 오류
원인: KMS 키가 비활성화되었거나 삭제 예약된 상태
해결 방법:
AWS KMS 콘솔에서 키 상태를 확인합니다.
- Disabled 상태: 키를 활성화(Enable)합니다.
- Pending deletion 상태: 삭제 예약을 취소하거나 새 키를 생성합니다.
NotFoundException — 키를 찾을 수 없음
원인:
keyId가 잘못된 ARN 또는 ID- 다른 AWS 리전의 키를 참조
해결 방법:
// 잘못된 예await AwsKmsExpoModule.init({keyId: 'my-key', // 별칭만으로는 찾을 수 없을 수 있음});// 올바른 예 (전체 ARN 사용)await AwsKmsExpoModule.init({keyId: 'arn:aws:kms:ap-northeast-2:123456789012:key/mrk-1234abcd12341234',});
init() 미호출 오류
원인: encrypt() 또는 decrypt()를 init() 이전에 호출
증상: 네이티브 모듈에서 KMS client not initialized 등의 오류 발생
해결 방법:
앱 시작 시 또는 API 호출 전에 반드시 init()을 호출합니다:
// App.tsx 또는 루트 컴포넌트에서useEffect(() => {async function initializeKms() {const creds = await getAwsCredentials();await AwsKmsExpoModule.init({...creds,keyId: KMS_KEY_ARN,});}initializeKms();}, []);
네트워크 오류 — AWS KMS API 호출 실패
원인:
- 기기 네트워크 연결 없음
- VPC 내부 전용 KMS 엔드포인트에 외부에서 접근 시도
- 잘못된 엔드포인트 URL
해결 방법:
// 커스텀 엔드포인트 설정await AwsKmsExpoModule.init({accessKey: '...',secretKey: '...',sessionToken: '...',keyId: '...',endpoint: 'https://kms.ap-northeast-2.amazonaws.com', // 리전별 엔드포인트});
네트워크 연결을 확인하고, 오프라인 상태에서는 암호화/복호화 작업을 지연시킵니다:
import NetInfo from '@react-native-community/netinfo';const state = await NetInfo.fetch();if (!state.isConnected) {throw new Error('KMS 작업을 위해 네트워크 연결이 필요합니다.');}
플랫폼별 이슈
iOS
NSURLSession SSL 오류
AWS KMS API는 HTTPS를 사용합니다. iOS의 ATS(App Transport Security) 설정이 AWS 도메인을 차단하지 않는지 확인합니다. 일반적으로 *.amazonaws.com은 ATS 기본 요건을 충족합니다.
Android
NetworkOnMainThreadException
모든 KMS 모듈 함수는 비동기(Promise)이므로 올바르게 await를 사용하고 있는지 확인합니다. 네이티브 레이어에서 별도 스레드에서 네트워크 작업을 수행하지만, JS 측에서 동기적으로 호출을 시도하면 안 됩니다.
minSdkVersion 오류
Android API 26 미만 기기 지원이 필요한 경우 모듈을 사용할 수 없습니다. android/build.gradle의 minSdkVersion을 26 이상으로 설정합니다.
자격증명 만료 처리
임시 자격증명(STS/Cognito)은 일정 시간 후 만료됩니다. 만료 후 KMS API 호출은 실패합니다.
async function withKmsRetry<T>(operation: () => Promise<T>): Promise<T> {try {return await operation();} catch (error: any) {// 자격증명 만료 감지 (오류 메시지로 판단)if (error?.message?.includes('ExpiredToken') ||error?.message?.includes('AccessDenied')) {// 자격증명 갱신const newCreds = await refreshAwsCredentials();await AwsKmsExpoModule.init({...newCreds,keyId: KMS_KEY_ARN,});// 재시도return await operation();}throw error;}}// 사용 예const encrypted = await withKmsRetry(() =>AwsKmsExpoModule.encrypt('민감한 데이터'));
프로덕션 환경에서는 자격증명 만료 시간을 추적하여 만료 전에 미리 갱신하는 것이 더 안정적입니다. 자격증명 만료 후 재시도는 사용자 경험을 저하시킬 수 있습니다.