我正在尝试使用TCP SSL连接openssl s_server
和iOS客户端,但获取CFNetwork SSLHandshake failed (-9807)
。
Objective-C代码(from here):
- (void)viewDidLoad {
[super viewDidLoad];
printf("method started \n");
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSData *iosTrustedCertDerData =
[NSData dataWithContentsOfFile:[bundle pathForResource:@"servercert"
ofType:@"der"]];
OSStatus err = noErr;
SecCertificateRef cert;
cert = SecCertificateCreateWithData(NULL, (CFDataRef) iosTrustedCertDerData);
assert(cert != NULL);
CFTypeRef result;
NSDictionary* dict = [NSDictionary dictionaryWithObjectsAndKeys:
(id)kSecClassCertificate, kSecClass,
cert, kSecValueRef,
nil];
err = SecItemAdd((CFDictionaryRef)dict, &result);
assert(err == noErr || err == errSecDuplicateItem);
printf("adding finished \n");
if ((err == noErr) ||
(err == errSecDuplicateItem)) {
printf("success \n");
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL,
(CFStringRef)@"localhost",
1678,
&readStream,
&writeStream);
CFReadStreamSetProperty(readStream,
kCFStreamPropertySocketSecurityLevel,
kCFStreamSocketSecurityLevelTLSv1);
CFReadStreamOpen(readStream);
CFWriteStreamOpen(writeStream);
UInt8 buf[] = "Hello from iOS";
int bytesWritten = CFWriteStreamWrite(writeStream, buf, strlen((char*)buf));
} else {
printf("error!");
}
CFRelease(cert);
}
创建证书并启动服务器的命令序列(请注意11步:在服务器端我使用pem证书,在客户端使用我的证书),我得到的文件样本this answer
1。touch openssl-ca.cnf
2.在openssl-ca.cnf中粘贴样本。只有一行改变了:
commonName_default = localhost
3。openssl req -x509 -config openssl-ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM
4。touch openssl-server.cnf
5.在openssl-server.cnf中粘贴样本。只改变了两行:
commonName_default = localhost
DNS.1 = localhost
6。openssl req -config openssl-server.cnf -newkey rsa:2048 -sha256 -nodes -out servercert.csr -outform PEM
7.在openssl-ca.cnf中增加了2 + 1个部分:
[ CA_default ]
...
base_dir = .
certificate = $base_dir/cacert.pem # The CA certifcate
private_key = $base_dir/cakey.pem # The CA private key
new_certs_dir = $base_dir # Location for new certs after signing
database = $base_dir/index.txt # Database index file
serial = $base_dir/serial.txt # The current serial number
unique_subject = no # Set to 'no' to allow creation of
# several certificates with same subject.
...
####################################################################
[ signing_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ signing_req ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
8。touch index.txt
9。echo '01' > serial.txt
10。openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out servercert.pem -infiles servercert.csr
11。openssl x509 -in servercert.pem -inform PEM -out servercert.der -outform DER
12.在iOS项目中添加了servercert.der
13。let sslsock = SSLSocketLite(inHost: "localhost", inPort: 1678)
14.Exception Domains - > + localhost
15。openssl s_server -key serverkey.pem -cert servercert.pem -accept 1678
openssl-ca.cnf
的最终版本:
HOME = .
RANDFILE = $ENV::HOME/.rnd
####################################################################
[ ca ]
default_ca = CA_default # The default ca section
[ CA_default ]
default_days = 1000 # how long to certify for
default_crl_days= 30 # how long before next CRL
default_md = sha256 # use public key default MD
preserve = no # keep passed DN ordering
x509_extensions = ca_extensions # The extensions to add to the cert
email_in_dn = no # Don't concat the email in the DN
copy_extensions = copy # Required to copy SANs from CSR to cert
base_dir = .
certificate = $base_dir/cacert.pem # The CA certifcate
private_key = $base_dir/cakey.pem # The CA private key
new_certs_dir = $base_dir # Location for new certs after signing
database = $base_dir/index.txt # Database index file
serial = $base_dir/serial.txt # The current serial number
unique_subject = no # Set to 'no' to allow creation of
# several certificates with same subject.
####################################################################
[ req ]
default_bits = 4096
default_keyfile = cakey.pem
distinguished_name = ca_distinguished_name
x509_extensions = ca_extensions
string_mask = utf8only
####################################################################
[ ca_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = Maryland
localityName = Locality Name (eg, city)
localityName_default = Baltimore
organizationName = Organization Name (eg, company)
organizationName_default = Test CA, Limited
organizationalUnitName = Organizational Unit (eg, division)
organizationalUnitName_default = Server Research Department
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = localhost
emailAddress = Email Address
emailAddress_default = test@example.com
####################################################################
[ ca_extensions ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid:always, issuer
basicConstraints = critical, CA:true
keyUsage = keyCertSign, cRLSign
####################################################################
[ signing_policy ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ signing_req ]
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
openssl-server.cnf的最终版本:
HOME = .
RANDFILE = $ENV::HOME/.rnd
####################################################################
[ req ]
default_bits = 2048
default_keyfile = serverkey.pem
distinguished_name = server_distinguished_name
req_extensions = server_req_extensions
string_mask = utf8only
####################################################################
[ server_distinguished_name ]
countryName = Country Name (2 letter code)
countryName_default = US
stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = MD
localityName = Locality Name (eg, city)
localityName_default = Baltimore
organizationName = Organization Name (eg, company)
organizationName_default = Test CA, Limited
commonName = Common Name (e.g. server FQDN or YOUR name)
commonName_default = localhost
emailAddress = Email Address
emailAddress_default = test@example.com
####################################################################
[ server_req_extensions ]
subjectKeyIdentifier = hash
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
subjectAltName = @alternate_names
nsComment = "OpenSSL Generated Certificate"
####################################################################
[ alternate_names ]
DNS.1 = localhost
iOS输出:
方法开始了 添加完成 成功
2016-08-30 19:17:06.619 ssltest [5418:141544] CFNetwork SSLHandshake失败(-9807)
OpenSSL s_server输出(没有发生):
使用默认的临时DH参数
ACCEPT
我错过了什么?我该如何解决?
也许有人可以与localhost
中的commonName
地址共享工作证书?使用此功能,我将了解问题究竟是什么:cert和我的pem
到der
转换或iOS应用。