Generate base64 url-encoded X.509 format 2048-bit RSA public key with Swift?

后端 未结 3 2029
梦如初夏
梦如初夏 2021-01-17 10:29

Working in Apple Swift for iOS. I have to generate this for the backend as it\'s a secure app.

I\'m new to security and certificates and have been searching for a da

3条回答
  •  悲&欢浪女
    2021-01-17 11:11

    If the public key is already in your keychain, you can look up the public key and return the data as base64 with something similar to the following:

    // Create dictionary to specify attributes for the key we're
    // searching for.  Swift will automatically bridge native values 
    // to to right types for the SecItemCopyMatching() call.
    var queryAttrs = [NSString:AnyObject]() 
    queryAttrs[kSecClass] = kSecClassKey 
    queryAttrs[kSecAttrApplicationTag] = publicKeyTag
    queryAttrs[kSecAttrKeyType] = kSecAttrKeyTypeRSA
    queryAttrs[kSecReturnData] = true
    
    var publicKeyBits = Unmanaged?()
    SecItemCopyMatching(queryAttrs, &publicKeyBits)
    
    // Work around a compiler bug with Unmanaged types
    //  the following two lines should simply be 
    //  let publicKeyData : NSData = publicKeyRef!.takeRetainedValue() as NSData
    let opaqueBits = publicKeyBits?.toOpaque() 
    let publicKeyData = Unmanaged.fromOpaque(opaqueBits).takeUnretainedValue()
    
    let publicKeyBase64 = publicKeyData.base64EncodedData(NSDataBase64EncodingOptions.Encoding64CharacterLineLength)
    

    If you need to generate the keypair and store it in the keychain, use something along these lines:

    // Create dictionaries to specify key attributes.  Swift will
    // automatically bridge native values to to right types for the
    // SecKeyGeneratePair() call.
    var pairAttrs = [NSString:AnyObject]()
    var privateAttrs = [NSString:AnyObject]()
    var publicAttrs = [NSString:AnyObject]()
    
    privateAttrs[kSecAttrIsPermanent] = true
    privateAttrs[kSecAttrApplicationTag] = privateKeyTag
    
    publicAttrs[kSecAttrIsPermanent] = true
    publicAttrs[kSecAttrApplicationTag] = publicKeyTag
    
    pairAttrs[kSecAttrKeyType] = kSecAttrKeyTypeRSA
    pairAttrs[kSecAttrKeySizeInBits] = 2048
    pairAttrs[(kSecPrivateKeyAttrs.takeUnretainedValue() as! String)] = privateAttrs
    pairAttrs[(kSecPublicKeyAttrs.takeUnretainedValue() as! String)] = publicAttrs
    
    var publicKeyPtr = Unmanaged?()
    var privateKeyPtr = Unmanaged?()
    
    let status = SecKeyGeneratePair(pairAttrs, &publicKeyPtr, &privateKeyPtr)
    

    Note: publicKeyTag and privateKeyTag are strings used to identify the key in the keystore. Apple recommends reverse-dns notation (com.company.key.xxx), but as long as they are unique, all should be good.

提交回复
热议问题