在 swift 中使用 public 密钥加密
using public key encryption in swift
我正在尝试使用网络服务开发人员提供给我的 public 密钥来安全地传输数据。我已经很努力了,但我找不到任何最新 swift 版本的工作示例。我将其编码如下(在 here:
的帮助下
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge){
if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
var localTrust: UnsafeMutablePointer<SecTrust?>
let serverTrust = challenge.protectionSpace.serverTrust!
let serverPublicKey = SecTrustCopyPublicKey(serverTrust)
let certificateData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("pinning-certificate", ofType: "der")!)
let localCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, certificateData!)
let policy = SecPolicyCreateBasicX509()
if SecTrustCreateWithCertificates(localCertificate!, policy, localTrust) == errSecSuccess {
let localTrustRef = localTrust
let localPublicKey = SecTrustCopyPublicKey(localTrustRef)!
if (localPublicKey as AnyObject).isEqual(serverPublicKey as! AnyObject) {
print("trusted")
return challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
}
}
}
print("not trusted")
return challenge.sender!.cancelAuthenticationChallenge(challenge)
}
但我在 SecTrustCreateWithCertificates() 和 SecTrustCopyPublicKey() 编译期间遇到以下错误:
无法将类型 'UnsafeMutablePointer?' 的值转换为预期的参数类型 'UnsafeMutablePointer'(又名 'UnsafeMutablePointer>')。
编辑 1: 我已将我的代码更改为以下内容,现在我的代码已执行但服务器未收到任何请求:
func extractIdentity(certData:NSData) -> IdentityAndTrust {
var identityAndTrust:IdentityAndTrust!
var securityError:OSStatus = errSecSuccess
let path: String = NSBundle.mainBundle().pathForResource("MobileAppClient", ofType: "pfx")!
let PKCS12Data = NSData(contentsOfFile:path)!
let key : NSString = kSecImportExportPassphrase as NSString
let options : NSDictionary = [key : "client"]
//create variable for holding security information
//var privateKeyRef: SecKeyRef? = nil
var items : CFArray?
securityError = SecPKCS12Import(PKCS12Data, options, &items)
if securityError == errSecSuccess {
let certItems:CFArray = items as CFArray!;
let certItemsArray:Array = certItems as Array
let dict:AnyObject? = certItemsArray.first;
if let certEntry:Dictionary = dict as? Dictionary<String, AnyObject> {
// grab the identity
let identityPointer:AnyObject? = certEntry["identity"];
let secIdentityRef:SecIdentityRef = identityPointer as! SecIdentityRef!;
print("\(identityPointer) :::: \(secIdentityRef)")
// grab the trust
let trustPointer:AnyObject? = certEntry["trust"];
let trustRef:SecTrustRef = trustPointer as! SecTrustRef;
print("\(trustPointer) :::: \(trustRef)")
// grab the cert
let chainPointer:AnyObject? = certEntry["chain"];
identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certArray: chainPointer! as! NSArray);
}
}
return identityAndTrust;
}
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge){
if challenge.protectionSpace.authenticationMethod == (NSURLAuthenticationMethodServerTrust) {
let serverTrust:SecTrustRef = challenge.protectionSpace.serverTrust!
let certificate: SecCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)!
let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))!
let cerPath: String = NSBundle.mainBundle().pathForResource("Certificates", ofType: "cer")!
let localCertificateData = NSData(contentsOfFile:cerPath)!
challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge)
if (remoteCertificateData.isEqualToData(localCertificateData) == true) {
let credential:NSURLCredential = NSURLCredential(forTrust: serverTrust)
challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge)
} else {
SVProgressHUD.dismiss()
return challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
}
}
else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate
{
let path: String = NSBundle.mainBundle().pathForResource("Certificates", ofType: "p12")!
let PKCS12Data = NSData(contentsOfFile:path)!
let identityAndTrust:IdentityAndTrust = self.extractIdentity(PKCS12Data);
let urlCredential:NSURLCredential = NSURLCredential(
identity: identityAndTrust.identityRef,
certificates: identityAndTrust.certArray as? [AnyObject],
persistence: NSURLCredentialPersistence.ForSession);
challenge.sender?.useCredential(urlCredential, forAuthenticationChallenge: challenge)
}
}
我认为有两个问题:
1) 要投射 UnsafeMutablePointer
你应该调用 localTrust.memory
但它会给你下一个错误
2)下一个错误会给你未初始化的指针,我想你可以使用这样的代码:
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge){
if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
var localTrust: UnsafeMutablePointer<SecTrust?> = nil
let serverTrust = challenge.protectionSpace.serverTrust!
let serverPublicKey = SecTrustCopyPublicKey(serverTrust)
let certificateData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("pinning-certificate", ofType: "der")!)
let localCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, certificateData!)
let policy = SecPolicyCreateBasicX509()
if SecTrustCreateWithCertificates(localCertificate!, policy, localTrust) == errSecSuccess {
let localTrustRef = localTrust
let localPublicKey = SecTrustCopyPublicKey(localTrustRef.memory!)!
if (localPublicKey as AnyObject).isEqual(serverPublicKey as! AnyObject) {
print("trusted")
return challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
}
}
}
print("not trusted")
return challenge.sender!.cancelAuthenticationChallenge(challenge)
}
P.s。强制施放 optional
是不安全的。请考虑使用 if let
语句
请找出下面给出的答案:
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
if challenge.protectionSpace.authenticationMethod == (NSURLAuthenticationMethodServerTrust) {
let serverTrust:SecTrustRef = challenge.protectionSpace.serverTrust!
let certificate: SecCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)!
let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))!
let cerPath: String = NSBundle.mainBundle().pathForResource("xyz.com", ofType: "cer")!
let localCertificateData = NSData(contentsOfFile:cerPath)!
if (remoteCertificateData.isEqualToData(localCertificateData) == true) {
let credential:NSURLCredential = NSURLCredential(forTrust: serverTrust)
challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge)
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!))
} else {
completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge, nil)
}
}
else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate
{
let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")!
let PKCS12Data = NSData(contentsOfFile:path)!
let identityAndTrust:IdentityAndTrust = self.extractIdentity(PKCS12Data);
let urlCredential:NSURLCredential = NSURLCredential(
identity: identityAndTrust.identityRef,
certificates: identityAndTrust.certArray as? [AnyObject],
persistence: NSURLCredentialPersistence.ForSession);
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, urlCredential);
}
else
{
completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge, nil);
}
}
添加以下代码
struct IdentityAndTrust {
var identityRef:SecIdentityRef
var trust:SecTrustRef
var certArray:AnyObject
}
func extractIdentity(certData:NSData) -> IdentityAndTrust {
var identityAndTrust:IdentityAndTrust!
var securityError:OSStatus = errSecSuccess
let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")!
let PKCS12Data = NSData(contentsOfFile:path)!
let key : NSString = kSecImportExportPassphrase as NSString
let options : NSDictionary = [key : "xyz"]
//create variable for holding security information
//var privateKeyRef: SecKeyRef? = nil
var items : CFArray?
securityError = SecPKCS12Import(PKCS12Data, options, &items)
if securityError == errSecSuccess {
let certItems:CFArray = items as CFArray!;
let certItemsArray:Array = certItems as Array
let dict:AnyObject? = certItemsArray.first;
if let certEntry:Dictionary = dict as? Dictionary<String, AnyObject> {
// grab the identity
let identityPointer:AnyObject? = certEntry["identity"];
let secIdentityRef:SecIdentityRef = identityPointer as! SecIdentityRef!;
print("\(identityPointer) :::: \(secIdentityRef)")
// grab the trust
let trustPointer:AnyObject? = certEntry["trust"];
let trustRef:SecTrustRef = trustPointer as! SecTrustRef;
print("\(trustPointer) :::: \(trustRef)")
// grab the cert
let chainPointer:AnyObject? = certEntry["chain"];
identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certArray: chainPointer!);
}
}
return identityAndTrust;
}
我正在尝试使用网络服务开发人员提供给我的 public 密钥来安全地传输数据。我已经很努力了,但我找不到任何最新 swift 版本的工作示例。我将其编码如下(在 here:
的帮助下func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge){
if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
var localTrust: UnsafeMutablePointer<SecTrust?>
let serverTrust = challenge.protectionSpace.serverTrust!
let serverPublicKey = SecTrustCopyPublicKey(serverTrust)
let certificateData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("pinning-certificate", ofType: "der")!)
let localCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, certificateData!)
let policy = SecPolicyCreateBasicX509()
if SecTrustCreateWithCertificates(localCertificate!, policy, localTrust) == errSecSuccess {
let localTrustRef = localTrust
let localPublicKey = SecTrustCopyPublicKey(localTrustRef)!
if (localPublicKey as AnyObject).isEqual(serverPublicKey as! AnyObject) {
print("trusted")
return challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
}
}
}
print("not trusted")
return challenge.sender!.cancelAuthenticationChallenge(challenge)
}
但我在 SecTrustCreateWithCertificates() 和 SecTrustCopyPublicKey() 编译期间遇到以下错误: 无法将类型 'UnsafeMutablePointer?' 的值转换为预期的参数类型 'UnsafeMutablePointer'(又名 'UnsafeMutablePointer>')。
编辑 1: 我已将我的代码更改为以下内容,现在我的代码已执行但服务器未收到任何请求:
func extractIdentity(certData:NSData) -> IdentityAndTrust {
var identityAndTrust:IdentityAndTrust!
var securityError:OSStatus = errSecSuccess
let path: String = NSBundle.mainBundle().pathForResource("MobileAppClient", ofType: "pfx")!
let PKCS12Data = NSData(contentsOfFile:path)!
let key : NSString = kSecImportExportPassphrase as NSString
let options : NSDictionary = [key : "client"]
//create variable for holding security information
//var privateKeyRef: SecKeyRef? = nil
var items : CFArray?
securityError = SecPKCS12Import(PKCS12Data, options, &items)
if securityError == errSecSuccess {
let certItems:CFArray = items as CFArray!;
let certItemsArray:Array = certItems as Array
let dict:AnyObject? = certItemsArray.first;
if let certEntry:Dictionary = dict as? Dictionary<String, AnyObject> {
// grab the identity
let identityPointer:AnyObject? = certEntry["identity"];
let secIdentityRef:SecIdentityRef = identityPointer as! SecIdentityRef!;
print("\(identityPointer) :::: \(secIdentityRef)")
// grab the trust
let trustPointer:AnyObject? = certEntry["trust"];
let trustRef:SecTrustRef = trustPointer as! SecTrustRef;
print("\(trustPointer) :::: \(trustRef)")
// grab the cert
let chainPointer:AnyObject? = certEntry["chain"];
identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certArray: chainPointer! as! NSArray);
}
}
return identityAndTrust;
}
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge){
if challenge.protectionSpace.authenticationMethod == (NSURLAuthenticationMethodServerTrust) {
let serverTrust:SecTrustRef = challenge.protectionSpace.serverTrust!
let certificate: SecCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)!
let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))!
let cerPath: String = NSBundle.mainBundle().pathForResource("Certificates", ofType: "cer")!
let localCertificateData = NSData(contentsOfFile:cerPath)!
challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge)
if (remoteCertificateData.isEqualToData(localCertificateData) == true) {
let credential:NSURLCredential = NSURLCredential(forTrust: serverTrust)
challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge)
} else {
SVProgressHUD.dismiss()
return challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
}
}
else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate
{
let path: String = NSBundle.mainBundle().pathForResource("Certificates", ofType: "p12")!
let PKCS12Data = NSData(contentsOfFile:path)!
let identityAndTrust:IdentityAndTrust = self.extractIdentity(PKCS12Data);
let urlCredential:NSURLCredential = NSURLCredential(
identity: identityAndTrust.identityRef,
certificates: identityAndTrust.certArray as? [AnyObject],
persistence: NSURLCredentialPersistence.ForSession);
challenge.sender?.useCredential(urlCredential, forAuthenticationChallenge: challenge)
}
}
我认为有两个问题:
1) 要投射 UnsafeMutablePointer
你应该调用 localTrust.memory
但它会给你下一个错误
2)下一个错误会给你未初始化的指针,我想你可以使用这样的代码:
func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge){
if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
var localTrust: UnsafeMutablePointer<SecTrust?> = nil
let serverTrust = challenge.protectionSpace.serverTrust!
let serverPublicKey = SecTrustCopyPublicKey(serverTrust)
let certificateData = NSData(contentsOfFile: NSBundle.mainBundle().pathForResource("pinning-certificate", ofType: "der")!)
let localCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, certificateData!)
let policy = SecPolicyCreateBasicX509()
if SecTrustCreateWithCertificates(localCertificate!, policy, localTrust) == errSecSuccess {
let localTrustRef = localTrust
let localPublicKey = SecTrustCopyPublicKey(localTrustRef.memory!)!
if (localPublicKey as AnyObject).isEqual(serverPublicKey as! AnyObject) {
print("trusted")
return challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge)
}
}
}
print("not trusted")
return challenge.sender!.cancelAuthenticationChallenge(challenge)
}
P.s。强制施放 optional
是不安全的。请考虑使用 if let
语句
请找出下面给出的答案:
func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
if challenge.protectionSpace.authenticationMethod == (NSURLAuthenticationMethodServerTrust) {
let serverTrust:SecTrustRef = challenge.protectionSpace.serverTrust!
let certificate: SecCertificateRef = SecTrustGetCertificateAtIndex(serverTrust, 0)!
let remoteCertificateData = CFBridgingRetain(SecCertificateCopyData(certificate))!
let cerPath: String = NSBundle.mainBundle().pathForResource("xyz.com", ofType: "cer")!
let localCertificateData = NSData(contentsOfFile:cerPath)!
if (remoteCertificateData.isEqualToData(localCertificateData) == true) {
let credential:NSURLCredential = NSURLCredential(forTrust: serverTrust)
challenge.sender?.useCredential(credential, forAuthenticationChallenge: challenge)
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, NSURLCredential(forTrust: challenge.protectionSpace.serverTrust!))
} else {
completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge, nil)
}
}
else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate
{
let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")!
let PKCS12Data = NSData(contentsOfFile:path)!
let identityAndTrust:IdentityAndTrust = self.extractIdentity(PKCS12Data);
let urlCredential:NSURLCredential = NSURLCredential(
identity: identityAndTrust.identityRef,
certificates: identityAndTrust.certArray as? [AnyObject],
persistence: NSURLCredentialPersistence.ForSession);
completionHandler(NSURLSessionAuthChallengeDisposition.UseCredential, urlCredential);
}
else
{
completionHandler(NSURLSessionAuthChallengeDisposition.CancelAuthenticationChallenge, nil);
}
}
添加以下代码
struct IdentityAndTrust {
var identityRef:SecIdentityRef
var trust:SecTrustRef
var certArray:AnyObject
}
func extractIdentity(certData:NSData) -> IdentityAndTrust {
var identityAndTrust:IdentityAndTrust!
var securityError:OSStatus = errSecSuccess
let path: String = NSBundle.mainBundle().pathForResource("client", ofType: "p12")!
let PKCS12Data = NSData(contentsOfFile:path)!
let key : NSString = kSecImportExportPassphrase as NSString
let options : NSDictionary = [key : "xyz"]
//create variable for holding security information
//var privateKeyRef: SecKeyRef? = nil
var items : CFArray?
securityError = SecPKCS12Import(PKCS12Data, options, &items)
if securityError == errSecSuccess {
let certItems:CFArray = items as CFArray!;
let certItemsArray:Array = certItems as Array
let dict:AnyObject? = certItemsArray.first;
if let certEntry:Dictionary = dict as? Dictionary<String, AnyObject> {
// grab the identity
let identityPointer:AnyObject? = certEntry["identity"];
let secIdentityRef:SecIdentityRef = identityPointer as! SecIdentityRef!;
print("\(identityPointer) :::: \(secIdentityRef)")
// grab the trust
let trustPointer:AnyObject? = certEntry["trust"];
let trustRef:SecTrustRef = trustPointer as! SecTrustRef;
print("\(trustPointer) :::: \(trustRef)")
// grab the cert
let chainPointer:AnyObject? = certEntry["chain"];
identityAndTrust = IdentityAndTrust(identityRef: secIdentityRef, trust: trustRef, certArray: chainPointer!);
}
}
return identityAndTrust;
}