【问题标题】:Saving SecKeyRef device generated public/private key pair on disk将 SecKeyRef 设备生成的公钥/私钥对保存在磁盘上
【发布时间】:2011-08-24 17:29:16
【问题描述】:

我在设备上使用SecKeyGeneratePair() 在设备上生成了一个 RSA 对称密钥对。我有每个键的SecKeyRef struct 指针。那么,如何将SecKeyRef 保存到磁盘?甚至传输它(我也想正确编码也有问题)? Apple 的“证书、密钥和信任服务”指南说明

您可以将您的公钥发送给任何人,然后谁可以使用它来加密数据。

我特别想保存私钥;所以我可以在部署的设备上使用它来解密用公钥加密的数据。

附:我不介意每个键的结果数据是 DER 编码的 ASN.1 还是 base-64;我只需要弄清楚如何从SecKeyRef 中拔出钥匙。我也很清楚 OS X 的 SecKeychainItemExport() 不存在。

【问题讨论】:

    标签: iphone ios security cryptography


    【解决方案1】:

    您可以使用iOS最新的加密API,您可以将密钥保存为NSData并从NSData中检索密钥

    SecKeyRef key = <# a key #>;
    CFErrorRef error = NULL;
    NSData* keyData = (NSData*)CFBridgingRelease(  // ARC takes ownership
                           SecKeyCopyExternalRepresentation(key, &error)
                       );
    if (!keyData) {
        NSError *err = CFBridgingRelease(error);  // ARC takes ownership
        // Handle the error. . .
    }
    

    https://developer.apple.com/documentation/security/certificate_key_and_trust_services/keys/storing_keys_as_data?language=objc

    【讨论】:

    • 此方案仅适用于iOS10+
    【解决方案2】:

    请参阅证书、密钥和信任服务编程指南的 Encrypting and Decrypting Data 部分,其中包含用于生成、保存和使用公钥/私钥对的代码示例。

    【讨论】:

      【解决方案3】:

      啊,自己找到了答案;您可以使用SecItemCopyMatching() 获取公钥的字节数。

      - (NSData *)getPublicKeyBits {
          OSStatus sanityCheck = noErr;
          NSData * publicKeyBits = nil;
      
          NSMutableDictionary * queryPublicKey = [[NSMutableDictionary alloc] init];
      
          // Set the public key query dictionary.
          [queryPublicKey setObject:(id)kSecClassKey forKey:(id)kSecClass];
          [queryPublicKey setObject:publicTag forKey:(id)kSecAttrApplicationTag];
          [queryPublicKey setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
          [queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnData];
      
          // Get the key bits.
          sanityCheck = SecItemCopyMatching((CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKeyBits);
      
          if (sanityCheck != noErr)
          {
              publicKeyBits = nil;
          }
      
          [queryPublicKey release];
      
          return publicKeyBits;
      }
      

      以上内容来自 Apple 的 CryptoExercise。不确定它是否适用于私钥。

      【讨论】:

      • 不。我填写了一份错误报告,但从未得到承认。
      • 在上面的代码中,publicTag 是什么?当我使用SecKeyRef 代替publicTag 时,我收到“属性列表对格式无效:200(属性列表不能包含'SecKey' 类型的对象)”SecKeyRef 是不透明的 RSA 公钥(Apple ) 格式。
      猜你喜欢
      • 2011-11-24
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-18
      • 1970-01-01
      • 2014-08-19
      • 2012-04-05
      相关资源
      最近更新 更多