【问题标题】:How to create a PKCS12 compatible with iOS's Multipeer Connectivity with node-forge?如何使用 node-forge 创建与 iOS 的 Multipeer Connectivity 兼容的 PKCS12?
【发布时间】:2016-11-28 19:05:23
【问题描述】:

我正在尝试通过使用 X509 证书的客户端身份验证来实现 Multipeer Connectivity 通信安全。

为此,我使用 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 : "hello@world.com"
} ];

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 : "hello@world.com"
} ];
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); 

但是,当我在我的 iOS 应用程序中导入它时,运行时不断崩溃,通过返回 errSecDecode

我不知道我的代码的哪一部分导致了这个错误,即使我怀疑 extensions 是这些问题的根源,顺便说一下我真的不知道什么适合最适合我的用例(两个客户端相互验证自己以与 MultiPeer Connectivity 进行通信)。

我还想知道当我将 PKCS#12 编码为 base64 字符串 时是否做错了什么?

如果有帮助,这是我在从服务器恢复 base64 字符串后在 iOS 端导入 PKCS#12 的代码。 p>

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

提前谢谢你

编辑: 通过使用 node-forge 解码 base64 字符串,我可以看到我在创建证书时输入的信息,而且它们打印得很好,没有呈现不佳的字符。

现在我问自己 iOS 是否故意抛出此错误以阻止我使用不是使用其特定工具创建的证书(如果我记得清楚的话,Apple Keychain)。

【问题讨论】:

    标签: node.js swift x509certificate multipeer-connectivity pkcs#12


    【解决方案1】:

    显然,iOS 的安全框架要求 PKCS#12 使用 TripleDES 加密算法。

    所以,换行:

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

    与:

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

    像魅力一样工作。

    在这一点上,我仍然不明白为什么 Apple 的文档在这个主题上如此详尽:/。

    【讨论】:

      猜你喜欢
      • 2013-10-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-10
      • 1970-01-01
      • 2016-01-24
      • 1970-01-01
      相关资源
      最近更新 更多