使用 Swift 3 和 Alamofire 4 获取客户端证书以进行相互身份验证

2024-01-23

我试图弄清楚如何使用 Alamofire 4.0 和 Swift 3.0 将 p12 (如果需要,我也有 PEM 证书和密钥)发送到网站进行身份验证。我看到的所有示例都是针对 Swift 2.0 的,并不完全是我想要的。在我的 mac 上的 safari 中,我可以通过将 p12 放入钥匙串中并在 safari 询问时发送来访问该网站,这样我就知道该部分有效。我不知道是否有人可以帮助我举一个如何在应用程序中的 Alamofire 4.0 和 Swift 3.0 中执行此操作的示例。证书也是自签名的。

有什么想法或帮助吗?我不仅仅是想固定证书,因为客户端密钥和证书需要发送到服务器进行访问......


我能够让它发挥作用。有几个问题妨碍了我们。首先,您必须允许 IOS 接受自签名证书。这需要设置 AlamoFire serverTrustPolicy:

let serverTrustPolicies: [String: ServerTrustPolicy] = [
        "your-domain.com": .disableEvaluation
    ]

self.sessionManager = Alamofire.SessionManager(
        serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies)
    )

从那里,您必须重写 sessionDidRecieveChallenge 才能发送客户端证书。因为我想使用 p12 文件,所以我修改了在其他地方找到的一些代码(抱歉我不再有源代码),使 Swift 3.0 使用基础类导入 p12:

import Foundation

public class PKCS12  {
    var label:String?
    var keyID:Data?
    var trust:SecTrust?
    var certChain:[SecTrust]?
    var identity:SecIdentity?

    let securityError:OSStatus

    public init(data:Data, password:String) {

        //self.securityError = errSecSuccess

        var items:CFArray?
        let certOptions:NSDictionary = [kSecImportExportPassphrase as NSString:password as NSString]

        // import certificate to read its entries
        self.securityError = SecPKCS12Import(data as NSData, certOptions, &items);

        if securityError == errSecSuccess {
            let certItems:Array = (items! as Array)
            let dict:Dictionary<String, AnyObject> = certItems.first! as! Dictionary<String, AnyObject>;

            self.label = dict[kSecImportItemLabel as String] as? String;
            self.keyID = dict[kSecImportItemKeyID as String] as? Data;
            self.trust = dict[kSecImportItemTrust as String] as! SecTrust?;
            self.certChain = dict[kSecImportItemCertChain as String] as? Array<SecTrust>;
            self.identity = dict[kSecImportItemIdentity as String] as! SecIdentity?;
        }


    }

    public convenience init(mainBundleResource:String, resourceType:String, password:String) {
        self.init(data: NSData(contentsOfFile: Bundle.main.path(forResource: mainBundleResource, ofType:resourceType)!)! as Data, password: password);
    }

    public func urlCredential()  -> URLCredential  {
        return URLCredential(
            identity: self.identity!,
            certificates: self.certChain!,
            persistence: URLCredential.Persistence.forSession);

    }



}

这将允许我导入文件并将其发送回客户端。

let cert = PKCS12.init(mainBundleResource: "cert", resourceType: "p12", password: "password");

self.sessionManager.delegate.sessionDidReceiveChallenge = { session, challenge in
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate {
            return (URLSession.AuthChallengeDisposition.useCredential, self.cert.urlCredential());
        }
        if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
            return (URLSession.AuthChallengeDisposition.useCredential, URLCredential(trust: challenge.protectionSpace.serverTrust!));
        }
        return (URLSession.AuthChallengeDisposition.performDefaultHandling, Optional.none);
    }

现在,您可以使用 sessionManager 创建所需数量的调用。

作为说明,我还按照建议将以下内容添加到了 info.plist 中,以绕过较新 iOS 功能中的新安全功能:

<key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
        <key>NSExceptionDomains</key>
        <dict>
            <key>your-domain.com</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSExceptionRequiresForwardSecrecy</key>
                <false/>
                <key>NSExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
        </dict>
    </dict>

我希望这有帮助!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Swift 3 和 Alamofire 4 获取客户端证书以进行相互身份验证 的相关文章

