[iOS] 대칭/비대칭 키 생성 및 암호화

코랑·2023년 4월 17일

ios

목록 보기
2/3

암호화 관련된 모듈

  • Security
    App signing부터 암호화, 복호화, 키체인에 키 저장 및 찾기 삭제 까지 지원.
    근데 ios에서 비대칭 키만 제공을 하고 대칭키에대한 암호화는 제공하지 않음
  • CryptoKit
    블록체인, 암호화폐 개발을 위한 효율적인 암호화 알고리즘 적용을 위해서 탄생했다고 함.
    그래서 효율적으로 대용량 데이터를 암호화를 할때 유용한 api들만 제공을 하고있음.

hashing

  • Sha256/384/512 + @
SHA256.hash(data: bytes)

SymmetricKey 대칭키

CryptoKit 사용 => keychain 저장 안됨. 수동으로 구현

1. 생성

 SymmetricKey(data: data)
 SymmetricKey(size: .bits256)

2. Encryption/Decryption

  • AES: GCM
		// encrypt
        let sealedBox = try AES.GCM.seal(self, using: key)
        return sealedBox.ciphertext + sealedBox.nonce
        // decrypt
        let sealedBox = try AES.GCM.seal(self, using: key)
        guard let decryptedData = sealedBox.combined else {
            return nil
        }
        return decryptedData

AsymmetricKey 비대칭키

Security 사용

1. 생성

비대칭 키 는 public 키로 암호화를 하고 private 키로 복호화를 해서 데이터를 보호함
SecKeyCreateRandomKey(query:CFDictionary) 사용하면 됨.

query 필수 값은

  • kSecAttrKeyType: 어떤 알고리즘 사용할건지
    - value로 ios는 rsa밖에 안됨 나머지는 mac용
  • kSecAttrKeySizeInBit: 키 사이즈

optional 값

  • kSecPrivateKeyAttrs: 개인키에 포함될 정보
    - kSecAttrIsPermanent: defaultKeychain에 저장 할거냐? 이렇게 해서 생성한 키는 생성과 동시에 키체인에 저장됨
  • kSecPublicKeyAttrs: 공개키에 포함될 정보
    - kSecAttrIsPermanent: defaultKeychain에 저장 할거냐? 이렇게 해서 생성한 키는 생성과 동시에 키체인에 저장됨
		/// SecKeyCreateRandomKey API를 활용한 rsa 키 만드는 예시
        let attributes: [CFString: Any] = [
            kSecAttrKeyType: kSecAttrKeyTypeRSA,
            kSecAttrKeySizeInBits: keySize,
            kSecPrivateKeyAttrs: [
                kSecAttrIsPermanent: true,
                kSecAttrApplicationTag: tag
            ]
        ]
        
        var error: Unmanaged<CFError>?
        guard let keyPair = SecKeyCreateRandomKey(attributes as CFDictionary, &error) else {
            throw error!.takeRetainedValue() as Error
        }

2. Encryption/Decryption

// encrypt 15 이상 => SecKeyCreateEncryptedData
var error: Unmanaged<CFError>?
guard let cipherText = SecKeyCreateEncryptedData(publicKey,
                                                 algorithm,
                                                 plainText as CFData,
                                                 &error) as Data? else {
                                                    throw error!.takeRetainedValue() as Error
}
// encrypt 15 미만 => SecKeyEncrypt
let chunk = data.subdata(in: index..<index+length)
var encryptedChunk = [UInt8](repeating: 0, count: blockSize)
var encryptedLength = encryptedChunk.count
let status = SecKeyEncrypt(publicKey, .PKCS1, chunk.bytes, length, &encryptedChunk, &encryptedLength)
guard status == errSecSuccess else {
      debugPrint("\(status)")
      hrow RSAError.decryptionFailed
}

// decrypt 15 이상, 미만은 SecKeyDecrypt
var error: Unmanaged<CFError>?
guard let clearText = SecKeyCreateDecryptedData(privateKey,
                                                algorithm,
                                                cipherText as CFData,
                                                &error) as Data? else {
                                                    throw error!.takeRetainedValue() as Error
}

참고 Apple Archive
https://developer.apple.com/documentation/applearchive/encrypting_and_decrypting_a_single_file

0개의 댓글