간단하게 iOS 앱의 Realm 데이터 보호하기 - 암호화 튜토리얼

사용자가 앱에 개인 정보를 입력하면, 이는 안전하게 지켜질거란 암묵적인 약속이 기반합니다. 하지만 여전히 많은 제품과 서비스에서 보안을 설계의 핵심 구성 요소가 아닌 나중에 생각할 것으로 취급하고 있죠.

Realm Objective-C 0.89와 이후에 배포된 Realm Swift에서 저희는 Realm 파일을 암호화하는 기능을 도입했습니다. Realm의 암호화 기능은 AES-256+SHA2 암호화로 뒷받침되는 64바이트의 키를 사용하여 안정성이 보장되며, 대형 은행과의 수많은 보안 감사를 거쳐 스마트폰 은행 앱에서도 사용되고 있습니다.

Realm의 암호화 기능을 통합하는 것은 매우 쉽습니다. Realm 설정에서 하나의 추가 설정만 추가하면 됩니다.

구현

Realm의 파일에 암호화를 사용하려면 Realm / RLMRealm 인스턴스의 Configuration / RLMRealmConfiguration 객체에 encryptionKey 속성을 추가하세요.

Swift

// 64 바이트의 랜덤 데이터를 생성해서 암호화 키로 사용합니다
let key = NSMutableData(length: 64)!
SecRandomCopyBytes(kSecRandomDefault, key.length, UnsafeMutablePointer<UInt8>(key.mutableBytes))

// 키를 사용해서 새 Realm 구성 객체를 설정하세요
let encryptionConfig = Realm.Configuration(encryptionKey: key)

// 암호화된 Realm을 여는 시도를 합니다
do {
  let realm = try Realm(configuration: encryptionConfig)
  // At this point, the key was accepted and we can use the Realm as normal
  let dogs = realm.objects(Dog.self).filter("name contains 'Fido'")
}
catch let error as NSError {
  // If the encryption key was not accepted, the error will state that the database was invalid
  fatalError("Error opening Realm: \(error)")
}

이런 개발 뉴스를 더 만나보세요

Objective-C

// 64 바이트의 랜덤 데이터를 생성해서 암호화 키로 사용합니다
uint8_t buffer[64];
SecRandomCopyBytes(kSecRandomDefault, 64, buffer);
NSData *keyData = [[NSData alloc] initWithBytes:buffer length:sizeof(buffer)];

// 키를 사용해서 새 Realm 구성 객체를 설정하세요
RLMRealmConfiguration *configuration = [RLMRealmConfiguration defaultConfiguration];
configuration.encryptionKey = keyData;

// 암호화된 Realm을 여는 시도를 합니다
NSError *error = nil;
RLMRealm *realm = [RLMRealm realmWithConfiguration:configuration error:&error];

// 암호화 키가 수락되지 않는 경우 데이터베이스가 유효하지 않은 에러를 나타냅니다
if (error != nil) {
  NSLog(@"%@", error.localizedDescription);
  return;
}

// 이 시점에서는 키가 수락되고 정상적으로 Realm을 사용할 수 있습니다
RLMResults *dogs = [Dog objectsWhere:@"name contains 'Fido'"];

다음 구현

일단 Realm 파일이 암호화 키로 생성되면, 파일이 열릴 때마다 해당 키가 필요합니다. 잘못된 키나 빈 키로 파일을 열려는 시도가 있으면 Realm은 데이터베이스가 ‘유효하지 않다’는 임의의 오류를 반환합니다.

이전에는 암호화된 Realm이 사용되면서 LLDB를 방해했기 때문에 앱에 디버거를 첨부할 수 없었습니다.하지만 0.97 버전 이후로는 암호화된 Realm을 일반 Realm처럼 쉽게 디버깅할 수 있습니다.

한계점

