问题
自从 M1 Mac/iPad 问世以后,iPhone 应用开始需要运行在 M1 芯片环境上。但是我发现也不是全部都能完美运行。比如现在这个 aws-sdk-ios 的问题就困扰我很久。一直连接 MQTT 的状态错误。
原因
根据 SDK 输出的日志,大概能猜测出是证书读取出了问题。
addPublicKey error: -50
全局搜索 addPublicKey error:
关键字,发现 -50
对应的值是 errSecParam。根据苹果的枚举的注释,发现是由于参数设置错误的问题。
CF_ENUM(OSStatus) {
errSecParam = -50, /* One or more parameters passed to a function were not valid. */
}
但是 SecItemAdd
的 attributes
参数到底是哪一个呢?这个问题实在是没有科学的方法,只能把 iPhone
上运行的 attributes
和 Mac
上运行的 attributes
分别打印比较。还真的发现了一些问题。
iPhone
{
atag = "org.cocoapods.AWSIoT.RSAPublicTag.45dcd54444454a45adb61d4986b51f55.p12";
class = keys;
kcls = 0;
"r_PersistentRef" = 1;
type = 42;
"v_Ref" = "<SecKeyRef algorithm id: 1, key type: RSAPublicKey, version: 4, block size: 2048 bits, exponent: {hex: 10001, decimal: 65537}, modulus: CE19A564255D59, addr: 0x6000037b56e0.............>";
}
Mac
{
atag = "org.cocoapods.AWSIoT.RSAPublicTag.60555cbf61b14fe1826cb993610f7dd1.p12";
class = keys;
kcls = 0;
"r_PersistentRef" = 1;
type = 42;
"v_Ref" = "<SecCDSAKeyRef 0x60000045d9e0: algorithm id: 1, class=0, algorithm=2a, usage=8 attrs=24>";
}
只有 v_Ref
的值差异最大,没有包含具体的证书信息。这个值的变量名是 publicKey
,它是由 [AWSIoTManager readPk12:]
方法里赋值的。在 AWSIoTManager.m Line:363
。
查看 SecTrustCopyPublicKey
的定义,你就会有意外的收获。
__nullable
SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
API_DEPRECATED_WITH_REPLACEMENT("SecTrustCopyKey", macos(10.7, 11.0), ios(2.0, 14.0), watchos(1.0, 7.0), tvos(9.0, 14.0));
SecTrustCopyPublicKey
已经被抛弃了!
解决
尝试采用 SecTrustCopyKey
替换 SecTrustCopyPublicKey
。
if (@available(iOS 14, *)) {
*publicKeyRef = SecTrustCopyKey(trust);
} else {
*publicKeyRef = SecTrustCopyPublicKey(trust);
}
再次运行,一切都正常了呢!
本文由 Bill 创作。
最后编辑时间为: 2022.04.15 at 02:54 pm