Some iOS and macOS applications require secure random numbers to create secrets and make an app harder to exploit. This post presents examples of generating secure random numbers and data using the Security framework in Swift:

  1. SecRandomCopyBytes
  2. Secure Random Bytes
  3. Secure Random Data
  4. Secure Random Int

SecRandomCopyBytes

Swift provides a number of interfaces for generating random numbers. However, most Swift interfaces for random do not use secure random algorithms. The Security framework in Swift provides a function SecRandomCopyBytes specifically for generating random numbers using a secure algorithm.

Calling SecRandomCopyBytes copies one or more securely and randomly generated bytes into a byte array. SecRandomCopyBytes takes three arguments:

// kSecRandomDefault specifies the default 
//     random number generator
// count is the number of bytes to generate
// bytes is a byte array
SecRandomCopyBytes(kSecRandomDefault, count, &bytes) 

Secure Random Bytes

Use SecRandomCopyBytes to generate secure random bytes:

func secureRandomBytes(count: Int) throws -> [Int8] {
    var bytes = [Int8](repeating: 0, count: count)

    // Fill bytes with secure random data
    let status = SecRandomCopyBytes(
        kSecRandomDefault, 
        count, 
        &bytes
    )

    // A status of errSecSuccess indicates success
    if status == errSecSuccess {
        return bytes
    }
    else {
        // Handle error
    }
}

Secure Random Data

To generate secure random data, use SecRandomCopyBytes to generate secure random bytes and convert the secure random bytes into Data:

func secureRandomData(count: Int) throws -> Data {
    var bytes = [Int8](repeating: 0, count: count)

    // Fill bytes with secure random data
    let status = SecRandomCopyBytes(
        kSecRandomDefault, 
        count, 
        &bytes
    )
    
    // A status of errSecSuccess indicates success
    if status == errSecSuccess {
        // Convert bytes to Data
        let data = Data(bytes: bytes, count: count)
        return data
    }
    else {
        // Handle error
    }
}

Secure Random Int

To generate a secure random Int, use SecRandomCopyBytes to generate secure random bytes and convert the secure random bytes into an Int:

func secureRandomInt() throws -> Int {
    let count = MemoryLayout<Int>.size
    var bytes = [Int8](repeating: 0, count: count)

    // Fill bytes with secure random data
    let status = SecRandomCopyBytes(
        kSecRandomDefault, 
        count, 
        &bytes
    )
    
    // A status of errSecSuccess indicates success
    if status == errSecSuccess {
        // Convert bytes to Int
        let int = bytes.withUnsafeBytes { pointer in
            return pointer.load(as: Int.self)
        }

        return int
    }
    else {
        // Handle error
    }
}

Secure Random in Swift

That’s it! By using SecRandomCopyBytes and the Security framework you can generate secure bytes, data, and integers in Swift.