我正在努力實現Multipeer Connectivity通過客戶端認證使用的通信安全X509證書。如何使用node-forge創建兼容iOS Multipeer連接的PKCS12?
爲此,我使用node-forge在我的服務器中生成客戶端證書。首先,創建X509,然後將其轉換爲返回給客戶端的PKCS12 base64字符串。
這基本上是我使用的代碼:
var username = "client1"
// Create key pair
var pki = forge.pki;
var keys = pki.rsa.generateKeyPair(2048);
var cert = pki.createCertificate();
// Creating the certificate
cert.publicKey = keys.publicKey;
cert.serialNumber = '01'; // TODO : generate random number and have a little custom algo to verify it !!
cert.validity.notBefore = new Date();
cert.validity.notAfter = new Date();
cert.validity.notAfter.setTime(cert.validity.notBefore.getTime() + msWeek);
var subject = [{
name : "commonName",
value : username
}, {
name : "organizationName",
value : "My Company"
}, {
name : "organizationalUnitName",
value : "MU"
}, {
name : "stateOrProvinceName",
value : "Ile-de-France"
}, {
name : "countryName",
value : "FR"
}, {
name : "localityName",
value : "Paris"
}, {
name : "emailAddress",
value : "hel[email protected]"
} ];
var issuer = [{
name : "commonName",
value : "MPC App"
}, {
name : "organizationName",
value : "My Company"
}, {
name : "organizationalUnitName",
value : "MU"
}, {
name : "stateOrProvinceName",
value : "Ile-de-France"
}, {
name : "countryName",
value : "FR"
}, {
name : "localityName",
value : "Paris"
}, {
name : "emailAddress",
value : "[email protected]"
} ];
cert.setSubject(subject);
cert.setIssuer(issuer);
// Extensions
cert.setExtensions([{
name: 'basicConstraints',
cA : true
} , {
name : 'keyUsage',
digitalSignature : true,
keyCertSign : true,
nonRepudiation : true,
keyEncipherment : true,
dataEncipherment : true
}, {
name : 'extKeyUsage',
clientAuth : true,
serverAuth : false,
codeSigning : true,
emailProtection : false,
timeStamping : true
}, {
name : 'nsCertType',
client : true,
server : false,
email : false,
objsign : true,
sslCA : false,
emailCA : false,
objCA : false
}]);
cert.sign(keys.privateKey);
var asn1Cert = pki.certificateToAsn1(cert);
// Create PKCS#12 from the certificate and encode to base64 string
var p12Asn1 = forge.pkcs12.toPkcs12Asn1(keys.privateKey , cert, "iPhone");
var p12Der = forge.asn1.toDer(p12Asn1).getBytes();
return forge.util.encode64(p12Der);
然而,當我導入它在我的iPhone應用程序,運行時將崩潰告訴我它無法讀取PKCS#12的內容(不同錯誤密碼錯誤雖然)通過返回errSecDecode。
即使我懷疑擴展是這些問題的根源,我不知道我的代碼的哪個部分導致了此錯誤,但我不太清楚什麼最適合我的用例(兩個客戶端互相驗證身份以便與MultiPeer Connectivity進行通信)。
我也想知道如果我做錯了什麼,當我編碼我PKCS#12到的base64字符串?
如果有幫助,這裏是我使用回收來自服務器以base64字符串之後導入的的iOS側PKCS#12的代碼。
private func generateIdentity (base64p12 : String, password : String?) {
print("gen id")
let p12KeyFileContent = NSData(base64EncodedString: base64p12, options: NSDataBase64DecodingOptions.IgnoreUnknownCharacters)
if (p12KeyFileContent == nil) {
NSLog("Cannot read PKCS12 data")
return
}
let options = [String(kSecImportExportPassphrase):password ?? ""]
var citems: CFArray? = nil
let resultPKCS12Import = withUnsafeMutablePointer(&citems) { citemsPtr in
SecPKCS12Import(p12KeyFileContent!, options, citemsPtr)
}
if (resultPKCS12Import != errSecSuccess) {
print("resultPKCS12Import :", resultPKCS12Import)
return
}
let items = citems! as NSArray
let myIdentityAndTrust = items.objectAtIndex(0) as! NSDictionary
let identityKey = String(kSecImportItemIdentity)
identity = myIdentityAndTrust[identityKey] as! SecIdentityRef
hasCertificate = true
print("cert cre", identity)
}
預先感謝您
編輯: 通過以base64字符串節點鍛解碼,我可以看到我輸入的時候創建的證書的相關信息,還他們印刷精美而不不佳呈現的字符。
現在我問自己,iOS是否故意拋出這個錯誤,以保留使用未使用特定工具創建的證書(Apple Keychain,如果我記得的話)。