Вы можете создать сертификат с Security.framework
. Вам нужно вручную добавить к нему заголовок x509.
Фрагменты, которые я опубликую ниже, являются упрощенными примерами. Убедитесь, что вы ответственно относитесь к nil
значениям.
Следующий код сгенерирует сертификат:
func obtainKeyData(_ tag: String) -> Data {
var keyRef: AnyObject?
let query: Dictionary<String, AnyObject> = [
String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
String(kSecReturnData): kCFBooleanTrue as CFBoolean,
String(kSecClass): kSecClassKey as CFString,
String(kSecAttrApplicationTag): tag as CFString,
]
switch SecItemCopyMatching(query as CFDictionary, &keyRef) {
case noErr:
return keyRef as! Data
default:
fatalError("Error")
}
}
Теперь вам необходимо добавить к нему заголовок x509. Вы можете сделать с категорией Data
:
extension Data {
public func dataByPrependingX509Header() -> Data {
let result = NSMutableData()
let encodingLength: Int = (self.count + 1).encodedOctets().count
let OID: [CUnsignedChar] = [0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00]
var builder: [CUnsignedChar] = []
// ASN.1 SEQUENCE
builder.append(0x30)
// Overall size, made of OID + bitstring encoding + actual key
let size = OID.count + 2 + encodingLength + self.count
let encodedSize = size.encodedOctets()
builder.append(contentsOf: encodedSize)
result.append(builder, length: builder.count)
result.append(OID, length: OID.count)
builder.removeAll(keepingCapacity: false)
builder.append(0x03)
builder.append(contentsOf: (self.count + 1).encodedOctets())
builder.append(0x00)
result.append(builder, length: builder.count)
// Actual key bytes
result.append(self)
return result as Data
}
}
Наконец, объедините их вместе для создания сертификатов в формате x509:
let x509Key = obtainKeyData(keyTag).dataByPrependingX509Header()
Для справки, я получил этот код от проект Heimdall , оболочка фреймворка Security
для Swift, и в настоящее время он используется в частном приложении.