2016-08-20 4 views
2

My wordpress backend использует алгоритм хэша phpass и дает мне phpass с помощью веб-службы. В ios end in swift я стараюсь сгенерировать тот же самый хэширование phpass в swift. Ниже приведены коды в swift и php. Оба имеют одинаковый вход, но вывод отличается. Поэтому вопрос в том, как я могу получить такой же результат. Я что-то пропустил?phpass hash аналогичная функциональность в swift

код 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; 
    } 

ответ

1

Вы были слишком нетерпелив, чтобы преобразовать массив байтов в String в вашей md5 функции. В качестве примера это изменяет значение целого числа 0x47 на строку 47. Ваш первый вызов md5() возвращает правильный хеш, но если вы снова нажмете md5(), это пойдет не так, потому что теперь это строка вместо массива байтов, как в PHP. Обратите внимание, что в PHP вы вызываете bin2hex на последнем шаге.

Поскольку функция CC_MD5 в CommonCrypt имеет отношение к массиву байтов, при необходимости сохраняйте все как байты и обертки писателя.

Во-первых, давайте определим некоторые вспомогательные функции:

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("") 
} 

Теперь вы можете написать свой хэш fucntions:

// 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 
+0

очень совершенный код. –

+1

Спасибо. Я удивлен, что смогу закодировать после нескольких сортов пива –

Смежные вопросы