我正在开发一个需要使用现有Symfony安装的API。 API使用Perfect。用Swift编写。
我已经确定Symfony使用FOS用户包和MessageDigest编码器(也就是SHA 512哈希)。
查看源代码,我可以看到FOS生成一个随机字节盐。 我可以看到这个salt值(32个字符长的十六进制字符串)存储在db。的用户表中。
然后我开始实现我在以下链接中看到的编码过程,在Swift中(注意,我包括从db获取的硬编码salt值和匹配的密码)。
MessageDigestPasswordEncoder.php
@IBAction func calculate(_ id: AnyObject?) {
let raw = "1234"
let salt = "6bf3brej22cc8g0go04ck44g0co484c"
let salted = "\(raw){\(salt)}"
var digestData = salted.data(using: String.Encoding.utf8)?.sha512()
var digest = digestData!.toHexString()
for _ in 0..<5000 {
digestData = "\(digest)\(salted)".data(using: String.Encoding.utf8)?.sha512()
digest = digestData!.toHexString()
}
let encodedPass = digestData!.base64EncodedString()
NSLog("encodedPass: \(encodedPass)")
}
不幸的是,我得到的结果与存储在DB中的编码字符串不是一个字符串。
我在代码中找不到任何错误,除非FOS没有使用存储在数据库中的完全相同的salt字符串。
我很感激FOS / Symfony用户对我做错了什么的帮助,或者我怎么可能去调试它。
答案 0 :(得分:1)
所以,我通过导入CommonCrypto lib找到了解决方案。 (通过自定义module.modulemap)而不是使用第三方框架进行SHA512散列(我正在使用):
func calculateCommonCrypto() {
let raw = "1234"
let salt = "6bf3brej22cc8g0go04ck44g0co484c"
let salted = "\(raw){\(salt)}"
let saltedData = NSData(data: salted.data(using: String.Encoding.utf8)!)
var digest = [UInt8].init(repeating: 0, count: Int(CC_SHA512_DIGEST_LENGTH))
CC_SHA512(saltedData.bytes, CC_LONG(saltedData.length), &digest)
var combinedData = NSMutableData()
let saltedBytes = NSData(data: salted.data(using: String.Encoding.utf8)!)
for _ in 1 ..< 5000 {
combinedData.append(&digest, length: digest.count)
combinedData.append(saltedBytes.bytes, length: saltedBytes.length)
CC_SHA512(combinedData.bytes, CC_LONG(combinedData.length), &digest)
combinedData = NSMutableData()
}
let finalData = Data(bytes: digest)
let encodedStr = finalData.base64EncodedString()
}