한번 암호화 키가 설정되면 해당 Realm 파일에 대한 암호화 키를 변경할 수 없습니다. 암호화 키를 변경하려면 writeCopyToPath(_:encryptionKey:) 메서드를 통해 Realm 파일 복사본을 내보내고 복사본에 새 암호화 키를 설정해야 합니다. 암호화를 사용하면 데이터 암호화와 암호 해독 작업이 필요하므로 Realm에 약간의 오버헤드가 발생합니다.

암호화 키 안전하게 유지하기

데이터 자체는 Realm에 의해 안전하게 보호되더라도 가장 큰 보안 문제는 암호화 키를 보호하는데 있습니다. 암호화 키를 안전하게 유지하는 것은 개발자의 책임이므로 사용자의 계정 비밀번호를 처리하는 것과 같이 철저한 검토 및 조사가 필요합니다.

단일 기기에서 생성되고 절대 전송되지 않는 Realm 파일의 경우 가장 안전한 옵션은 암호화 키를 시스템 보안 키체인에 저장하는 것입니다.

보안 키체인은 매우 강력한 저장소 위치로, 기기에서 사용자 비밀번호를 저장하기 위한 업계 표준입니다. 보안 키체인에 데이터를 저장하는 예제는 저희 샘플 앱 중 ‘Encryption’ 예제에서 볼 수 있습니다.

여러 장치의 경우 암호화된 Realm 파일을 새 장치에 복사할 때 새 장치에서 암호화 키가 사용 가능해야 합니다. 암호화 키를 키체인에 저장하고 iCloud로 동기화하거나, 커스텀 온라인 사용자 로그인 서비스 등 다양한 방법을 통해 이를 허용할 수 있습니다.

Apple App Store를 통해 앱을 배포할 때 암호화 기능이 통합된 앱의 수출 규정과 관련된 법적 의무가 존재합니다.

보통 여기에는 앱에 암호화가 통합돼 있으며, 암호화된 데이터의 성격에 따라 미국 산업 안전청에 수출 등록 요청서를 제출해야 한다는 내용이 포함됩니다.

다만 사용자 인증과 같이 일반적인 암호화 사용 사례 대부분의 경우 2010년에 면제 조항이 등록되었으므로 Apple에 앱 제출 과정 중에 암호화가 통합되어 있음을 알리는 것으로 축소됐습니다.

미국 수출 규정 및 특정 면제에 대한 자세한 내용은 [미국 산업 보안국 웹 사이트] (http://www.bis.doc.gov/index.php/policy-guidance/encryption)에서 확인할 수 있습니다.

권리포기각서: 이 섹션의 정보는 공식적인 법률 자문이 아니며, 암호화에 대한 특정 사용 사례는 다양합니다. 확실하지 않은 경우 앱이 수출 규정 준수 면제 조항에 해당되는지 변호사에게 문의하십시오.

결론

일반적으로 암호화에는 많은 시간이 들고 복잡한 프로세스가 필요하지만, Realm을 사용하면 앱 내부의 민감한 사용자 데이터를 정말 간단한 프로세스만으로 암호화할 수 있습니다. Realm 파일의 설정에서 키를 정의하고, 그 다음의 일은 명료하게 처리됩니다.

암호화를 쉽게 통합할 수 있는 이 기능으로, 개발자가 사용자의 데이터를 적절하게 보호하고 향후 데이터 유출을 최소화하는데 도움이 되길 바랍니다.

다음: iOS를 위한 Realm #4: 동기 Realm 마이그레이션 가이드

General link arrow white

컨텐츠에 대하여

이 컨텐츠는 저자의 허가 하에 이곳에서 공유합니다.


Tim Oliver

호주 퍼스 출신인 Tim Oliver는 6년간 iOS 개발자로 일했으며, 2015년 3월에 Realm에 합류했습니다. iComics라는 앱의 개발자이며 가라오케를 좋아합니다. 가끔 뒷마당에 너무 캥거루가 많이 오는 것이 골칫거리라고 합니다.

4 design patterns for a RESTless mobile integration »

close