본문 바로가기
#모바일 [Mobile]/iOS

[iOS] 애플 암호화 개발 도구 (Apple CryptoKit Swift Framework)

by cy_mos 2019. 10. 21.
반응형
Cryptography and Your Apps

 

System frameworks encrypt both data at rest and data in transit in a transparent way for you. This functionality is available by simply setting an attribute. However you may want to do more to protect your users' data. CryptoKit is a new Swift framework that makes it easier and safer than ever to perform cryptographic operations, whether you simply need to compute a hash or are implementing a more advanced authentication protocol.

 

  • Compute and compare cryptographically secure digests.

  • Use public-key cryptography to create and evaluate digital signatures, and to perform key exchange. In addition to working with keys stored in memory, you can also use private keys stored in and managed by the Secure Enclave.

  • Generate symmetric keys, and use them in operations like message authentication and encryption.


⏰ Apple CryptoKit 성능 (Performance - Using CPU, Memory)

  • 테스트 파일 크기 - 1KB, 1MB, 1GB, 2GB, 5GB

CryptoKit HMAC Using CPU
CryptoKit HMAC Using Memory
CryptoKit SHA Using CPU
CryptoKit SHA Using Memory
CryptoKit SHA256 Using CPU
CryptoKit SHA256 Using Memory
CryptoKit SHA384 Using CPU
CryptoKit SHA384 Using Memory
CryptoKit SHA512 Using CPU
CryptoKit SHA512 Using Memory

📄 CryptoKit Message Authentication Example Swift Source Code

CryptoKitAuth.swift
0.00MB

/*
 * Copyright (c) 2019 양창엽. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
 
import CryptoKit
import Foundation

@available(iOS 13, OSX 10.15, *)
class Auth: NSObject {
    
    // MARK: - Enum
    public enum AuthHashType: String {
        case MD5 = "MD5"
        case SHA1 = "SHA1"
        case SHA256 = "SHA256"
        case SHA384 = "SHA384"
        case SHA512 = "SHA512"
    }
    
    // MARK: - Object Propertise
    internal static let shared: Auth = Auth()
    private let privateKey: P256.Signing.PrivateKey = P256.Signing.PrivateKey()
    
    // MARK: - Init
    private override init() { super.init() }
    
    // MARK: - Authentication Method
    internal func createSignature(message: Data) -> P256.Signing.ECDSASignature? {
                
        do {
            let authData: NSData = NSData(data: message)
            return try self.privateKey.signature(for: authData)
        } catch let error {
            print("❌ Error, Faily Signature to Data. - \(error.localizedDescription)")
        }
        
        return nil
    }
    internal func createPublicKey() -> P256.Signing.PublicKey {
        return self.privateKey.publicKey
    }
    internal func authenticatingDataWithHMAC(resource: Data, key: SymmetricKey, type: AuthHashType) -> Data {
                
        switch type {
        case .MD5:
            let authenticationCode = HMAC<Insecure.MD5>.authenticationCode(for: NSData(data: resource), using: key)
            return Data(authenticationCode)
        case .SHA1:
            let authenticationCode = HMAC<Insecure.SHA1>.authenticationCode(for: NSData(data: resource), using: key)
            return Data(authenticationCode)
        case .SHA256:
            let authenticationCode = HMAC<SHA256>.authenticationCode(for: NSData(data: resource), using: key)
            return Data(authenticationCode)
        case .SHA384:
            let authenticationCode = HMAC<SHA384>.authenticationCode(for: NSData(data: resource), using: key)
            return Data(authenticationCode)
        case .SHA512:
            let authenticationCode = HMAC<SHA512>.authenticationCode(for: NSData(data: resource), using: key)
            return Data(authenticationCode)
        }
    }
    internal func checkVaildAuthenticationDataWithHMAC(authCode: Data, resource: Data, key: SymmetricKey, type: AuthHashType) -> Bool {
                
        switch type {
        case .MD5:
            return HMAC<Insecure.MD5>.isValidAuthenticationCode(authCode, authenticating: NSData(data: resource), using: key)
        case .SHA1:
            return HMAC<Insecure.SHA1>.isValidAuthenticationCode(authCode, authenticating: NSData(data: resource), using: key)
        case .SHA256:
            return HMAC<SHA256>.isValidAuthenticationCode(authCode, authenticating: NSData(data: resource), using: key)
        case .SHA384:
            return HMAC<SHA384>.isValidAuthenticationCode(authCode, authenticating: NSData(data: resource), using: key)
        case .SHA512:
            return HMAC<SHA512>.isValidAuthenticationCode(authCode, authenticating: NSData(data: resource), using: key)
        }
    }
}

📄 CryptoKit Ciphers Example Swift Source Code

CryptoKitCrypto.swift
0.00MB

/*
 * Copyright (c) 2019 양창엽. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

import CryptoKit
import Foundation

@available(iOS 13, OSX 10.15, *)
class Crypto: NSObject {
    
    // MARK: - Typealias
    public typealias CryptoReturnType = (encryptedData: Any?, key: SymmetricKey?)
    
    // MARK: - Enum
    public enum CryptoType: String {
        case AES = "AES"
        case ChaChaPoly = "ChaChaPoly"
    }
    
    // MARK: - Object Propertse
    internal static let shared: Crypto = Crypto()
    
    // MARK: - Init
    private override init() { super.init() }
    
    // MARK: - Cipher Method
    internal func encryptCipher(message: String, keySize: SymmetricKeySize, type: CryptoType) -> CryptoReturnType {
        
        let cipherKey = SymmetricKey(size: keySize)
        
        guard let data = message.data(using: .utf8) else { return CryptoReturnType(nil, nil) }
        
        do {
            var encryptedData: Any?
            let cipherData = NSData(data: data)
            
            switch type {
            case .AES:
                encryptedData = try AES.GCM.seal(cipherData, using: cipherKey)
            case .ChaChaPoly:
                encryptedData = try ChaChaPoly.seal(cipherData, using: cipherKey)
            }
            
            return CryptoReturnType(encryptedData, cipherKey)
        } catch let error {
            print("❌ Error, Failly encrypt cipher message. - \(error.localizedDescription)")
        }
        
        return CryptoReturnType(nil, nil)
    }
    internal func decryptCipher(encryptedMessage: Any, key: SymmetricKey, type: CryptoType) -> Data? {
                
        do {
            switch type {
            case .AES:
                guard let sealed = encryptedMessage as? AES.GCM.SealedBox else { return nil }
                return try AES.GCM.open(sealed, using: key)
            case .ChaChaPoly:
                guard let sealed = encryptedMessage as? ChaChaPoly.SealedBox else { return nil }
                return try ChaChaPoly.open(sealed, using: key)
            }
            
        } catch let error {
            print("❌ Error, Failly decrypt cipher message. - \(error.localizedDescription)")
        }
        
        return nil
    }
}

🚀 REFERENCE

 

Apple CryptoKit | Apple Developer Documentation

Use CryptoKit to carry out operations like hashing, key generation, and encryption.

developer.apple.com

 

ChangYeop-Yang/Study-macOS

Contribute to ChangYeop-Yang/Study-macOS development by creating an account on GitHub.

github.com

 

Cryptography and Your Apps - WWDC 2019 - Videos - Apple Developer

System frameworks encrypt both data at rest and data in transit in a transparent way for you. This functionality is available by simply...

developer.apple.com

 

반응형

댓글