swift 中的 phpass 哈希类似功能
phpass hash similar functionality in swift
我的 wordpress 后端正在使用 phpass 散列算法并给我 phpass 使用网络服务。在 ios 中以 swift 结束我试图在 swift 中生成相同的 phpass 散列。以下是 swift 和 php 中的代码。两者都有相同的输入但输出不同。所以问题是我怎样才能得到相同的输出。我错过了什么吗?
Php代码:
<?php
function phpassHash($password, $salt,$iterations){
$hash = hash('md5', $salt.$password, TRUE);
for($i = 0; $i < $iterations; $i++){
$hash = hash('md5', $hash.$password, TRUE);
}
return $hash;
}
$result = phpassHash("a_test_password","MsdvACyA", 8192);
echo bin2hex($result);
?>
Swift代码:
func md5(string: String) -> String {
var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
if let data = string.dataUsingEncoding(NSUTF8StringEncoding) {
CC_MD5(data.bytes, CC_LONG(data.length), &digest)
}
var digestHex = ""
for index in 0..<Int(CC_MD5_DIGEST_LENGTH) {
digestHex += String(format: "%02x", digest[index])
}
return digestHex
}
func phpassHash(password: String, salt: String, iterations: Int) -> String {
var hash = md5(salt+password)
for _ in 0..<iterations {
hash = md5(hash+password)
}
return hash;
}
您太急于在 md5
函数中将字节数组转换为 String
。例如,这会将整数 0x47
的含义更改为字符串 47
。你第一次调用 md5()
returns 正确的散列,但如果你再次 md5()
,它会出错,因为它现在是一个字符串而不是 [=28= 中的字节数组].请注意,在 PHP 中,您在最后一步调用了 bin2hex
。
由于 CommonCrypt 中的 CC_MD5
函数喜欢处理字节数组,因此如有必要,请将所有内容都保留为字节和 writer wrapper。
首先,让我们定义一些辅助函数:
extension String {
// Return the bytes that make up the string according to UTF-8 encoding
var bytes: [UInt8] {
get {
return self.cStringUsingEncoding(NSUTF8StringEncoding)!
.dropLast() // C strings are null-terminated so we need to drop the last byte
.map { UInt8(bitPattern: [=10=]) }
}
}
}
// Convert an array of bytes to a hex string
func toHexString(bytes: [UInt8]) -> String {
return bytes.map { String(format: "%02x", [=10=]) }.joinWithSeparator("")
}
现在您可以编写哈希函数了:
// Allow you to quickly hash a string. We don't really use it here
func md5(string: String) -> [UInt8] {
return md5(string.bytes)
}
func md5(bytes: [UInt8]) -> [UInt8] {
var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
CC_MD5(bytes, CC_LONG(bytes.count), &digest)
return digest
}
func phpassHash(password: String, salt: String, iterations: Int) -> [UInt8] {
let passwordBytes = password.bytes
let saltBytes = salt.bytes
var hash = md5(saltBytes + passwordBytes)
for _ in 0..<iterations {
hash = md5(hash + passwordBytes)
}
return hash
}
let password = "a_test_password"
let salt = "MsdvACyA"
let iterations = 8192
let assHash = phpassHash(password, salt: salt, iterations: iterations)
print(toHexString(assHash)) // 42a89278a28860f223a10fdb43b5d4b2
我的 wordpress 后端正在使用 phpass 散列算法并给我 phpass 使用网络服务。在 ios 中以 swift 结束我试图在 swift 中生成相同的 phpass 散列。以下是 swift 和 php 中的代码。两者都有相同的输入但输出不同。所以问题是我怎样才能得到相同的输出。我错过了什么吗?
Php代码:
<?php
function phpassHash($password, $salt,$iterations){
$hash = hash('md5', $salt.$password, TRUE);
for($i = 0; $i < $iterations; $i++){
$hash = hash('md5', $hash.$password, TRUE);
}
return $hash;
}
$result = phpassHash("a_test_password","MsdvACyA", 8192);
echo bin2hex($result);
?>
Swift代码:
func md5(string: String) -> String {
var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
if let data = string.dataUsingEncoding(NSUTF8StringEncoding) {
CC_MD5(data.bytes, CC_LONG(data.length), &digest)
}
var digestHex = ""
for index in 0..<Int(CC_MD5_DIGEST_LENGTH) {
digestHex += String(format: "%02x", digest[index])
}
return digestHex
}
func phpassHash(password: String, salt: String, iterations: Int) -> String {
var hash = md5(salt+password)
for _ in 0..<iterations {
hash = md5(hash+password)
}
return hash;
}
您太急于在 md5
函数中将字节数组转换为 String
。例如,这会将整数 0x47
的含义更改为字符串 47
。你第一次调用 md5()
returns 正确的散列,但如果你再次 md5()
,它会出错,因为它现在是一个字符串而不是 [=28= 中的字节数组].请注意,在 PHP 中,您在最后一步调用了 bin2hex
。
由于 CommonCrypt 中的 CC_MD5
函数喜欢处理字节数组,因此如有必要,请将所有内容都保留为字节和 writer wrapper。
首先,让我们定义一些辅助函数:
extension String {
// Return the bytes that make up the string according to UTF-8 encoding
var bytes: [UInt8] {
get {
return self.cStringUsingEncoding(NSUTF8StringEncoding)!
.dropLast() // C strings are null-terminated so we need to drop the last byte
.map { UInt8(bitPattern: [=10=]) }
}
}
}
// Convert an array of bytes to a hex string
func toHexString(bytes: [UInt8]) -> String {
return bytes.map { String(format: "%02x", [=10=]) }.joinWithSeparator("")
}
现在您可以编写哈希函数了:
// Allow you to quickly hash a string. We don't really use it here
func md5(string: String) -> [UInt8] {
return md5(string.bytes)
}
func md5(bytes: [UInt8]) -> [UInt8] {
var digest = [UInt8](count: Int(CC_MD5_DIGEST_LENGTH), repeatedValue: 0)
CC_MD5(bytes, CC_LONG(bytes.count), &digest)
return digest
}
func phpassHash(password: String, salt: String, iterations: Int) -> [UInt8] {
let passwordBytes = password.bytes
let saltBytes = salt.bytes
var hash = md5(saltBytes + passwordBytes)
for _ in 0..<iterations {
hash = md5(hash + passwordBytes)
}
return hash
}
let password = "a_test_password"
let salt = "MsdvACyA"
let iterations = 8192
let assHash = phpassHash(password, salt: salt, iterations: iterations)
print(toHexString(assHash)) // 42a89278a28860f223a10fdb43b5d4b2