如何使用Swift将字符串解密为base64中的sha1? [英] How to crypt string to sha1 in base64 with Swift?

查看:133
本文介绍了如何使用Swift将字符串解密为base64中的sha1?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想加密privateKey&使用Swift在base64中使用sha1的publicKey,但是输出不是我在Codecademy中尝试过的PHP urlencode base64_encode中看到的输出:"

I want to crypt privateKey & publicKey to sha1 in base64 with Swift, but the output is not the one I see in PHP urlencode base64_encode which I tried in Codecademy:"https://www.codecademy.com/courses/web-beginner-en-StaFQ/0/3?curriculum_id=5124ef4c78d510dd89003eb8".

请在Swift和Codecademy中查看以下代码:

Pls see the following codes in Swift and Codecademy:

快捷键:

//pls see func dataFromHexadecimalString() details here "http://stackoverflow.com/questions/26501276/convert-string-to-hex-string-in-swift/26502285#26502285" 

extension String {

func dataFromHexadecimalString() -> NSData? {
    let trimmedString = self.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<> ")).stringByReplacingOccurrencesOfString(" ", withString: "")

    var error: NSError?
    let regex = NSRegularExpression(pattern: "^[0-9a-f]*$", options: .CaseInsensitive, error: &error)
    let found = regex?.firstMatchInString(trimmedString, options: nil, range: NSMakeRange(0, count(trimmedString)))
    if found == nil || found?.range.location == NSNotFound || count(trimmedString) % 2 != 0 {
        return nil
    }

    let data = NSMutableData(capacity: count(trimmedString) / 2)

    for var index = trimmedString.startIndex; index < trimmedString.endIndex; index = index.successor().successor() {
        let byteString = trimmedString.substringWithRange(Range<String.Index>(start: index, end: index.successor().successor()))
        let num = UInt8(byteString.withCString { strtoul($0, nil, 16) })
        data?.appendBytes([num] as [UInt8], length: 1)
    }

    return data
  }
}

func URLEcodekey() -> String {
    let appid="a1b2c34d5e"
    let privateKey="ef7d6s0d"
    let areaid="101020900"
    let time="201507191254"
    let publicKey="http://open.weather.com.cn/data/?areaid=\(areaid)&type=forecast_v&date=\(time)&appid=\(appid)"

    let cPrivateKey=privateKey.dataUsingEncoding(NSUTF8StringEncoding)!
    let cPublicKey=publicKey.dataUsingEncoding(NSUTF8StringEncoding)!
    var cHMAC = [CUnsignedChar](count: Int(CC_SHA1_DIGEST_LENGTH), repeatedValue: 0)
    CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1), cPublicKey.bytes, Int(cPublicKey.length), cPrivateKey.bytes, Int(cPrivateKey.length), &cHMAC)

    let hexKeyString=NSMutableString(capacity: Int(CC_SHA1_DIGEST_LENGTH))
    for byte in cHMAC{
        hexKeyString.appendFormat("%02hhx", byte)
    }
    println("hexKeyString:\(encryptedKey)")

    let binaryData = hexKeyString.dataFromHexadecimalString()
    let base64String = binaryData?.base64EncodedStringWithOptions(nil)
    println("base64String:\(base64String)")

    var urlEncodeKey=base64String!.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!
    println("urlEncodeKey:\(urlEncodeKey)")
    return urlEncodeMessage
}

输出为:

hexKeyString:d4433d42b1505c00a4aa80205171d0d04754d254

base64String:1EM9QrFQXACkqoAgUXHQ0EdU0lQ =

urlEncodeKey:1EM9QrFQXACkqoAgUXHQ0EdU0lQ =

Codecademy中的PHP:

echo urlencode(base64_encode(hash_hmac('sha1', " http://open.weather.com.cn/data/?areaid=101020900&type=forecast_v&date=201507191254&appid=a1b2c34d5e", "ef7d6s0d", TRUE)));

输出为:

