5

I'm working on an iOS app that is written in Objective-C and C++. In the C++ part, I need cryptographically secure random numbers.

  1. As I understand the iOS security model, there is no way to access /dev/random directly. Is that correct?

  2. The official way to get secure random numbers is SecRandomCopyBytes. Sadly, this is an Objective-C interface. Is there a way to use this interface from C++, ideally without resorting to Objective-C++?

There's also arc4random, but I'm reluctant to use anything that's based on RC4 nowadays...

zaph
  • 111,848
  • 21
  • 189
  • 228
Daniel Seither
  • 1,647
  • 1
  • 13
  • 19

2 Answers2

7

The official way to get secure random numbers is SecRandomCopyBytes. Sadly, this is an Objective-C interface. Is there a way to use this interface from C++, ideally without resorting to Objective-C++?

SecRandomCopyBytes is a C API. There is no problem using it from C++.

Here's a full example. No ObjC++ required, even using fancy vector and whatnot to show it's all C++. Obviously you could just use malloc.

#include <iostream>
#include <Security/Security.h>
#include <vector>

int main(int argc, const char * argv[]) {
    const int length = 20;
    std::vector<uint8_t> randomBytes(length, 0);

    int rc = SecRandomCopyBytes(kSecRandomDefault, randomBytes.size(), &(randomBytes[0]));
    if (rc != 0) {
        std::cout << "Failed: " << rc << std::endl;
        return 1;
    }

    for (int i = 0; i < randomBytes.size(); ++i) {
        std::cout << std::hex << +randomBytes[i] << " ";
    }
    std::cout << std::endl;

    return 0;
}
Rob Napier
  • 286,113
  • 34
  • 456
  • 610
7

One way to get cryptographically secure random numbers on any "C" based language including Swift is the "C" arc4random functions.

For random number integers (u_int32_t) use arc4random() and arc4random_uniform().

For a range of random bytes use the arc4random_buf() function fills the buffer of length nbytes with ARC4-derived random data.

RC4 is a part of arc4random, the key is the continual seeding:

The arc4random() function provides a high quality 32-bit pseudo-random number very quickly. arc4random() seeds itself on a regular basis from the kernel strong random number subsystem described in random(4).

The arc4random source code is available. Note that it is seeded by (stir) partially by reading from /dev/urandom. Care is taken to avoid well known RC4 weaknesses. Additionally the time is included when initializing the state making it impossible to regenerate the same random sequence twice.

Note: While the docs state that /dev/random blocks on lack of entropy this may not be true on OS X and it may be more like /dev/urandom.

zaph
  • 111,848
  • 21
  • 189
  • 228