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.
As I understand the iOS security model, there is no way to access /dev/random
directly. Is that correct?
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...
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
.
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With