Как создать правильный параметр Signature для предварительно подписанного URL-адреса S3 в Swift - PullRequest
0 голосов
/ 10 марта 2020

У меня есть следующий код песочницы в Swift, который пытается создать правильный URL-адрес Amazon S3 с подходящей подписью для защищенного контента, и я пытаюсь «преобразовать» его из моего рабочего PHP кода. Однако я получаю страшную

Рассчитанная нами подпись запроса не соответствует предоставленной вами подписи. Проверьте ваш ключ и метод подписи.

сообщение при попытке URL. Одна вещь, которую я заметил, состоит в том, что подпись, генерируемая из PHP, имеет длину 30 символов, но та, которая генерируется в Swift, намного длиннее. Вот два примера:

PHP: Signature=jCpLoXYohCo%2BIkOS%2BjaObehyIng%3D

Swift: Signature=YmRhYWI2ZjkwY2VjZmY4YTNlZDhhYWI4ZTA2ZGI1ZDZjYjI3ZmEwZg==

Поскольку мне ничего не нужно из Amazon SDK, я решил не включать его в этот проект , В PHP функция, которая успешно генерировала правильную подпись в течение многих лет, выглядит так:

 {
     return base64_encode(extension_loaded('hash') ?
     hash_hmac('sha1', $string, self::$__secretKey, true) : pack('H*', sha1(
     (str_pad(self::$__secretKey, 64, chr(0x00)) ^ (str_repeat(chr(0x5c), 64))) .
     pack('H*', sha1((str_pad(self::$__secretKey, 64, chr(0x00)) ^
     (str_repeat(chr(0x36), 64))) . $string)))));
 }

Я доказал, что extension_loaded ('ha sh') возвращает true в приведенном выше коде.

В Swift я попробовал некоторый код, который я нашел здесь, в Переполнении стека, который генерирует эту более длинную подпись. Генерируемый ha sh имеет длину 40 символов, который я затем пытаюсь кодировать в Base64:

enum CryptoAlgorithm {
    case MD5, SHA1, SHA224, SHA256, SHA384, SHA512

    var HMACAlgorithm: CCHmacAlgorithm {
        var result: Int = 0
        switch self {
        case .MD5:      result = kCCHmacAlgMD5
        case .SHA1:     result = kCCHmacAlgSHA1
        case .SHA224:   result = kCCHmacAlgSHA224
        case .SHA256:   result = kCCHmacAlgSHA256
        case .SHA384:   result = kCCHmacAlgSHA384
        case .SHA512:   result = kCCHmacAlgSHA512
        }
        return CCHmacAlgorithm(result)
    }

    var digestLength: Int {
        var result: Int32 = 0
        switch self {
        case .MD5:      result = CC_MD5_DIGEST_LENGTH
        case .SHA1:     result = CC_SHA1_DIGEST_LENGTH
        case .SHA224:   result = CC_SHA224_DIGEST_LENGTH
        case .SHA256:   result = CC_SHA256_DIGEST_LENGTH
        case .SHA384:   result = CC_SHA384_DIGEST_LENGTH
        case .SHA512:   result = CC_SHA512_DIGEST_LENGTH
        }
        return Int(result)
    }
}

extension String {

    func hmac(algorithm: CryptoAlgorithm, key: String) -> String {
        let str = self.cString(using: String.Encoding.utf8)
        let strLen = Int(self.lengthOfBytes(using: String.Encoding.utf8))
        let digestLen = algorithm.digestLength
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
        let keyStr = key.cString(using: String.Encoding.utf8)
        let keyLen = Int(key.lengthOfBytes(using: String.Encoding.utf8))

        CCHmac(algorithm.HMACAlgorithm, keyStr!, keyLen, str!, strLen, result)

        let digest = stringFromResult(result: result, length: digestLen)

        result.deallocate()
        return digest.toBase64()
        }

        private func stringFromResult(result: UnsafeMutablePointer<CUnsignedChar>, length: Int) -> String {
            var hash = NSMutableString()
            for i in 0..<length {
                hash.appendFormat("%02x", result[i])
            }
            return String(hash)
        }
}

extension String {
        func fromBase64() -> String? {
                guard let data = Data(base64Encoded: self) else {
                        return nil
                }
                return String(data: data, encoding: .utf8)
        }
        func toBase64() -> String {
            return Data(self.utf8).base64EncodedString()
        }
}

Кто-нибудь может помочь мне понять, почему это не генерирует правильную подпись? Если версия PHP генерирует 30-символьную подпись, мое первое предположение состоит в том, что версия Swift должна быть такой же, но я не обязательно приклеен к этому как факт.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...