首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SecPKCS12Import在iOS 11上返回的结果与iOS 10上的结果不同

SecPKCS12Import在iOS 11上返回的结果与iOS 10上的结果不同
EN

Stack Overflow用户
提问于 2017-10-14 10:54:50
回答 2查看 1.1K关注 0票数 5

此函数接受Base64编码的PKCS#12证书字符串作为参数,然后对其进行解码并传递给SecPKCS12Import函数。在更新到iOS 11 ( SecPKCS12Import )之后,会产生不同的结果。在这两个操作系统版本上,securityError返回0。

代码语言:javascript
运行
复制
let securityError: OSStatus = SecPKCS12Import(decodedData!, options, &items)

返回0项的列表。而在iOS 10上,我得到数组中的1项。

代码语言:javascript
运行
复制
func certificateFromCertificate(certP12: String, psswd: String) -> SecCertificate {
    let decodedData = NSData(base64Encoded: certP12, options:NSData.Base64DecodingOptions(rawValue: 0))

    let keytmp : NSString = kSecImportExportPassphrase as NSString
    let options : NSDictionary = [keytmp : psswd]

    var certificateRef: SecCertificate? = nil

    var items : CFArray?

    let securityError: OSStatus = SecPKCS12Import(decodedData!, options, &items)

    let theArray: CFArray = items!
    if securityError == noErr && CFArrayGetCount(theArray) > 0 {
        let newArray = theArray as [AnyObject] as NSArray
        let dictionary = newArray.object(at: 0)
        let secIdentity = (dictionary as AnyObject)[kSecImportItemIdentity as String] as! SecIdentity
        let securityError = SecIdentityCopyCertificate(secIdentity , &certificateRef)
        if securityError != noErr {
            certificateRef = nil
        }
    }

    certificate = certificateRef

    return certificateRef!
}

这是苹果开发者论坛上的一篇文章,它说SecPKCS12Import实现了来自Base64的自动转换。这意味着在将普通证书传递给函数之前,我应该对其进行解码。这会是问题吗?

我已经向苹果论坛技术支援事件提交了帖子。

开发环境:

编程语言: Swift 3

调试设备: Apple iPad迷你Retina Wi 32 Fi ME280SL/A

开发设备: iMAC迷你Xcode版本9.0 9A 235

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-01-30 08:18:09

Apple支持部门对此问题进行了调查,并得出结论:特定的.p12文件具有DER编码,而不符合iOS 11的安全要求。

下面发布Quinn来自Apple的电子邮件:

要了解发生了什么,必须在函数SecKeyCreateRSAPrivateKey上设置一个断点。这是Security中的一个私有函数,因此您需要使用一个符号断点(在断点导航器中,单击+按钮并从菜单中选择符号断点。一旦你这样做了,点击“测试1”按钮,你将停止在断点。 这个函数有4个参数,但两个相关的参数是第二个和第三个参数,它们是一个指向RSA私钥的指针。 要解码的数据和该数据的长度。一旦到达断点,就可以按如下方式转储数据:

代码语言:javascript
运行
复制
(lldb) # Confirm the length in the third argument.
(lldb) p $arg3
(unsigned long) $0 = 1192
(lldb) # Dump the data pointed to be the second argument.
(lldb) memory read -f x -s 1 -c 1192 --force $arg2
… elided …

结果太长,无法在这里包含,因此我取消了十六进制编码,并将结果作为文件RSAPrivateKey.asn1附加。 如果用dumpasn1转储它,就会发现问题所在:

代码语言:javascript
运行
复制
$ dumpasn1 -p -a RSAPrivateKey.asn1 
SEQUENCE {
  INTEGER 0
  INTEGER
    …
  INTEGER 65537
  INTEGER
    00 0B 67 67 29 0A 38 38 7A 7E 17 39 E7 84 FB 7D
    02 D1 AB AD 21 27 4D CD 2C 09 C1 1F CB 73 5C 18
    37 D4 CE E2 98 61 19 3B 70 6C 1A 1B 33 E8 69 8C
    65 5B 77 B8 24 9C 90 8A 79 A7 4A 77 26 38 7C 3E
    70 3C 80 24 BD 73 DA 97 5A F3 90 0F 79 2D 45 F8
    2A 5A 37 03 4D 0C 80 DB 8F 99 67 55 D3 F3 70 CA
    2D F0 B6 48 6A D8 9A 95 CE AA C8 F1 96 24 04 61
    38 A1 7C CD 56 70 5E F9 13 D4 1B E2 F2 5D 28 67
    9A 30 E0 ED 71 84 4C EC 86 44 18 5F 64 70 46 D8
    6B 3A 52 2C D7 DE AF E5 E2 35 41 0D 1E FF E7 DE
    AC 43 83 5C A6 F2 2E C8 79 1A 30 87 7A 78 9B 42
    3E D9 2D AA C0 9D A6 7C E9 5C E3 6C 1E 8D 87 DF
    EB 05 DF CA F5 B9 2D BA B6 01 71 18 22 4D 25 4E
    D5 77 CB B8 9B 95 F9 C6 39 1C 0D D2 46 E4 4A 45
    D8 26 6F B4 25 03 E7 BE 91 02 43 7D DC B0 1E C8
    67 E8 2E 5F EA 3A 8D 1C 69 43 80 F9 60 69 BF BA
    01
    Error: Integer has non-DER encoding.
  INTEGER
    …
  INTEGER
    …
  INTEGER
    …
  INTEGER
    …
  INTEGER
    …
  }

注意,“INTEGER具有非DER编码”错误在第四个整数元素中被标记。这是因为整数数据不是规范的。在ASN.1 DER中,整数是有符号的,这就引入了歧义。像8000这样的值可以解释为-32768或32768。要解决此ASN.1 DER,需要将正窗体编码为008000(有类似的情况需要引导ff)。此外,DER还特别要求只在必要时添加此前导字节。在上面所示的情况下,第二个字节0b没有设置顶部位,因此不能有前导00。 早期版本的iOS没有强制执行这一要求。iOS 11包括许多安全强化更改,拒绝无效编码的ASN.1 DER整数是这些更改之一。 我曾见过其他开发人员被这种安全性变化所困扰,但是这些情况更容易调试,因为密钥不是嵌入在PKCS#12中的。此外,这个问题很难调试,因为当您用https://forums.developer.apple.com/message/262593#262593解压缩.p12时,它会忽略输入上的错误,并且在输出时会发出一个固定版本的私钥!

Quin建议我通过修复生成这个PKCS#12数据的代码来解决这个问题。如果这是不可能的,那么您需要编写(或获取)自己的代码来解析PKCS#12。iOS 11正确地拒绝了格式错误的私钥,这种情况不太可能改变。

票数 0
EN

Stack Overflow用户

发布于 2017-10-17 21:03:52

使用Xcode Version 9.0.1 (9A1004)Apple Swift version 4.0 (swiftlang-900.0.65.2 clang-900.0.37),我可以从您的函数中获得正常的结果。还可以使用Swift语言设置为3.2。

在你提到的那篇文章中,爱斯基摩说(用粗体表示我的):

你在这里的选择是:

  • 针对iOS 11测试版编写兼容性缺陷,并希望在通用汽车之前修复
  • 将应用程序更改为按文档方式使用SecPKCS12Import,即撤消Base64解码。

似乎有人提交了一个错误,并且这个问题已经被修复了(按照最初的记录来工作)。没有自动解码从Base64。你提供解码是对的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46743709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档