0

J'essaie d'atteindre Multipeer Connectivité sécurité des communications grâce à l'authentification des clients en utilisant X509 certificat. Pour ce faire, je génère les certificats clients sur mon serveur à l'aide de node-forge. Tout d'abord, le X509 est créé, puis il est transformé en une chaîne PKCS12 base64 qui est renvoyée au client.Comment créer un PKCS12 compatible avec Multipeer Connectivity d'iOS avec node-forge?

C'est essentiellement le code que je utilise:

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 : "[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); 

Cependant, quand je l'importer dans mon application iOS, l'exécution se bloque en me disant qu'il n'a pas lu le contenu des PKCS # 12 (différents erreur de l'erreur de mauvais mot de passe si) en retournant errSecDecode.

Je ne sais pas quelle partie de mon code provoque cette erreur même si je suspecte que les extensions soient à l'origine de ces problèmes, d'ailleurs je ne sais pas vraiment ce qui convient le mieux à mon utilisation (deux clients s'authentifiant l'un pour l'autre afin de communiquer avec MultiPeer Connectivity).

Je voudrais aussi savoir si je fais quelque chose de mal quand j'encode mes PKCS # 12 à une chaîne base64?

Si elle aide, voici le code que je utilise pour importer les PKCS # 12 dans le côté iOS après avoir récupéré la chaîne base64 du serveur.

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) 
} 

Nous vous remercions à l'avance

modifier: En décodant la chaîne base64 avec nœud forge, je peux voir les infos je suis entré lorsque le certificat a été créé, ils sont bien imprimés sans mal aussi caractère rendu.

Maintenant, je me demande si iOS lance intentionnellement cette erreur pour me garder d'utiliser des certificats qui ne sont pas créés avec leur outil spécifique (Apple Keychain si je me souviens bien).

Répondre

0

Apparemment, le cadre de sécurité d'iOS exige que le PKCS # 12 utilise l'algorithme de chiffrement TripleDES.

Ainsi, en remplaçant la ligne:

var p12Asn1 = forge.pkcs12.toPkcs12Asn1(keys.privateKey , cert, "iPhone"); 

avec:

var p12Asn1 = forge.pkcs12.toPkcs12Asn1(keys.privateKey , cert, "iPhone", {algorithm : '3des'}); 

fonctionne comme un charme. À ce stade, je ne comprends toujours pas pourquoi la documentation d'Apple est si inépuisable sur le sujet: /.