2015-01-09 26 views
2

我使用SecKeyGeneratePair生成了一个守护者。如何导出使用SecKeyGeneratePair生成的用于服务器的公钥<SecKey>?

 var publicKeyPtr, privateKeyPtr: Unmanaged<SecKey>? 

     let publicKeyParameters: [String: AnyObject] = [ 
      kSecAttrIsPermanent: true, 
      kSecAttrApplicationTag: "com.example.site.public" 
     ] 
     let privateKeyParameters: [String: AnyObject] = [ 
      kSecAttrIsPermanent: true, 
      kSecAttrApplicationTag: "com.example.site.private" 
     ] 
     let parameters: [String: AnyObject] = [ 
      kSecAttrKeyType: kSecAttrKeyTypeRSA, 
      kSecAttrKeySizeInBits: 2048, 
      kSecPublicKeyAttrs.takeUnretainedValue() as String: publicKeyParameters, 
      kSecPrivateKeyAttrs.takeUnretainedValue() as String: privateKeyParameters 
     ] 
     let result = SecKeyGeneratePair(parameters, &publicKeyPtr, &privateKeyPtr) 
     let publicKey = publicKeyPtr!.takeRetainedValue() 
     let privateKey = privateKeyPtr!.takeRetainedValue() 
     let blockSize = SecKeyGetBlockSize(publicKey) 

如果我打印出来的公钥,我可以看到的模量,这一点我敢肯定是我需要的:

publicKey: <SecKeyRef algorithm id: 1, key type: RSAPublicKey, version: 3, block size: 2048 bits, exponent: {hex: 10001, decimal: 65537}, modulus: B2A7BD90C909F8084AD5B34040ABDAF7D1A6AFBADB35F3B6AB5CDDAB473449B0F175DEA32A7476F339D98F4AB3716AA2C1476D4009A80574B984DDFA1EF1A2550E48C46791CEFBFC39EF281049AA74E4C734C3B2A7B3F621B8A41F8B6689C4978696690D4EF9FFF0F90DB85C8ECBCF721FB7652AD7B337880A09D97EA736008C3ADBB72223F18C522C0C0889B05122561042D8637D1CBEF8F9F5AE88CDC43E411AA217E2A81C2D812B46D01C3BDC2799DFF3EAD46BB092A566E18EE94F63C4690ECE806B993FDDAC3159BE2098C2428F24969C109E221D8F066BEE3530848DE328D888B4C7E701435EACB116F97BB77B9379EF818B4D280890262EE678B92705, addr: 0x144841a00> 

但我无法弄清楚如何导出密钥,以便我能发送给我的服务器在那里使用。

从我的理解。 SecKey存储在Keychain中,并且是指向它的指针,块大小是内存中密钥的长度。所以理论上我可以将它解压缩为NSData,然后将其转换为我的服务器可以读取的内容。从理论上讲,我认为这会奏效,我在实践中遇到了困难。所有的帮助将不胜感激。

回答

3

SecItemCopyMatching是你:

var dataPtr:Unmanaged<AnyObject>? 
let query: [String:AnyObject] = [ 
    kSecClass: kSecClassKey, 
    kSecAttrApplicationTag: "com.example.site.public", 
    kSecReturnData: kCFBooleanTrue 
] 
let qResult = SecItemCopyMatching(query, &dataPtr) 

// error handling with `qResult` ... 

let publicKeyData = dataPtr!.takeRetainedValue() as NSData 

// convert to Base64 string 
let base64PublicKey = publicKeyData.base64EncodedStringWithOptions(nil) 

注意,数据的大小是270,不一样的关键块大小。见this question on the crypto.stackexchange.com

+0

看起来很有前途,谢谢。只要我可以测试它,我就会将其标记为正确。快速跟进。我看到它是NSData,我将如何将它转换为我可以发送到可以理解的Web服务器的东西?谢谢。 – jackreichert

+0

这取决于服务器接受的内容。通常,对于使用HTTP发送到服务器,使用'publicKeyData.base64EncodedStringWithOptions(nil)'编码为base64字符串,并使用'NSJSONSerialization'序列化为JSON。 – rintaro

+0

所以,即使我们在做PublicData的NSData我仍然可以base64EncodeString它呢? – jackreichert

相关问题