2016-08-20 5 views
2

내 wordpress 백엔드가 phpass 해시 알고리즘을 사용하고 웹 서비스를 사용하여 phpass를 제공합니다. 신속한 ios end에서 신속한 동일한 phpass 해시를 생성하려고합니다. 아래 코드는 swift와 php입니다. 둘 다 동일한 입력을 가지고 있지만 출력은 다릅니다. 그래서 질문은 동일한 출력을 얻는 방법입니다. 내가 놓친 게 있니?신속한 phpass 해시 유사 기능

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); 
?> 

스위프트 코드 :

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

당신은 당신의 md5 기능에 String으로 바이트 배열을 변환 너무 열망했다. 예를 들어 정수 0x47의 의미를 47 문자열로 변경합니다. md5()에 대한 첫 번째 호출은 올바른 해시를 반환하지만 다시 md5() 인 경우 PHP에서와 같이 바이트 배열 대신 문자열이되므로 잘못 처리됩니다. PHP에서는 마지막 단계에서 bin2hex으로 호출합니다.

CommonCrypt의 CC_MD5 함수는 바이트 배열을 처리하기 때문에 모든 항목을 바이트로 유지하고 필요한 경우 작성자 래퍼로 유지하십시오.

첫째, 일부 도우미 함수를 정의 할 수 있습니다 :

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

감사합니다. 나는 맥주 몇 개를 코딩 할 수있어서 놀랍다. –