A5O59Y%2BFbGjhVwaI9JNB7DkcX%2F4%3D////输出非常像API中的示例,我认为可能是正确的示例.

A5O59Y%2BFbGjhVwaI9JNB7DkcX%2F4%3D // the output is much like the example in API, which I think maybe the right one.

因此,我该如何为我的privateKey&接收正确的 urlEncodeKey 像PHP中的publicKey?

So, how can I receive the right urlEncodeKey for my privateKey & publicKey like in PHP?

非常感谢您!

推荐答案

您应该阅读有关加密和哈希的更多信息.在您的情况下,没有公钥,私钥,... SHA代表安全哈希算法,而您想要获取的是基于 Hash的身份验证代码.查看有关 HMAC SHA-1 公共密钥,...我强烈建议您阅读更多有关它的信息,否则,如果您误解了它,可能会造成更大的损失.

You should read more about cryptography and hashing. In your case, there's no public key, private key, ... SHA stands for Secure hash algorithm and what you're trying to get is Hash based authentication code. Check Wikipedia articles about HMAC, SHA-1, Public key, ... I strongly recommend to read more about it otherwise you can create more damage if you misunderstand it.

回到您的问题.它是一个字符:

Back to your problem. It's in one character:

  • 快速代码-让publicKey ="http://open.weather.com.cn ...
  • PHP代码- hash_hmac('sha1',"http://open.weather.com.cn ...

您看到问题出在哪里吗?在您的PHP代码中, http 前面有一个空格 字符.此字符不在您的Swift代码中.

Do you see where the problem is? In your PHP code, there's one space character just before http. This character is not in your Swift code.

老实说,我没有检查您的整个代码,因为我不知道您为什么要尝试从十六进制字符串等转换它.仅使用某些部分并为您重新编写.这是工作示例:

Honestly, I didn't check your whole code, because I don't know why you're trying to convert it from hexadecimal string, etc. Used some parts only and rewrote it from scratch for you. Here's working example:

func URLEncodedKey() -> String? {
  let appid = "a1b2c34d5e"
  let time = "201507191254"
  let areaid = "101020900"

  let key = "ef7d6s0d"
  let string = " http://open.weather.com.cn/data/?areaid=\(areaid)&type=forecast_v&date=\(time)&appid=\(appid)"
  //            ^  <- in your PHP example, there's space

  guard let keyData = key.dataUsingEncoding(NSUTF8StringEncoding),
    stringData = string.dataUsingEncoding(NSUTF8StringEncoding),
    outputData = NSMutableData(length: Int(CC_SHA1_DIGEST_LENGTH)) else {
    return nil
  }
  outputData.length = Int(CC_SHA1_DIGEST_LENGTH)

  CCHmac(CCHmacAlgorithm(kCCHmacAlgSHA1),
    keyData.bytes, keyData.length,
    stringData.bytes, stringData.length,
    outputData.mutableBytes)

  return outputData
    .base64EncodedStringWithOptions([])
    .stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet())
}

返回值为:

`Optional("A5O59Y+FbGjhVwaI9JNB7DkcX/4=")`

解码PHP输出时会得到什么.

Which is what you get when you decode your PHP output.

只需将 URLQueryAllowedCharacterSet 替换为以下任何字符集:

Just replace URLQueryAllowedCharacterSet with any of the following character sets:

class func URLUserAllowedCharacterSet() -> NSCharacterSet    
class func URLPasswordAllowedCharacterSet() -> NSCharacterSet
class func URLHostAllowedCharacterSet() -> NSCharacterSet    
class func URLPathAllowedCharacterSet() -> NSCharacterSet
class func URLQueryAllowedCharacterSet() -> NSCharacterSet
class func URLFragmentAllowedCharacterSet() -> NSCharacterSet

取决于您的用例.IOW您要在URL的哪一部分中使用它.

Depends on your use case. IOW in which part of the URL your would like to use it.

这篇关于如何使用Swift将字符串解密为base64中的sha1?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