InitCrypto 失败 - 无法在 Unity Smartfox 客户端中启用 SSL
InitCrypto fails - unable to enable SSL in Unity Smartfox client
我使用的代码是 SFS 的 Unity 示例代码——也就是说,只是概念验证。服务器是SFS 2.13.0.
这是我做过的事情。
- 在区域配置中启用加密(
true )。
- 最初使用 Let's Encrypt 证书,后来使用 Certum 的证书。
- 证书被导入 JKS 密钥库并放置在 lib/jetty/etc 中。 lib/jetty/start.d/ssl.ini 相应更新并重新启动服务器。
SFS 启动后,我可以连接 openssl 命令行工具并查看证书。
我正在尝试使用示例客户端 (Connector.cs) 从 Unity 登录。如果我禁用加密,它就可以正常工作。我添加监听器的那一刻,它失败了。
首先是事件监听器:
if (useEncryption) {
sfs.AddEventListener (SFSEvent.CRYPTO_INIT, OnCryptoInit);
}
然后从OnConnection触发事件:
if (useEncryption) {
trace("Initializing Crypto");
StartCoroutine(sfs.InitCrypto ());
} else {
enableInterface ("LOGIN");
uiState = 2;
}
OnCryptoInit 方法如下所示:
private void OnCryptoInit(BaseEvent evt) {
trace("Crypto Initialized?");
if ((bool) evt.Params["success"]) {
trace("....YES!");
enableInterface ("LOGIN");
uiState = 2;
} else {
trace("Encryption initialization failed: " + (string)evt.Params["errorMessage"]);
}
}
当我运行这个时,我总是得到(不管证书如何):
Encryption initialization failed: Unknown Error
这不是很有帮助。
Wireshark 转储向我显示了客户端问候、服务器问候和握手失败。我在 Smartfox 端(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)只启用了一个密码,但我可以在客户端发送的密码列表(其中 85 个)中看到它,所以我不认为这是因为无法协商可接受的密码。
我最初的尝试是在 Smartfox 端使用 Let's Encrypt 证书。后来我从 Certum 购买了一个(Certum Domain Validation CA SHA2 是发行者)。我无法验证我的 Unity 安装是否具有验证这些证书所需的中间体。
如何找出 SSL 失败的原因?
Unity 是否希望所有中间证书都在其自己的证书存储中?
Unity 的证书存储在哪里?如何检查是否存在所有根证书?
关于如何进一步调试这个问题有什么建议吗?
对于那些可能遇到类似问题的人:我在 SFS 支持的帮助下解决了这个问题。简而言之,问题在于密钥库需要一个别名下的所有证书和密钥。我有一个在不同别名下列出的中间证书(用于生成密钥库导入的中间证书的脚本,其 CN 的散列版本作为别名),因此没有提供它们。这导致客户端的证书链验证不完整 - 一个未准确报告给应用程序代码的错误。
生成密钥库的正确命令序列是:
CN=my.domain.tld
cat $CN.pem IntermediateCert1.pem IntermediateCert2.pem > $CN-chain.pem
openssl pkcs12 -export -in $CN-chain.pem -inkey $CN.key -name $CN -out $CN.p12
keytool -importkeystore -deststorepass xxxxxx -destkeystore $CN.keystore -srckeystore $CN.p12 -srcstoretype PKCS12
这确保最终证书、其私钥和所有中间证书都列在密钥库中的单个别名下。
我使用的代码是 SFS 的 Unity 示例代码——也就是说,只是概念验证。服务器是SFS 2.13.0.
这是我做过的事情。
- 在区域配置中启用加密(
true )。 - 最初使用 Let's Encrypt 证书,后来使用 Certum 的证书。
- 证书被导入 JKS 密钥库并放置在 lib/jetty/etc 中。 lib/jetty/start.d/ssl.ini 相应更新并重新启动服务器。
SFS 启动后,我可以连接 openssl 命令行工具并查看证书。
我正在尝试使用示例客户端 (Connector.cs) 从 Unity 登录。如果我禁用加密,它就可以正常工作。我添加监听器的那一刻,它失败了。
首先是事件监听器:
if (useEncryption) {
sfs.AddEventListener (SFSEvent.CRYPTO_INIT, OnCryptoInit);
}
然后从OnConnection触发事件:
if (useEncryption) {
trace("Initializing Crypto");
StartCoroutine(sfs.InitCrypto ());
} else {
enableInterface ("LOGIN");
uiState = 2;
}
OnCryptoInit 方法如下所示:
private void OnCryptoInit(BaseEvent evt) {
trace("Crypto Initialized?");
if ((bool) evt.Params["success"]) {
trace("....YES!");
enableInterface ("LOGIN");
uiState = 2;
} else {
trace("Encryption initialization failed: " + (string)evt.Params["errorMessage"]);
}
}
当我运行这个时,我总是得到(不管证书如何):
Encryption initialization failed: Unknown Error
这不是很有帮助。
Wireshark 转储向我显示了客户端问候、服务器问候和握手失败。我在 Smartfox 端(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256)只启用了一个密码,但我可以在客户端发送的密码列表(其中 85 个)中看到它,所以我不认为这是因为无法协商可接受的密码。
我最初的尝试是在 Smartfox 端使用 Let's Encrypt 证书。后来我从 Certum 购买了一个(Certum Domain Validation CA SHA2 是发行者)。我无法验证我的 Unity 安装是否具有验证这些证书所需的中间体。
如何找出 SSL 失败的原因?
Unity 是否希望所有中间证书都在其自己的证书存储中?
Unity 的证书存储在哪里?如何检查是否存在所有根证书?
关于如何进一步调试这个问题有什么建议吗?
对于那些可能遇到类似问题的人:我在 SFS 支持的帮助下解决了这个问题。简而言之,问题在于密钥库需要一个别名下的所有证书和密钥。我有一个在不同别名下列出的中间证书(用于生成密钥库导入的中间证书的脚本,其 CN 的散列版本作为别名),因此没有提供它们。这导致客户端的证书链验证不完整 - 一个未准确报告给应用程序代码的错误。
生成密钥库的正确命令序列是:
CN=my.domain.tld
cat $CN.pem IntermediateCert1.pem IntermediateCert2.pem > $CN-chain.pem
openssl pkcs12 -export -in $CN-chain.pem -inkey $CN.key -name $CN -out $CN.p12
keytool -importkeystore -deststorepass xxxxxx -destkeystore $CN.keystore -srckeystore $CN.p12 -srcstoretype PKCS12
这确保最终证书、其私钥和所有中间证书都列在密钥库中的单个别名下。