문서 메뉴

문서 홈애플리케이션 개발Atlas Device SDK

Realm 암호화 - Swift SDK

이 페이지의 내용

  • 개요
  • 고려 사항
  • & 저장 키 재사용
  • 성능에 미치는 영향
  • 암호화 및 Atlas Device Sync
  • 여러 프로세스에서 암호화된 Realm에 액세스하기
  • 예제

Realm을 열 때 64바이트 암호화 키를 제공하여 디스크에 있는 Realm 파일을 AES-256 + SHA-2로 암호화할 수 있습니다.

Realm은256 표준 AES- 암호화 를 사용하여 데이터를 투명하게 암호화하고 256 512해독합니다. 지정된 비트 암호화 키의 처음 비트를 사용합니다. Realm은 256 512비트 암호화 키의 다른 비트를 사용하여 해시 기반 메시지 인증 코드(HMAC)를 통해 무결성을 검증합니다.

경고

Realm 암호화 키에 암호화가 취약한 해시를 사용하지 마십시오. 최적의 보안을 위해 파생된 암호화 키가 아닌 임의의 암호화 키를 생성하는 것이 좋습니다.

참고

암호화되지 않은 기존 Realm을 암호화할 수 없습니다.

Realm을 처음 열 때 Realm을 암호화해야 합니다. 암호화 키가 포함된 구성을 사용하여 암호화되지 않은 기존 Realm을 열려고 하면 Realm에서 오류가 발생합니다.

다음은 Realm을 암호화할 때 고려해야 할 주요 영향입니다.

암호화된 Realm을 열 때마다 반드시 동일한 암호화 키를 전달해야 합니다. 키를 제공하지 않거나 암호화된 영역에 잘못된 키를 지정하면 Realm SDK에서 오류가 발생합니다.

앱은 다른 앱이 키를 읽을 수 없도록 키 체인에 암호화 키를 저장해야 합니다.

암호화된 Realm의 읽기 및 쓰기 속도는 암호화되지 않은 Realm보다 최대 10% 느릴 수 있습니다.

동기화된 Realm을 암호화할 수 있습니다.

Realm은 기기의 데이터만 암호화하고 암호화되지 않은 데이터는 Atlas 데이터 소스에 저장합니다. Atlas 데이터 소스에 대한 액세스 권한이 있는 모든 사용자는 데이터를 읽을 수 있지만 다음 사항은 여전히 적용됩니다.

  • 동기화된 데이터를 읽으려면 사용자에게 올바른 읽기 권한 이 있어야 합니다.

  • Atlas에 저장된 데이터는 항상 볼륨(디스크) 수준에서 암호화됩니다.

  • 클라이언트와 서버 간의 전송은 항상 완전히 암호화됩니다.

고객 키 관리 를 활성화하여 클라우드 제공자의 키(예: AWS KMS, Azure Key Vault, Google Cloud KMS)를 사용하여 저장된 Atlas 데이터를 암호화할 수도 있습니다.

애플리케이션의 각 사용자에 대해 고유한 키가 필요한 경우 OAuth 제공자를 사용하거나 Realm 인증 제공자 중 하나와 인증 트리거 를 사용하여 64비트 키를 생성하고 해당 키를 사용자 객체에 저장할 수 있습니다.

버전 10.38.0에서 변경된 사항입니다.

Realm Swift SDK 10.38.0 버전부터 Realm은 여러 프로세스에서 동일한 암호화된 Realm을 열 수 있도록 지원합니다.

앱에서 Realm Swift SDK 10.37.2 버전 이하를 사용하는 경우 여러 프로세스에서 암호화된 Realm을 열려고 시도하면 다음 오류가 발생합니다. Encrypted interprocess sharing is currently unsupported.

이전 SDK 버전을 사용하는 앱에는 여러 프로세스의 영역에서 작업할 수 있는 옵션이 두 가지 있습니다.

  • 암호화되지 않은 Realm을 사용합니다.

  • Realm 객체에 NSData 속성으로 암호화하려는 데이터를 저장합니다. 그런 다음 개별 필드를 암호화하고 북호화할 수 있습니다.

필드를 암호화하고 해독할 수 있는 도구 중 하나는 Apple의 CryptoKit 프레임워크 입니다. .Swift Crypto 를 사용할 수 있습니다. CryptoKit으로 앱 개발을 간소화합니다.

다음 코드는 암호화 키를 생성하고 암호화된 Realm을 여는 방법을 보여 줍니다.

다음 Swift 예제는 키 체인에서 생성된 키를 저장하고 검색하는 방법을 보여 줍니다.

// Retrieve the existing encryption key for the app if it exists or create a new one
func getKey() -> Data {
// Identifier for our keychain entry - should be unique for your application
let keychainIdentifier = "io.Realm.EncryptionExampleKey"
let keychainIdentifierData = keychainIdentifier.data(using: String.Encoding.utf8, allowLossyConversion: false)!
// First check in the keychain for an existing key
var query: [NSString: AnyObject] = [
kSecClass: kSecClassKey,
kSecAttrApplicationTag: keychainIdentifierData as AnyObject,
kSecAttrKeySizeInBits: 512 as AnyObject,
kSecReturnData: true as AnyObject
]
// To avoid Swift optimization bug, should use withUnsafeMutablePointer() function to retrieve the keychain item
// See also: http://stackoverflow.com/questions/24145838/querying-ios-keychain-using-swift/27721328#27721328
var dataTypeRef: AnyObject?
var status = withUnsafeMutablePointer(to: &dataTypeRef) { SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) }
if status == errSecSuccess {
// swiftlint:disable:next force_cast
return dataTypeRef as! Data
}
// No pre-existing key from this application, so generate a new one
// Generate a random encryption key
var key = Data(count: 64)
key.withUnsafeMutableBytes({ (pointer: UnsafeMutableRawBufferPointer) in
let result = SecRandomCopyBytes(kSecRandomDefault, 64, pointer.baseAddress!)
assert(result == 0, "Failed to get random bytes")
})
// Store the key in the keychain
query = [
kSecClass: kSecClassKey,
kSecAttrApplicationTag: keychainIdentifierData as AnyObject,
kSecAttrKeySizeInBits: 512 as AnyObject,
kSecValueData: key as AnyObject
]
status = SecItemAdd(query as CFDictionary, nil)
assert(status == errSecSuccess, "Failed to insert the new key in the keychain")
return key
}
// ...
// Use the getKey() function to get the stored encryption key or create a new one
var config = Realm.Configuration(encryptionKey: getKey())
do {
// Open the realm with the configuration
let realm = try Realm(configuration: config)
// Use the realm as normal
} catch let error as NSError {
// If the encryption key is wrong, `error` will say that it's an invalid database
fatalError("Error opening realm: \(error)")
}
← Realm 파일 크기 줄이기 - Swift SDK