随机推荐

  • CriteriaBuilder. 和 & CriteriaBuilder.or,如何操作?

    我正在尝试更改以下 HQL 以使用 JPA Criteria select distinct d from Department d left join fetch d children c where d parent is null a
  • 如何告诉 Visual Studio 不要填充设计器代码中的字段?

    我有一个自定义控件 当我将其拖到表单上时 会创建以下 Designer cs 代码 colorPickerBackground this colorPickerBackground Color Color Empty this colorP
  • 主线程上的 Okhttp 响应回调

    我创建了一个帮助程序类来处理我的应用程序中的所有 http 调用 它是 okhttp 的一个简单的单例包装器 如下所示 我省略了一些不重要的部分 public class HttpUtil private OkHttpClient clie
  • 在RelativeLayout中获取子视图

    我想在我的活动中添加一个按钮 该按钮将返回相对布局的所有子视图 如何获取相对布局视图的所有子视图 RelativeLayout延伸ViewGroup其中有getChildCount and getChildAt int index 方法 所
  • 使用命令行编译 C++ 代码

    我使用下面的命令来编译我的 C 代码 它使用 OpenCV 库 我的命令就像 opencv main cpp o binary name 其中 opencv 是一个别名命令 例如 alias opencv g pkg config cfla
  • 使用 YoutubeURL 获取 oembed 返回 403 Forbidden

    这几天 我突然收到来自 403 Forbidden 的回复https www youtube com oembed url youtubeURl 我检查了Youtube API的文档 但我找不到它对oembed有限制并且也有授权 我只能看到
  • 在 bash 中将 HH:MM:SS.mm 转换为秒

    我正在运行一些 gnu 时间脚本 它们会生成以下形式的输出 mm ss mm 分 秒和毫秒 例如 1 20 66 或 hh MM ss 小时 分钟和秒 例如 1 43 38 我想将其转换为秒 以便比较它们并将它们绘制在图形中 使用 bash
  • Silverlight:如何在代码后面更改AxisLabelStyle?

    在 xaml 文件中 我们可以通过执行以下操作来更改 AxisLabelStyle
  • Java Servlet API 向后兼容吗?

    我想编写一个使用 javax servlet API 的 JAR 文件 如果我针对 2 2 版本编写 是否意味着它可以在 2 3 2 4 和 2 5 版本上工作 Thanks 是的 它们是向后兼容的 甲骨文来源 http docs orac
  • 面向对象设计实践问题[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 过去几年我几乎只开发 C 代码 我目前正在寻求提高我的面向对象设计技能 任何人都可以推荐任何包含一系列简
  • 如何在 Kerberos 中“取消模拟”(取消委托?)

    我有一个使用 Kerberos 的 Web 应用程序来使用 ASP NET 3 5 和 IIS 访问外部资源 当用户连接到应用程序时 Kerberos 身份验证会自动允许我使用委派作为用户连接到外部资源 这并不容易做到 这很好 但我有一个问
  • .net 正则表达式用于超过 2 个连续字母

    我正在尝试为 2 个以上的连续字母编写 Net 正则表达式 aa fine Aa fine aaa not allowed Aaa not allowed 我是正则表达式的新手 但这是我到目前为止所拼凑的 if Regex IsMatch
  • uwp命令栏始终显示标签

    Answer 谢谢贾斯汀XL https stackoverflow com users 231837 justin xl我能够解决我的问题 我实现了他在下面的回答中提供的样式 并按照他的说法在 App xaml 中添加了这一点 我将高度更
  • 在 Android 上点击后退按钮时关闭应用程序

    所以我的登录活动是您看到的第一个屏幕 当您点击后退按钮时 它会退出应用程序 很好 所以我再次打开应用程序 登录后 我现在处于我的主要活动中 我该如何做到这一点 以便当我现在点击后退按钮时 它会退出应用程序而不是返回到登录活动 当您推送新活动
  • git分支、fork、fetch、merge、rebase和clone之间有什么区别?

    我想了解 Git 中分支 分叉和克隆之间的区别 同样 当我做一个时 这意味着什么git fetch与git pull 另外 什么是rebase与 相比 意味着merge 我怎样才能将个人的承诺压缩在一起 它们如何使用 为什么使用以及它们代表
  • 从另一个对象向 stdClass 对象添加属性

    我希望能够执行以下操作 obj new stdClass obj gt status success obj2 new stdClass obj2 gt message OK 如何扩展 obj 使其包含 obj2 的属性 例如 obj gt
  • 错误:未定义配置属性“mongoURI”

    我尝试启动一个项目 但是当我尝试将 mongo 连接到服务器时 我遇到一个错误 显示连接不起作用 因为它找不到连接字符串所在的文件夹 我的数据库文件 const mongoose require mongoose const config
  • Roslyn 实际上允许您操作 CSharp 项目的 TreatWarningsAsErrors 吗?

    我正在尝试检索设置 TreatWarningsAsErrors 但无法为我加载的解决方案的项目找到它 我想要完成的是从项目文件中获取设置 并将其设置为true 如果还没有的话 接下来 我想让 Roslyn 使用新设置进行编译 这样我就可以检
  • 替换 html 标签中没有的所有引号

    目前我正在用特殊引号替换文本中的所有引号 但是我如何更改我的正则表达式 只替换文本中的引号 而不替换 html 标记中使用的引号 text preg replace w raquo text text preg replace lt w l
  • 使用 Swift 3 和 Alamofire 4 获取客户端证书以进行相互身份验证

    我试图弄清楚如何使用 Alamofire 4 0 和 Swift 3 0 将 p12 如果需要 我也有 PEM 证书和密钥 发送到网站进行身份验证 我看到的所有示例都是针对 Swift 2 0 的 并不完全是我想要的 在我的 mac 上的