Safari推送通知-推送包的签名验证失败

时间:2019-06-12 09:29:52

标签: node.js safari apple-push-notifications

我已经花了一个星期的时间,试图在MacOS上获得Safari推送通知。我已经按照此处列出的步骤进行操作:https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/NotificationProgrammingGuideForWebsites/PushNotifications/PushNotifications.html#//apple_ref/doc/uid/TP40013225-CH3-SW24和此处:https://medium.com/@rossbulat/safari-push-notifications-complete-setup-ef57f19bbb89,实现了为zip包和日志记录终结点提供服务的终结点,但是我不断收到错误消息“推送包的签名验证失败”。 / p>

我正在使用nodejs创建zip包并签署清单文件。

执行此操作的代码:

const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const child_process = require('child_process');
const rimraf = require('rimraf');

const archiver = require('archiver');
const websiteName = 'mywebsite.com';
const websiteFolder = 'mywebsite.com';
const websitePushID = 'web.com.mywebsite';
const allowedDomains = [
  'https://www.mywebsite.nl',
  'https://www.mywebsite.com'
];
const webServiceURL = 'https://api.mywebsite.com';
const urlFormatString = 'https://www.mywebsite.com/%@';
const authenticationToken = '3F2UyWU8VfJ6EHGZqd5TMteQ';
const certP12 = '../cert/certificate.p12';
const wwdrca = '../cert/AppleWWDRCA.pem';
const certPasswd = 'my password'; //p12 password

const raw_files = [
  'website.json',
  'icon.iconset/icon_16x16.png',
  'icon.iconset/icon_16x16@2x.png',
  'icon.iconset/icon_32x32.png',
  'icon.iconset/icon_32x32@2x.png',
  'icon.iconset/icon_128x128.png',
  'icon.iconset/icon_128x128@2x.png'
];

const website = {
  websiteName,
  websitePushID,
  allowedDomains,
  urlFormatString,
  authenticationToken,
  webServiceURL
};
const manifest = {};

const createZip = () => {
  return new Promise((resolve, reject) => {
    const basePath = `${__dirname}/${websiteFolder}.pushpackage`;
    console.log('website.json', `${basePath}/website.json`);

    fs.writeFileSync(`${basePath}/website.json`, JSON.stringify(website));
    console.log('manifest.json');

    raw_files.forEach(file => {
      const sha512 = crypto.createHash('sha512');
      sha512.update(fs.readFileSync(`${basePath}/${file}`), 'binary');
      manifest[file] = {
        hashType: 'sha512',
        hashValue: sha512.digest('hex')
      };

    });

    fs.writeFileSync(`${basePath}/manifest.json`, JSON.stringify(manifest));
    child_process.execSync(`openssl pkcs12 -in ${path.join(__dirname, certP12)} -nocerts -out private.pem -passin pass:${certPasswd} -passout pass:${certPasswd}`);
    child_process.execSync(`openssl pkcs12 -in ${path.join(__dirname, certP12)} -clcerts -nokeys -out cert.pem -passin pass:${certPasswd}`);

    child_process.execSync(`openssl smime -binary -sign -certfile ${path.join(__dirname, wwdrca)} -signer ${path.join(__dirname, '../cert', 'certificate.pem')} -inkey private.pem -in ${basePath}/manifest.json -out ${basePath}/signature -outform DER -passin pass:${certPasswd}`);

    raw_files.push('manifest.json');

    raw_files.push('signature');
    if(fs.existsSync(`${basePath}.zip`)) {
      fs.unlinkSync(`${basePath}.zip`);

    }

    const archive = archiver('zip');
    const output = fs.createWriteStream(`${basePath}.zip`);

    archive.pipe(output);

    console.log('building Package');

    raw_files.forEach(file => archive.append(fs.createReadStream(`${basePath}/${file}`), {name: file}));

    archive.on('finish', () => {
      console.log('finished');
      return resolve();
    });

    console.log('finalize');

    archive.finalize((err, bytes) => {
      if(err) {
        throw err;
      }

      console.log(`${bytes} total bytes`);

      fs.unlink('cert.pem');
      fs.unlink('private.pem');
      rimraf.sync(basePath);
    });

  });
};

module.exports = createZip;

由于签名验证失败,因此问题可能出在此行:

child_process.execSync(`openssl smime -binary -sign -certfile ${path.join(__dirname, wwdrca)} -signer ${path.join(__dirname, '../cert', 'certificate.pem')} -inkey private.pem -in ${basePath}/manifest.json -out ${basePath}/signature -outform DER -passin pass:${certPasswd}`);

对于-signer参数,我首先使用cert.pem,它是在上一行中生成的:

child_process.execSync(`openssl pkcs12 -in ${path.join(__dirname, certP12)} -clcerts -nokeys -out cert.pem -passin pass:${certPasswd}`);

但是我认为这应该是我使用以下命令从certificate.pem文件生成的certificate.p12文件:

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

但是,这不能解决问题。 我几次按照步骤获得正确的证书,我敢肯定我做得正确,但是我对证书专家的了解还很遥远,所以也许我在这里做错了。 也许有人可以验证上面的代码以查看其是否正确。

任何帮助都将不胜感激,因为我的头几乎没有任何头发可以拔出来……谢谢!

0 个答案:

没有答案