Search code examples
node.jscertificatedigital-signatureprivate-keypassbook

Is it possible to sign a Passbook manifest using node.js and crypto?


I'm trying to figure out how to sign an iOS Passbook pass manifest.json using node.js and crypto. It seems like it should be possible but I can't seem to create a proper signature.

Here's is what I've tried:

var crypto = require("crypto");
var fs = require('fs');

var manifest = fs.readFileSync('manifest.json');
var pem = fs.readFileSync('passbookdemo.pem');
var key = pem.toString('ascii');

var sign = crypto.createSign('RSA-SHA256');
sign.update(manifest);
var sig = sign.sign(key);

fs.writeFileSync('signature');

I generated the passbookdemo.pem earlier using:

openssl pkcs12 -in passbookdemo.p12 -out passbookdemo.pem -nodes

There is no passphrase associated with passbookdemo.pem.

One possible problem I can see is that I'm not incorporating the Apple developer relations certificate during the signing process, which I believe is a requirement.

Another possibility is that I'm using the incorrect argument in crypto.createSign('RSA-SHA256');. I'm not sure what I should use instead.

Here's a sample of ruby code that Apple supplied that I was able to use to sign the manifest correctly.

def sign_manifest
    puts "Signing the manifest"
    # Import the certificates
    p12_certificate = OpenSSL::PKCS12::new(File.read(self.certificate_url), self.certificate_password)
    wwdr_certificate = OpenSSL::X509::Certificate.new(File.read(self.wwdr_intermediate_certificate_path))

    # Sign the data
    flag = OpenSSL::PKCS7::BINARY|OpenSSL::PKCS7::DETACHED
    signed = OpenSSL::PKCS7::sign(p12_certificate.certificate, p12_certificate.key, File.read(self.manifest_url), [wwdr_certificate], flag)

    # Create an output path for the signed data
    self.signature_url = self.temporary_path + "/signature"

    # Write out the data
    File.open(self.signature_url, "w") do |f|
        f.syswrite signed.to_der
    end
end

Some related resources:


Solution

  • I know it's been five years since this was written but I came across it and thought it deserved an answer. Yes it is possible. Here is an example script that calls openssl from node.