向google.com发送HTTPS请求时,我执行了以下操作:
import Foundation
class LearnNSURLSession: NSObject, NSURLSessionDelegate, NSURLSessionTaskDelegate {
override init() {
super.init()
let mySession = NSURLSession(configuration: NSURLSessionConfiguration.ephemeralSessionConfiguration(), delegate: self, delegateQueue: NSOperationQueue.mainQueue())
let data = mySession.dataTaskWithURL(NSURL(string: "https://www.google.com")!, completionHandler: myHandler)
data.resume()
}
func myHandler(data: NSData!, response: NSURLResponse!, error: NSError!) -> Void {
let s = NSString(data: data, encoding: NSASCIIStringEncoding)
println(s)
}
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
println("ERROR: \(error)")
}
// Handles HTTPS connections
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential!) -> Void) {
println("\nPublic KEY: \(SecTrustCopyPublicKey(challenge.protectionSpace.serverTrust).takeUnretainedValue())")
completionHandler(NSURLSessionAuthChallengeDisposition.PerformDefaultHandling, nil)
}
// Handles redirection
func URLSession(session: NSURLSession, task: NSURLSessionTask, willPerformHTTPRedirection response: NSHTTPURLResponse, newRequest request: NSURLRequest, completionHandler: (NSURLRequest!) -> Void) {
completionHandler(request)
}
当我运行代码时,我注意到URLSession:didReceiveChallenge
被调用两次,我从println("Public KEY:\(SecTrustCopyPublicKey(challenge.protectionSpace.serverTrust).takeUnretainedValue())")
得到以下输出:
Public KEY: <SecKeyRef algorithm id: 1, key type: RSAPublicKey, version: 3, block size: 2048 bits, exponent: {hex: 10001, decimal: 65537}, modulus: 982A37418AF3B46A9C0BDC42520DD4EFE3854B118194B8A199ACE499B8B3FF8F566360E0DCF44659AA2BB07CCAD187FB9238C925B2F1F7864492BF79F99DE9DD8F8CFB6D868C5DCA4146D78BA33182FC4FE54D9C68B14F3D13795FAAA20A5133B73D1FEBD1AD1B12B2010A8687D6848335A1C0BA4FCBF530A098EE16C22EEBE21D5DD8C296ECA39501B3D1A8848DEC265B9A1F63D95C852040B40A5B2E7712D8A24CAC67245D9AD3A8D9446E26905A4D8A2002876659BFE9204D30A08CBC49095FF3045C33E52C20FD6EA6FD5DD7E9F61E103190BE46638C0FBD43CCE88242020395921C7542F59D17E63BEB17C95798E45DEB989610B672294A856BF1F6667B, addr: 0x7f96fb044000>
Public KEY: <SecKeyRef curve type: kSecECCurveSecp256r1, algorithm id: 3, key type: ECPublicKey, version: 3, block size: 256 bits, y: Value1, x: Value2, addr: 0x7f96fc032970>
我在第二个输出中省略了“y”和“x”的值,因为我不知道是否应该发布它们。 “Value1”(y)是一个包含66个字符的字符串,“Value2”(x)是一个包含130个字符的字符串。两者都只有数字和大写字母,没有符号。
第二个输出中的“x”和“y”值是多少?他们是“subjectPublicKeyInfo”吗?为什么这个函数被调用两次?为什么我必须在调用“SecTrustCopyPublicKey”之前调用“SecTrustEvaluate”?文件说我必须这样做,但我找不到原因。此外,当建立HTTPS连接时,iOS会自动执行“SecTrustEvaluate”的操作吗?
答案 0 :(得分:0)
什么是&#34; x&#34;和&#34; y&#34;第二个输出中的值?
正在使用的椭圆曲线的参数。基本上,&#34;公钥。&#34;出于您的目的,您不需要知道数学,但是接受有两个非常大的数字,当放入数学曲线的公式时,可以用于加密只有发送方可以解密的数据,或者对称地,以验证数据是否由给定发件人发送。如果你关心,here's对这个概念有一个相当有用的介绍。没有一些数学就很难解释,但那篇论文中的数学并不太疯狂。
&#34;数字和字母&#34;只是两个大数的十六进制编码。它与&#34;模数&#34;相同。在你列出的另一个键中。这是一种不同的算法,称为RSA。在这种情况下,这是一个(实际上非常巨大的)数字,将用作其中一个步骤中的模数(除以数字并取余数)。
所有这些数字都是公开的。这里没有秘密。
为什么这个函数被调用两次?
它开始谈判RSA。然后看起来它升级到椭圆曲线,对于密钥中的给定位数,椭圆曲线通常更强。简答:&#34;协议升级。&#34;
为什么我必须致电&#34; SecTrustEvaluate&#34;在致电&#34; SecTrustCopyPublicKey&#34;?
之前
SecTrustEvaluate
在数据结构中的公钥可用之前进行一堆必要的解码。 &#34;因为Security.Framework是以这种方式实现的。&#34;从理论上讲,SecTrustCopyPublicKey
可以在必要时进行解码,但它没有。
此外,iOS会自动执行&#34; SecTrustEvaluate&#34;是,当建立HTTPS连接时?
是