Ios 为加密和解密生成和保存密码的策略

Ios 为加密和解密生成和保存密码的策略,ios,cryptography,aes,keychain,rncryptor,Ios,Cryptography,Aes,Keychain,Rncryptor,我使用RNEncryptor和RNDecryptor类进行加密和解密,如下所示: NSData *encryptedData = [RNEncryptor encryptData:input withSettings:kRNCryptorAES256Settings password:thePassword

我使用
RNEncryptor
RNDecryptor
类进行加密和解密,如下所示:

NSData *encryptedData = [RNEncryptor encryptData:input
                                    withSettings:kRNCryptorAES256Settings
                                        password:thePassword
                                           error:nil];

NSData *output = [RNDecryptor decryptData:encryptedData
                             withSettings:kRNCryptorAES256Settings
                                 password:thePassword
                                    error:nil];
NSData *thePasswordData = [RNCryptor randomDataOfLength:32];
NSString *thePassword = [aesPasswordData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
我第一次必须加密应用程序中的数据时,我使用
RNCryptor
类生成密码,如下所示:

NSData *encryptedData = [RNEncryptor encryptData:input
                                    withSettings:kRNCryptorAES256Settings
                                        password:thePassword
                                           error:nil];

NSData *output = [RNDecryptor decryptData:encryptedData
                             withSettings:kRNCryptorAES256Settings
                                 password:thePassword
                                    error:nil];
NSData *thePasswordData = [RNCryptor randomDataOfLength:32];
NSString *thePassword = [aesPasswordData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
我将生成的密码保存在应用程序的密钥链中,并将其用于所有后续的加密和解密

这是一个很好的加密/解密策略还是有人能看到其中的任何缺陷?我应该生成一个AES密钥并将其存储在密钥链中,然后使用它而不是密码吗


编辑:根据Rob Napier的回答,我将上述生成密码的方式从使用
NSProcessInfo
类更改为使用
RNCryptor
类。除此之外,我仍然想知道使用密码而不是AES密钥的策略是否正确和安全。

这不是选择密码的好方法
globallyUniqueString
在许多方面都是可以预测的。您最好使用
RNCryptor.randomDataOfLength
之类的方法生成所需长度的blob(理想情况下是32字节),然后对其进行base-64编码以获得密码


使用
randomDataOfLength
生成密钥实际上不会更安全,但速度会更快(取决于设备,如果这对您很重要的话,会缩短10毫秒)。一般来说,我建议使用密码界面,除非您遇到特殊问题,其中密钥特别有用。钥匙只是有点难以正确使用。

这不是选择密码的好方法
globallyUniqueString
在许多方面都是可以预测的。您最好使用
RNCryptor.randomDataOfLength
之类的方法生成所需长度的blob(理想情况下是32字节),然后对其进行base-64编码以获得密码


使用
randomDataOfLength
生成密钥实际上不会更安全,但速度会更快(取决于设备,如果这对您很重要的话,会缩短10毫秒)。一般来说,我建议使用密码界面,除非您遇到特殊问题,其中密钥特别有用。密钥的正确使用有点困难。

这些LIB使用的实际加密密钥是从密码中派生出来的,如果您使用密码的话,但是,IIRC是salt,因此它本质上并不不安全

有人担心这些库提供的理论安全级别,(请参阅),但您必须对此做出判断。需要记住的是,RNCryptor是一组库(可能在不同的实现中发布了攻击向量)和一致的格式,如果您希望跨平台移动加密数据,这非常有用


就我个人而言,我更愿意为每次加密使用唯一的随机AES密钥,并将该密钥存储在密钥链中,并使用RSA加密

这些lib使用的实际加密密钥是从密码中派生出来的,如果您使用密码的话,但是,IIRC是salt,因此它本质上并不不安全

有人担心这些库提供的理论安全级别,(请参阅),但您必须对此做出判断。需要记住的是,RNCryptor是一组库(可能在不同的实现中发布了攻击向量)和一致的格式,如果您希望跨平台移动加密数据,这非常有用


就我个人而言,我更愿意为每次加密使用唯一的随机AES密钥,并将该密钥存储在密钥链中,并使用RSA加密

globallyUniqueString
nsuid
是可以的,但是没有什么比向用户索要一个好的密码更好的了。谢谢您的回复。我需要让这一切无缝地发生。。。没有用户交互。因此,我必须生成一个随机字符串。@Wain但是如何信任用户提供一个好的密码呢?“Passw0rd”将通过大多数测试,8个字符,至少一个大写字母和一个数字,但远不是一个好的密码。@zaph用户输入的密码可能很弱,但没有将密码存储在设备上会使加密更难进行undo@Wain是的,但问题不是关于用户生成的密码。我还发现了一个假设的问题,即用户可以提供一个“良好的密码”。如果要接受用户密码,则必须处理其他事项,例如限制尝试的速率。存在大量用户界面问题,要求用户重复输入密码,这可能是不可接受的。该评论最好作为一个带有适当警告的答案。
globallyUniqueString
nsuid
是可以的,但没有什么比向用户索要一个好密码更好的了。谢谢您的回复。我需要让这一切无缝地发生。。。没有用户交互。因此,我必须生成一个随机字符串。@Wain但是如何信任用户提供一个好的密码呢?“Passw0rd”将通过大多数测试,8个字符,至少一个大写字母和一个数字,但远不是一个好的密码。@zaph用户输入的密码可能很弱,但没有将密码存储在设备上会使加密更难进行undo@Wain是的,但问题不是关于用户生成的密码。我还发现了一个假设的问题,即用户可以提供一个“良好的密码”。如果要接受用户密码,则必须处理其他事项,例如限制尝试的速率。存在大量用户界面问题,要求用户重复输入密码,这可能是不可接受的。如果你能给出一个完整的答案,并附上适当的警告,那就更好了。你好,罗布,谢谢你的回复。很高兴!:-)我没有意识到,
RPCryptor
库有一个我