ios - iOS上是否有加密安全的替代arc4random的替代方案?

标签 ios security random

我想使用像 arc4random_uniform() 这样的PRNG;但是,Wikipedia seems to think that rc4 is insecure。我没有足够的钱来确认自己,但是安全是我用例的要求。

最佳答案

arc4random_uniform被记录为“加密伪随机数生成器”,因此可以满足此目的。不要将RC4的安全性问题与arc4random混淆。有关更多详细信息,请参见Zaph's answer。 (我之前对此进行了研究,我记得arc4random与其他方法一样安全,但是我对Zaph的信任比对我自己的内存的信任还要多。)

就是说,如果您很紧张,则要使用的工具是SecRandomCopyBytes(或者,您可以从/dev/random读取,这正是SecRandomCopyBytes的功能)。

SecRandomCopyBytes获取随机值比它应该的难,但也不太难。这是您以一种非常通用的方式进行操作的方法(快速3):

extension Integer {
    static func makeRandom() -> Self {
        var result: Self = 0
        withUnsafeMutablePointer(to: &result) { resultPtr in
            resultPtr.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout<Self>.size) { bytePtr in
                SecRandomCopyBytes(nil, MemoryLayout<Self>.size, bytePtr)
            }
        }
        return result
    }
}

这适用于任何Integer。基本上,我们将一堆随机字节解释为Integer。 (顺便说一句,这种方法在浮点值上效果不佳。可以做到这一点,但是您会发现并非所有位模式实际上都是浮点中的“数字”。因此稍微复杂一些。)

现在,您希望在不引入偏差的情况下获得这些值。只是说x % limit会创建modulo bias。不要那样做正确的方法是执行arc4random_uniform要做的事情。它是open source,所以您可以看看它。在Swift中应用相同的方法如下所示:
extension Int {
    static func makeRandom(betweenZeroAnd limit: Int) -> Int {
        assert(limit > 0)

        // Convert our range from [0, Int.max) to [Int.max % limit, Int.max)
        // This way, when we later % limit, there will be no bias
        let minValue = Int.max % limit

        var value = 0

        // Keep guessing until we're in the range.
        // In theory this could loop forever. It won't. A couple of times at worst
        // (mostly because we'll pick some negatives that we'll throw away)
        repeat {
            value = makeRandom()
        } while value < minValue

        return value % limit
    }
}

我们无法在Integer上构建它,因为.max上没有Integer属性。

在Swift 4中,所有这些都用FixedWidthInteger清理了,我们可以使它更通用:
extension FixedWidthInteger {
    static func makeRandom() -> Self {
        var result: Self = 0
        withUnsafeMutablePointer(to: &result) { resultPtr in
            resultPtr.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout<Self>.size) { bytePtr in
                SecRandomCopyBytes(nil, MemoryLayout<Self>.size, bytePtr)
            }
        }
        return result
    }

    static func makeRandom(betweenZeroAnd limit: Self) -> Self {
        assert(limit > 0)

        // Convert our range from [0, Int.max) to [Int.max % limit, Int.max)
        // This way, when we later % limit, there will be no bias
        let minValue = Self.max % limit

        var value: Self = 0

        // Keep guessing until we're in the range.
        // In theory this could loop forever. It won't. A couple of times at worst
        // (mostly because we'll pick some negatives that we'll throw away)
        repeat {
            value = makeRandom()
        } while value < minValue

        return value % limit
    }
}

关于ios - iOS上是否有加密安全的替代arc4random的替代方案?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44751523/

相关文章:

ios - 启动屏幕在 iPad 设备中不起作用

objective-c - UITableViewController 滚动僵尸

security - 不需要 UserProvider 的自定义身份验证

security - 使用 WebAuthN 可以拒绝某些类型的身份验证方法 FIDO2)

.net - 从源列表创建新的随机列表

c# - 随机连接图生成器

ios - 缩小我的世界 : Joints and their positions are not adjusted

iphone - 使用quartz-2d时如何实现触摸

java - 保护属性文件?

java - 获取一个重复操作的按钮