APN-Node: Error when loading PEM file

2019-08-18 02:01发布

I am trying to get apn-node to push to my devices. The server is hosted on Heroku, so I do not want to commit the file. Also, I do not want to fetch it from a remote server but instead put it in an environment variable.

I already tried the following (source):
I created and downloaded the certificate from Apple and now have it in my Keychain. I exported it as a *.p12 file and converted it with openssl pkcs12 -in dev.p12 -out dev.pem -nodes into a *.pem file.

To set the environment variable, I did export APN_CERT="$(cat dev.pem)". When I print it out in my application it shows the certificate perfectly fine. However, when I actually send a notification (and node-apn opens the connection) it throws an [Error: wrong tag].
This error is emitted by the crypto module:

apn Raising error: +4ms [Error: wrong tag] undefined undefined
 apn Error occurred with trace: +1ms Error: wrong tag
  at Object.exports.createCredentials (crypto.js:176:17)
  at Object.exports.connect (tls.js:1344:27)
  at apnSocketLegacy

The module also throws a APN transmission error: moduleInitialisationFailed (Code: 513).

I was unable to find any useful information other than that this could be related to the crypto module itself of node itself. That's why I suspect I did something wrong when creating the certificate but thankful for any guiding advice.

2条回答
成全新的幸福
2楼-- · 2019-08-18 03:02

The preference here would be to use an encrypted p12 stored alongside the applciation and specify a passphrase which you set via an environment variable.

I was unable to replicate your problem using the following script

var apn = require("apn");

var token = "<token>; // iPad

var service = new apn.connection({
    cert: process.env.APN_CERT, key: process.env.APN_KEY
});

service.on("connected", function() {
    console.log("Connected");
});

service.on("error", function(err) {
    console.log("Standard error", err);
});

function pushNotification() {
    var note = new apn.notification().setAlertText("Hello");

    service.pushNotification(note, token);
    service.shutdown();
}

pushNotification();

Run with:

$ export APN_CERT=$(cat certificates/cert.pem)
$ export APN_KEY=$(cat certificates/key.pem)
$ node apn-env.js

The error you are seeing "wrong tag" is from OpenSSL and suggests a parsing error of the data contained within the certificate data itself rather than the data being loaded incorrectly from the env. Loading PEM files from environment variables works correctly

查看更多
该账号已被封号
3楼-- · 2019-08-18 03:03

I found this guide for apns-sharp which actually described how to generate a valid .p12 file.

Still, writing it into an environment variable did not work. My code for reading it is: new Buffer(certString, 'binary') but I thought it still was not supplied in a correct format.

The solution for me was to actually read the buffer directly from a file via fs.readFileSync.


To get the env variable to work you could encode the file via cat cert.p12 | base64 and load it as such with new Buffer(certString, 'base64'). This finally worked for me.

查看更多
登录 后发表回答