[英]SSL connection on iOS error
我有一個使用 OpenSSL 用 C++ 編寫的服務器。 我使用的客戶端適用於 iOS。 我在 iOS 上使用 SSL 的安全框架。 為了連接到服務器,我就是這樣做的。
創建 SSL 上下文
創建套接字並連接到服務器
設置證書
與服務器握手
SSLHandshake 返回 -9807 錯誤無效證書鏈,在服務器端,服務器仍然等待 SSL_Accept。
這是代碼
-(int)SSLInitClientSocket
{
@try
{
UINT uitimeout = 40 ;
int inret = 1,err=-1;
int verify_client = 1;
m_sslCTX= SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
if (!m_sslCTX)
{
//ERR_print_errors_fp(stderr);
printf("\n ERROR in SSL_CTX_new \n");
return OS_SOCK_ERROR;
}
//Socket is created using socket() function
if ( OS_SockCreate(&listenerSocket, OS_TCP_SOCK, FALSE) != OS_SOCK_OK)
{
CFRelease(m_sslCTX);
//SSL_CTX_free(m_sslCTX);
m_sslCTX = NULL;
return OS_SOCK_ERROR;
}
fcntl(listenerSocket, F_SETFD, O_NONBLOCK);
/* Setting the socket to ignore Nagle Algorithm */
OS_SockSetOpt(listenerSocket, TCP_OPT_NODELAY, &inret);
/* Set Timeout for send and recv */
OS_SockSetOpt(listenerSocket, TCP_OPT_RCVTIMEOUT, &uitimeout);
OS_SockSetOpt(listenerSocket, TCP_OPT_SNDTIMEOUT, &uitimeout);
OS_SockInfo sockinfo;
strcpy(sockinfo.strName,"172.16.30.209");
sockinfo.usPort = 5212;
//connected using connect
if(OS_SockConnect(listenerSocket, &sockinfo) != OS_SOCK_OK)
{
printf("ERROR :: OS_SockConnect \n");
return OS_SOCK_ERROR;
}
OSStatus osstatus;
osstatus = SSLSetIOFuncs(m_sslCTX, readFromSocket,writeToSocket);
if(osstatus) {
return OS_SOCK_ERROR;
}
//connectionRef = (SSLConnectionRef)listenerSocket;
err=SSLSetConnection(m_sslCTX,(SSLConnectionRef)listenerSocket);
if ((err)==-1)
{
return OS_SOCK_ERROR;
}
SSLSessionState state;
SSLGetSessionState(m_sslCTX, &state);
osstatus = SSLSetProtocolVersionMin(m_sslCTX,kTLSProtocol1);
//Set certificates
if(verify_client == 1)
{
CFArrayRef arrcert = CFArrayCreate(NULL, 0, 0, NULL);
NSData *certData = [[NSData alloc]
initWithContentsOfFile:@"/Users/xyz/Desktop/cert/client.p12"];
CFDataRef myCertData = (CFDataRef)certData;
const void *keys[] = { kSecImportExportPassphrase};
const void *values[] = { CFSTR("password")};
CFDictionaryRef options = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, NULL, NULL);
SecPKCS12Import(myCertData, options, &arrcert);
CFRelease(options);
CFDictionaryRef item = CFArrayGetValueAtIndex(arrcert, 0);
SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(item, kSecImportItemIdentity);
CFArrayRef certs = CFArrayCreate(kCFAllocatorDefault, (const void **)&identity, 1, NULL);
err=SSLSetCertificate(m_sslCTX,certs);
}
SSLGetSessionState(m_sslCTX, &state); //Here Session state is Idle
do
{
err = SSLHandshake(m_sslCTX);
} while (err == errSSLWouldBlock);
SSLGetSessionState(m_sslCTX, &state); //here session state is idle and the server is still blocked on SSL_Accept
return OS_SOCK_OK;
}
@catch(...)
{
return OS_SOCK_ERROR;
}
}
我的服務器代碼與 c++ 和 java 客戶端完美配合。 我不知道我錯過了什么。
在 iOS 中使用自簽名 SSL 證書可以通過一種解決方法來完成,但強烈建議不要這樣做,而是使用受信任的證書。 此外,Apple 可能會拒絕使用自簽名證書的應用程序。
這個問題是: NSOSStatusErrorDomain errSSLXCertChainInvalid
如果您使用的是OpenSSL
您可以嘗試:
$ openssl s_client -connect www.apple.com:443
openssl s_client -showcerts -host www.apple.com -port 443
您可以在此處獲得更多參考: https : //developer.apple.com/library/ios/technotes/tn2232/_index.html https://developer.apple.com/library/mac/navigation/index.html#topic =示例+代碼&部分=資源+類型
我希望它可以幫助
為舊線程帶來生命!
我假設您使用的代碼用於研究或學術工作。
由於您使用的是自簽名證書,因此您只需將其添加到 iPhone 上的受信任證書中,然后嘗試連接即可。 它應該工作。 但是,此方法僅用於研究,不應用於您希望發布到應用商店的任何內容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.