首页 文章

Qt 5.8 Apple Notification Server握手失败

提问于
浏览
1

我现在尝试了一些,但我无法让它工作 . 我想从Qt应用程序中推送一些通知 . 尝试使用Qt 5.8安装在macOS Sierra上工作,在Pi3上使用Qt 5.8 .

我用“fastlane pem”创建了我的推送证书,我用“Pusher”进行了测试,它的工作正常 . 但我无法让它在Qt中工作....

首先是我用来初始化和连接QSslSocket的代码:

QSslSocket * ssl = new QSslSocket;

connect(ssl, &QSslSocket::encrypted, this, &IOSPusher::encrypted );
connect(ssl, static_cast<void(QSslSocket::*)(const QList<QSslError> &)>(&QSslSocket::sslErrors),this,&IOSPusher::sslErrors);
connect(ssl, static_cast<void(QSslSocket::*)(QAbstractSocket::SocketError)>(&QSslSocket::error),this, &IOSPusher::error );
connect(ssl,&QSslSocket::stateChanged,this,&IOSPusher::stateChanged );

加载证书

QString path = QStandardPaths::writableLocation(certificateLocation) + "/apns.pem";

const auto certs =  QSslCertificate::fromPath(path);

if(certs.count() > 0){
    qDebug() << "IOSPusher: Certificate loaded successfully";
}else{
    qDebug() << "Could not load certificate : " + path;
}

QSslConfiguration config = QSslConfiguration::defaultConfiguration();
config.setCaCertificates(certs);

ssl->setSslConfiguration(config);
ssl->connectToHostEncrypted( gateway.sandbox.push.apple.com,2195 );

这就是我得到的输出:

IOSPusher: Certificate loaded successfully
IOSPusher::stateChanged  QAbstractSocket::HostLookupState
IOSPusher::stateChanged  QAbstractSocket::ConnectingState
IOSPusher::stateChanged  QAbstractSocket::ConnectedState
IOSPusher::error  QAbstractSocket::SocketError(13)
IOSPusher::stateChanged  QAbstractSocket::ClosingState
IOSPusher::stateChanged  QAbstractSocket::UnconnectedState

所以根据Qt文档的错误:

QAbstractSocket :: SocketError(13)

表示以下内容:

SslHandshakeFailedError

SSL / TLS握手失败,无法 Build 加密通道 . 应该发出sslErrors()信号 .

But 在我的情况下不会发出 sslErrors() 信号....

SSL / TLS握手失败,因此连接已关闭(仅在QSslSocket中使用)

任何想法或样本如何 Build 与苹果的加密连接?

提前致谢!

1 回答

  • 0

    当我试图从现在得到它的任何人那里得到帮助的时候经常这样:D

    现在对我有用的解决方案是:

    使用带有密码的 fastlane pem 创建 *.pem 证书(也许它没有密码也能正常工作,但这是我现在尝试的最后一个......并且永远不会改变正在运行的系统哈哈)

    fastlane pem --development -p <private_key_password> -a <your_app_identifier>
    

    然后连接QSslSocket执行以下操作......就像我之前的问题一样......

    QSslSocket * ssl = new QSslSocket;
    QString path = QStandardPaths::writableLocation(certificateLocation) + "/apns.pem";
    
    connect(ssl, &QSslSocket::encrypted, this, &IOSPusher::encrypted );
    connect(ssl, static_cast<void(QSslSocket::*)(const QList<QSslError> &)>(&QSslSocket::sslErrors),this,&IOSPusher::sslErrors);
    connect(ssl, static_cast<void(QSslSocket::*)(QAbstractSocket::SocketError)>(&QSslSocket::error),this, &IOSPusher::error );
    connect(ssl,&QSslSocket::stateChanged,this,&IOSPusher::stateChanged );
    
    QSslCertificate cert;
    const auto certs =  QSslCertificate::fromPath(path);
    
    if(certs.count() > 0){
        cert = certs.at(0);
        qDebug() << "IOSPusher: Certificate loaded successfully";
    }else{
        qDebug() << "Could not load certificate : " + path;
        return false;
    }
    

    Now here comes the magic what it did for me

    使用private_key(.pkey)文件,该文件也将使用 fastlane pem 创建

    //Use the path to the .pkey file from fastlane
    QFile keyfile(path + "/apns.pkey");
    keyfile.open(QFile::ReadOnly);
    
    //Create the QSslKey as private key
    QSslKey privateKey(&keyfile,QSsl::Rsa,QSsl::Pem,QSsl::PrivateKey,QByteArray("<private_key_password_from_fastlane>"));
    //Close the file
    keyfile.close();
    

    并将私钥和证书添加到ssl配置中

    QSslConfiguration config = QSslConfiguration::defaultConfiguration();
    
    config.setLocalCertificate(cert);
    config.setPrivateKey(privateKey);
    

    正如你在这里看到的,这次我不使用 config.setCaCertificates 方法,而是使用 config.setLocalCertificate 方法 . 那是我身上的错误......

    至少将配置添加到ssl套接字和FIRE!

    ssl->setSslConfiguration(config);
    ssl->connectToHostEncrypted( "gateway.sandbox.push.apple.com",2195 );
    

    Thats all

    现在 encrypted() 信号被发射了!是啊..

相关问题