您好我现在正在疯狂地使用alamofire :)。 我想要做的是禁用评估,因为服务器没有有效的SSL证书,但我必须通过https连接,我必须通过OpenSSL发送在IOS设备上制作的x509证书 我目前正在使用alamofire 4而我正在尝试:
open class CertTrustPolicyManager: ServerTrustPolicyManager {
open override func serverTrustPolicy(forHost host: String) -> ServerTrustPolicy? {
let policy = ServerTrustPolicy.disableEvaluation;
// let policy = ServerTrustPolicy.pinCertificates(certificates: [certificateToPin], validateCertificateChain: true, validateHost: false);
// var policy = ServerTrustPolicy.pinCertificates(certificates: [certificateToPin], validateCertificateChain: false, validateHost: false);
return policy
}
let trustPolicies = CertTrustPolicyManager(policies: [:])
let alamofireManager:SessionManager = Alamofire.SessionManager(configuration: configuration, delegate: SessionDelegate(), serverTrustPolicyManager: trustPolicies)
也在尝试
var serverTrustPolicy:[String: ServerTrustPolicy] = [
Router.baseURLString : .pinCertificates(
certificates: [certificateToPin],
validateCertificateChain: false,
validateHost: false)
]
let alamofireManager:SessionManager = Alamofire.SessionManager(configuration: configuration, delegate: SessionDelegate(), serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicy))
第一种方法 let policy = ServerTrustPolicy.disableEvaluation; 给了我成功的联系,但后来我无法固定证书(或者我不知道如何)
第二种方法产生,上帝知道下一步:)
2017-05-10 08:37:13.801894+0200 App[10117:1120893] [] nw_coretls_callback_handshake_message_block_invoke_3 tls_handshake_continue: [-9812]
2017-05-10 08:37:13.802 App[10117:1120907] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
我甚至不知道我是否正确发送。
任何提示?
编辑这使我的连接很好,但我没有发送证书
alamofireManager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling
var credential: URLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = URLSession.AuthChallengeDisposition.useCredential
credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
} else {
if challenge.previousFailureCount > 0 {
disposition = .cancelAuthenticationChallenge
} else {
credential = alamofireManager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)
if credential != nil {
disposition = .useCredential
}
}
}
return (disposition, credential)
}
干杯
答案 0 :(得分:0)
问题自我解决了。
现在发送客户端证书的答案可能会有人需要它:)
我们需要PKCS12来发送证书
import Foundation
public class PKCS12 {
let label:String?
let keyID:NSData?
let trust:SecTrust?
let certChain:[SecTrust]?
let identity:SecIdentity?
public init(PKCS12Data:NSData,password:String)
{
let importPasswordOption:NSDictionary = [kSecImportExportPassphrase as NSString:password]
var items : CFArray?
let secError:OSStatus = SecPKCS12Import(PKCS12Data, importPasswordOption, &items)
guard secError == errSecSuccess else {
if secError == errSecAuthFailed {
NSLog("ERROR: SecPKCS12Import returned errSecAuthFailed. Incorrect password?")
}
fatalError("SecPKCS12Import returned an error trying to import PKCS12 data")
}
guard let theItemsCFArray = items else { fatalError() }
let theItemsNSArray:NSArray = theItemsCFArray as NSArray
guard let dictArray = theItemsNSArray as? [[String:AnyObject]] else { fatalError() }
func f<T>(key:CFString) -> T? {
for d in dictArray {
if let v = d[key as String] as? T {
return v
}
}
return nil
}
self.label = f(key: kSecImportItemLabel)
self.keyID = f(key: kSecImportItemKeyID)
self.trust = f(key: kSecImportItemTrust)
self.certChain = f(key: kSecImportItemCertChain)
self.identity = f(key: kSecImportItemIdentity)
}
}
extension URLCredential {
public convenience init?(PKCS12 thePKCS12:PKCS12) {
if let identity = thePKCS12.identity {
self.init(
identity: identity,
certificates: thePKCS12.certChain,
persistence: URLCredential.Persistence.forSession)
}
else { return nil }
}
}
我们还需要x509才能做PKCS12我需要动态生成证书所以代码桥接来自C
-(void) createX509{
OPENSSL_init();
NSString *docPath = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/cert"];
NSString *docPathKey = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/key"];
NSString *docPathp12 = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/p12"];
NSString *dataFile = [NSString stringWithContentsOfFile:docPath
encoding:NSUTF8StringEncoding
error:NULL];
FILE *fp = fopen(docPath.UTF8String, "r");
if(fp == NULL){
fp = fopen(docPath.UTF8String, "w+");
FILE *fpKey = fopen(docPathKey.UTF8String, "w+");
EVP_PKEY * pkey;
pkey = EVP_PKEY_new();
RSA * rsa;
rsa = RSA_generate_key(
2048, /* number of bits for the key - 2048 is a sensible value */
RSA_F4, /* exponent - RSA_F4 is defined as 0x10001L */
NULL, /* callback - can be NULL if we aren't displaying progress */
NULL /* callback argument - not needed in this case */
);
EVP_PKEY_assign_RSA(pkey, rsa);
X509 * x509;
x509 = X509_new();
ASN1_INTEGER_set(X509_get_serialNumber(x509), 1);
X509_gmtime_adj(X509_get_notBefore(x509), 0);
X509_gmtime_adj(X509_get_notAfter(x509), 31536000000L);
X509_set_pubkey(x509, pkey);
X509_NAME * name;
name = X509_get_subject_name(x509);
X509_NAME_add_entry_by_txt(name, "C", MBSTRING_ASC,
(unsigned char *)"CA", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "O", MBSTRING_ASC,
(unsigned char *)"company", -1, -1, 0);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_ASC,
(unsigned char *)"localhost", -1, -1, 0);
X509_set_issuer_name(x509, name);
X509_sign(x509, pkey, EVP_sha1());
[@"" writeToFile:docPath
atomically:YES
encoding:NSUTF8StringEncoding
error:NULL];
fp = fopen(docPath.UTF8String, "a+");
PEM_write_X509(
fp, /* write the certificate to the file we've opened */
x509 /* our certificate */);
PEM_write_PrivateKey(fpKey, pkey, NULL, NULL, 0, NULL, NULL);
fflush(fpKey);
fclose(fpKey);
fflush(fp);
fclose(fp);
dataFile = [NSString stringWithContentsOfFile:docPath
encoding:NSUTF8StringEncoding
error:NULL];
OpenSSL_add_all_algorithms();
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();
PKCS12* p12;
p12 = PKCS12_create("password", "login", pkey, x509, NULL, 0,0,0,0,0);
if(!p12) {
fprintf(stderr, "Error creating PKCS#12 structure\n");
ERR_print_errors_fp(stderr);
exit(1);
}
fp = fopen(docPathp12.UTF8String, "w+");
if (!(fp = fopen(docPathp12.UTF8String, "wb"))) {
ERR_print_errors_fp(stderr);
exit(1);
}
i2d_PKCS12_fp(fp, p12);
PKCS12_free(p12);
fflush(fp);
fclose(fp);
}
现在制作了pkcs12和x05,所以我们继续快速
public let alamofireManager: SessionManager = {
let obj = OpenSSL();
obj.createX509()
var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first;
var certPEM:String!;
var keyPEM:String!;
var certificateToPin:SecCertificate!;
var pkcs12:PKCS12?;
do{
try certPEM = String(contentsOfFile: path! + "/cert").replacingOccurrences(of: "\n", with: "")
try keyPEM = String(contentsOfFile: path! + "/key").replacingOccurrences(of: "\n", with: "")
let p12 = NSData(contentsOfFile: path! + "/p12");
pkcs12 = PKCS12.init(PKCS12Data: p12!, password: "password")
let docsurl = try! FileManager.default.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let urlAp = docsurl.appendingPathComponent("cert");
var cert64 = certPEM.replacingOccurrences(of: "-----BEGIN CERTIFICATE-----", with: "")
cert64 = cert64.replacingOccurrences(of: "-----END CERTIFICATE-----", with: "")
let certificateData = NSData(base64Encoded: cert64, options: .ignoreUnknownCharacters)
certificateToPin = SecCertificateCreateWithData(kCFAllocatorMalloc, certificateData!)
var trust: SecTrust?
let policy = SecPolicyCreateBasicX509()
let status = SecTrustCreateWithCertificates(certificateToPin!, policy, &trust)
let publicKey:SecKey?;
if status == errSecSuccess {
publicKey = SecTrustCopyPublicKey(trust!)!;
}
let dictionary = SecPolicyCopyProperties(policy)
}catch{
print("err")
}
let configuration = URLSessionConfiguration.default
configuration.timeoutIntervalForResource = Request.settings.timeout
let trustPolicies = CertTrustPolicyManager(policies: [:])
var serverTrustPolicy:[String: ServerTrustPolicy] = [
Router.baseURLString : .pinCertificates(
certificates: [certificateToPin],
validateCertificateChain: false,
validateHost: false)
]
var alamofireManager:SessionManager = Alamofire.SessionManager(configuration: configuration, delegate: SessionDelegate(), serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicy))
alamofireManager.delegate.sessionDidReceiveChallenge = { session, challenge in
var disposition: URLSession.AuthChallengeDisposition = .useCredential
var credential: URLCredential?
if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
disposition = URLSession.AuthChallengeDisposition.useCredential
credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
} else {
if challenge.previousFailureCount > 0 {
disposition = .cancelAuthenticationChallenge
} else {
credential = alamofireManager.session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)
if credential != nil {
disposition = .useCredential
}
}
}
let certs = [certificateToPin]
let persist = URLCredential.Persistence.forSession;
return (disposition, URLCredential.init(PKCS12: pkcs12!))
}
return alamofireManager
}()
我需要获得证书,可能有些代码是无用的或写得不好但是它的工作(我是IOS的新手:)),我也将PEM证书转换为DER,但在这些操作之后我是终于能够与发送客户端进行不安全的连接并使用Alamofire创建证书。
以上代码从各处收集!
干杯