2

我的 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;
    }
4

1 回答 1

1

您太急于将字节数组转换String为您的md5函数。例如,这会将整数的含义更改为0x47字符串47。您的第一次调用md5()返回正确的哈希值,但如果您md5()再次调用,它将出错,因为它现在是一个字符串,而不是 PHP 中的字节数组。请注意,在 PHP 中,您bin2hex在最后一步调用。

由于CC_MD5CommonCrypt 中的函数喜欢处理字节数组,因此如有必要,请将所有内容保存为字节和编写器包装器。

首先,让我们定义一些辅助函数:

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: $0) }
        }
    }
}

// Convert an array of bytes to a hex string
func toHexString(bytes: [UInt8]) -> String {
    return bytes.map { String(format: "%02x", $0) }.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
于 2016-08-20T03:56:46.170 回答