我必须在钥匙串中保存一个字符串(密码),但原始字符串是
那么,字符串必须存在于app中的某个位置(硬编码?)。
我非常确定您无法为安装后的应用程序准备好钥匙串的数据,就像您可以在应用程序包中添加一个plist,以便可以立即加载它应用程序正在运行(即使它是第一次启动)。
我读过Data Protection:它允许使用敏感数据的应用程序利用某些设备上的加密功能。这是要走的路吗?那就是:我将数据存储到文本文件中,然后保护文件,然后从文件中检索数据,然后将其保存到钥匙串中?
任何提示都表示赞赏。
答案 0 :(得分:2)
如果无法从外部提供字符串(用户输入,服务器),则开发人员必须以某种形式将其放入应用程序包中。它可以是硬编码的,存储在文件中,也可以由函数生成。这意味着应用程序具有获取/生成此类字符串所需的所有信息。 因此,它无法像加密一样保护信息。
iOS应用程序受Apple的DRM保护,因此如果有人将您的二进制文件复制到Mac并开始反汇编,您会感到安全。但是,如果黑客有一个越狱设备,不幸的是,有一些工具可以将你的应用程序二进制文件从内存转储到磁盘。
所以它归结为混淆。您可以编写一个动态生成字符串的函数(例如,对硬编码字节数组执行一系列操作,然后将其转换为字符串)。这将使你的字符串更难被黑客拦截。
答案 1 :(得分:2)
这个问题的变种已经在很多时候讨论过了,不幸的是你没有找到一个完美的答案,因为不是。
基本上,您希望在应用中发送身份验证凭据,即将秘密捆绑到其中。这意味着无论您做什么,攻击者都有可能通过逆向工程检索它。即使您使用技术上足够安全的硬算法对其进行加密,在某些时候您的应用程序也会对其进行解密,并且由于应用程序可能掌握在攻击者手中,因此他们将能够嗅探秘密。
这意味着最终你只能通过基本上混淆你处理秘密的方式("使嗅探变得复杂")来试图让它们变得困难。捆绑一个加密的文件,解密然后打包到钥匙串对我来说似乎不是一个坏主意,但请记住,对于有人看着你的应用程序,特别是在越狱的iPhone上,这个消失的文件可以是一个好的第一个提示。此外,删除它并没有什么帮助,因为重新安装很容易恢复它。
另一个想法可能是使用On-Demand Resources来分发您的秘密,这也可能使您更容易用更新版本替换它,以防您的秘密被泄露。我自己并不熟悉按需资源,所以我无法告诉你它们对实际撤销事物的适用程度。
这都假定您无法根据用户输入实现身份验证机制。这样攻击者只能窃取自己的密码(假设他们不会窃取别人的iPhone ......)而不是整个应用程序的重要部分(可能会影响所有用户)。
我的书签中的其他SO答案可能会对您有所帮助:
好的,在重新阅读了问题的最后一条评论之后,这是一个具体的建议。如果你已经拥有用户身份验证(你说他们已经登录了),我根本不知道为什么你需要这个第二个密码/令牌,但是你现在就去了:
令牌的潜在缺点是它是静态的而不是用户限制的,或者它是否没有这个生存时间限制。您必须在服务器上以巧妙的方式生成此内容,并明确记下哪个用户使用哪个令牌。这样,您就可以查明安全漏洞并做出相应的反应(而不是通过使您的唯一令牌失效来突然关闭所有用户的服务器)。不过,我不知道为什么你需要这个。
关于中间人攻击:一个令牌,无论是app-bundled(这本身就是一种风险)还是服务器生成的,它本身并不能防止这种情况发生。我不知道你的老板会在这里瞄准什么,但也许我错过了一些信息。一般来说,https已经保护你免受这种情况(好吧,通常只有服务器经过身份验证,但如果你已经有了用户名和密码系统,那么对于客户端来说也应该没问题)。总的来说,它实际上是一个重点。对我而言,这听起来越来越像原始问题中的某些东西,只是对现有基础设施和/或老板诱导的"的误解。问题......:)
答案 2 :(得分:2)
主要关注的是复述或访问令牌,它可以作为加密数据保存在钥匙串中,但每当我们发送请求时,它都会被解密。它可以在越狱设备上进行跟踪。但是使用更多不可知算法加密请求数据会增加API响应时间。但是,在服务器端定义基于用户的权限是最好的方法,因为在最坏的情况下,只能跟踪1个用户的数据。
SSL Pinning - 使用质询响应身份验证,我们可以防止app在中间攻击中受到攻击。是的,可以绕过ssl pinning,但这并不容易。只能在越狱设备上使用。
将到期时间定义为几秒可能是防止用户数据的另一种方法。在授予权限之前,识别请求源也非常重要。 因此,通过多种方式的合作,我们可以尝试建立更好的系统。
修改强>
通常我们使用1个密钥作为令牌和放大器加密数据。一旦该密钥被泄露,它就可以被解密。 非对称加密使用公共和加密增加了1层加密。私钥。 https://developer.apple.com/library/content/documentation/Security/Conceptual/Security_Overview/CryptographicServices/CryptographicServices.html#//apple_ref/doc/uid/TP30000976-CH3-SW12
这是另一个例子,其中随机盐用于令牌以编码数据https://en.wikipedia.org/wiki/PBKDF2
答案 3 :(得分:2)
您可以做的是在调用API时使用AES 256加密对参数进行加密,然后服务器解密参数并再次发送加密响应。如果您的服务器和应用程序共享相同的密钥,您可以解密并读取响应用于加密和解密。
我的应用程序中有类似功能,因此我的Util类使用以下代码加密和解密请求和响应,
class func encrypt (stringToEncrypt: String) -> String {
let messageData = stringToEncrypt.data(using: .utf8)
let encryptedBytes = try! AES(key: "abcdefghijklmnopqrstuvwxyz012345", iv: "abcdefghijklmost").encrypt([UInt8](messageData!))
return encryptedBytes.toBase64()!
}
class func decrypt ( message: String) -> String {
let messageData = Data(base64Encoded: message, options: .ignoreUnknownCharacters)
let decryptedBytes: [UInt8] = try! AES(key: "abcdefghijklmnopqrstuvwxyz012345", iv: "abcdefghijklmost").decrypt([UInt8](messageData!))
let unencryptedString = String(bytes: decryptedBytes, encoding: .utf8)
return unencryptedString!
}
同样,这只是一个建议,你也可以用其他方式来做。
答案 4 :(得分:1)
要在Keychain中保存一些字符串值,您可以使用pod库
pod 'SSKeychain'
您可以将字符串保存到钥匙串,如下所示
let appName = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
SSKeychain.setAccessibilityType(kSecAttrAccessibleAlways)
SSKeychain.setPassword(stringToSave, forService: appName, account: "MyAppName")
也可以使用
检索相同内容let appName = NSBundle.mainBundle().infoDictionary!["CFBundleName"] as! String
let stringRetrieved = SSKeychain.passwordForService(appName, account: "MyAppName")
安装上述窗格
后导入这些内容import SystemConfiguration
import SSKeychain
即使应用程序已删除并重新安装,也会保留此项。如果您想要额外的加密,可以使用任何加密算法,这个算法非常有用
答案 5 :(得分:1)
加密技术可能有助于解决需求。以下是我们如何在Diffie–Hellman key exchange
加密技术之上维护密钥的简单阐述。
<强>先决条件:强>
<强>过程:强>
应用程序和后端都应该有一个公共公钥,在这种情况下只需将其作为应用程序名称,如MyApplication。
public key: MyApplication
应使用某些加密过程或逻辑在两端生成私钥。假设将随机数生成为私钥,如下所示。
Suppose App private key is: 10
Suppose Backend private key is: 90
按照某种算法在app和后端生成交换密钥。这里只是结合公钥和私钥,如
App final key: MyApplication + 10
Backend final key: MyApplication + 90
在app和backend之间交换密钥。
App Got key: MyApplication + 90
Backend Got key: MyApplication + 10
使用某种技术(如
)将收到的密钥与自己的密钥进行比较我。通过组合应用私钥和App Got键生成新的App键,如:MyApplication + 90 + 10
II。通过组合Backend私钥和Backend Got键生成新的后端键,如:MyApplication + 10 + 90
要检查两个键是否相同需要遵循逻辑例如这里只需在键中添加最后两个数字结果就像
App owned key: MyApplication + 100
App acquired key: MyApplication + 100
BackEnd owned key: MyApplication + 100
BackEnd acquired key: MyApplication + 100
Hola终于后端和app都有相同的密钥。
取决于需求需求,每个会话维护不同的私钥并将其存储在钥匙串上。或制作一个私钥并将其存储在应用程序端。
注意:此描述仅概述了如何维护密钥,它可能涉及大量逻辑,并且还提供了完全依赖于使用加密和逻辑的其他人分解密钥的规定生成并破坏密钥。
<强>参考文献:强>