- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试以编程方式在 iOS(iPhone/iPhone 模拟器)上安装 SSL 证书。 我已经使用 this small guide 成功创建并安装了 .crt
! 但是当我尝试将获得的 server.crt
转换为 server.der
并以编程方式安装它时,我得到 CFNetwork SSLHandshake failed (-9807)
。请注意,我在 iOS 上使用此证书的 .der
版本,在 OS X openssl 服务器上使用 .crt
版本。
转换:
openssl x509 -outform der -in server.crt -out server.der
在 OS X 上接收:
openssl s_server -key server.key -cert server.crt -accept 1678
在iOS上安装和发送:
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSData *iosTrustedCertDerData =
[NSData dataWithContentsOfFile:[bundle pathForResource:@"certificate"
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\n";
int bytesWritten = CFWriteStreamWrite(writeStream, buf, strlen((char*)buf));
}
那么,如何在iOS上正确转换和安装.der
证书呢?
更新:
NSBundle *bundle = [NSBundle bundleForClass:[self class]];
NSString *resourcePath = [bundle pathForResource:@"certificate" ofType:@"der"];
NSData *certData = [NSData dataWithContentsOfFile:resourcePath];
NSString* publickKeyRef = @"certificate_der";
NSData* headerStrippedData = [self stripPublicKeyHeader:certData];
[self addPeerPublicKey:publickKeyRef keyBits:headerStrippedData];
SecKeyRef ref= [self getPublicKeyReference:publickKeyRef];
printf("adding finished \n");
CFReadStreamRef readStream;
CFWriteStreamRef writeStream;
CFStreamCreatePairWithSocketToHost(NULL,
(CFStringRef)@"localhost",
1678,
&readStream,
&writeStream);
CFReadStreamSetProperty(readStream,
kCFStreamPropertySocketSecurityLevel,
kCFStreamSocketSecurityLevelTLSv1);
CFReadStreamOpen(readStream);
CFWriteStreamOpen(writeStream);
异常发生在这一行:
[self addPeerPublicKey:publickKeyRef keyBits:headerStrippedData];
异常(exception):
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: object cannot be nil (key: v_Data)'
*** First throw call stack:
(
0 CoreFoundation 0x00a81a14 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x00540e02 objc_exception_throw + 50
2 CoreFoundation 0x0096a174 -[__NSDictionaryM setObject:forKey:] + 948
3 ssl2 0x0006d8eb -[ViewController addPeerPublicKey:keyBits:] + 491
4 ssl2 0x0006e2dd -[ViewController viewDidLoad] + 397
5 UIKit 0x010932ae -[UIViewController _sendViewDidLoadWithAppearanceProxyObjectTaggingEnabled] + 44
6 UIKit 0x01097dce -[UIViewController loadViewIfRequired] + 1384
7 UIKit 0x010981ed -[UIViewController view] + 35
8 UIKit 0x00f45f94 -[UIWindow addRootViewControllerViewIfPossible] + 69
9 UIKit 0x00f466b1 -[UIWindow _setHidden:forced:] + 304
10 UIKit 0x00f46a67 -[UIWindow _orderFrontWithoutMakingKey] + 49
11 UIKit 0x00f5a118 -[UIWindow makeKeyAndVisible] + 80
12 UIKit 0x00ec26e7 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4190
13 UIKit 0x00ec9cd6 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1989
14 UIKit 0x00eeeee5 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke3218 + 68
15 UIKit 0x00ec6966 -[UIApplication workspaceDidEndTransaction:] + 163
16 FrontBoardServices 0x0373fc76 __37-[FBSWorkspace clientEndTransaction:]_block_invoke_2 + 71
17 FrontBoardServices 0x0373f74d __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 54
18 FrontBoardServices 0x0375d173 -[FBSSerialQueue _performNext] + 184
19 FrontBoardServices 0x0375d5aa -[FBSSerialQueue _performNextFromRunLoopSource] + 52
20 FrontBoardServices 0x0375c8a6 FBSSerialQueueRunLoopSourceHandler + 33
21 CoreFoundation 0x0099b6ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
22 CoreFoundation 0x0099138b __CFRunLoopDoSources0 + 523
23 CoreFoundation 0x009907a8 __CFRunLoopRun + 1032
24 CoreFoundation 0x009900e6 CFRunLoopRunSpecific + 470
25 CoreFoundation 0x0098fefb CFRunLoopRunInMode + 123
26 UIKit 0x00ec6206 -[UIApplication _run] + 540
27 UIKit 0x00ecbbfa UIApplicationMain + 160
28 ssl2 0x0006e91a main + 138
29 libdyld.dylib 0x0310ba21 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
最佳答案
在 iOS 中,它有点不同,您需要将此 .der
文件添加到您的钥匙串(keychain),然后从您的钥匙串(keychain)引用它。我正在提供下面的代码以添加钥匙串(keychain)并从钥匙串(keychain)中取回
- (void)addPeerPublicKey:(NSString *)peerName keyBits:(NSData *)publicKeyData {
OSStatus sanityCheck = noErr;
CFTypeRef persistPeer = NULL;
[self removePeerPublicKey:peerName];
NSData * peerTag = [[NSData alloc] initWithBytes:(const void *)[peerName UTF8String] length:[peerName length]];
NSMutableDictionary * peerPublicKeyAttr = [[NSMutableDictionary alloc] init];
[peerPublicKeyAttr setObject:(id)kSecClassKey forKey:(id)kSecClass];
[peerPublicKeyAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[peerPublicKeyAttr setObject:peerTag forKey:(id)kSecAttrApplicationTag];
[peerPublicKeyAttr setObject:publicKeyData forKey:(id)kSecValueData];
[peerPublicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnData];
sanityCheck = SecItemAdd((CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef *)&persistPeer);
if(sanityCheck == errSecDuplicateItem)
{
NSLog(@"HanselErrorCode: -1");
}
persistPeer = NULL;
[peerPublicKeyAttr removeObjectForKey:(id)kSecValueData];
sanityCheck = SecItemCopyMatching((CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef*)&persistPeer);
if (persistPeer) CFRelease(persistPeer);
}
-(SecKeyRef)getPublicKeyReference:(NSString*)peerName
{
OSStatus sanityCheck = noErr;
SecKeyRef pubKeyRefData = NULL;
NSData * peerTag = [[NSData alloc] initWithBytes:(const void *)[peerName UTF8String] length:[peerName length]];
NSMutableDictionary * peerPublicKeyAttr = [[NSMutableDictionary alloc] init];
[peerPublicKeyAttr setObject:(id)kSecClassKey forKey:(id)kSecClass];
[peerPublicKeyAttr setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
[peerPublicKeyAttr setObject:peerTag forKey:(id)kSecAttrApplicationTag];
[peerPublicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey: (id)kSecReturnRef];
sanityCheck = SecItemCopyMatching((CFDictionaryRef) peerPublicKeyAttr, (CFTypeRef*)&pubKeyRefData);
if(pubKeyRefData)
{
return pubKeyRefData;
}
else
{
return nil;
}
}
- (NSData *)stripPublicKeyHeader:(NSData *)d_key
{
// Skip ASN.1 public key header
if (d_key == nil) return(nil);
unsigned int len = (unsigned int)[d_key length];
if (!len) return(nil);
unsigned char *c_key = (unsigned char *)[d_key bytes];
unsigned int idx = 0;
if (c_key[idx++] != 0x30) return(nil);
if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
else idx++;
// PKCS #1 rsaEncryption szOID_RSA_RSA
static unsigned char seqiod[] =
{ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
0x01, 0x05, 0x00 };
if (memcmp(&c_key[idx], seqiod, 15)) return(nil);
idx += 15;
if (c_key[idx++] != 0x03) return(nil);
if (c_key[idx] > 0x80) idx += c_key[idx] - 0x80 + 1;
else idx++;
if (c_key[idx++] != '\0') return(nil);
// Now make a new NSData from this buffer
return([NSData dataWithBytes:&c_key[idx] length:len - idx]);
}
- (void)removePeerPublicKey:(NSString *)peerName
{
OSStatus sanityCheck = noErr;
NSData * peerTag = [[NSData alloc] initWithBytes:(const void *)[peerName UTF8String] length:[peerName length]];
NSMutableDictionary * peerPublicKeyAttr = [[NSMutableDictionary alloc] init];
[peerPublicKeyAttr setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
[peerPublicKeyAttr setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[peerPublicKeyAttr setObject:peerTag forKey:(__bridge id)kSecAttrApplicationTag];
sanityCheck = SecItemDelete((__bridge CFDictionaryRef) peerPublicKeyAttr);
}
要使用此 key ,您必须执行以下操作
NSString *resourcePath = [bundle pathForResource:@"publickey" ofType:@"der"];
NSData *certData = [NSData dataWithContentsOfFile:resourcePath];
NSData* headerStrippedData = [self stripPublicKeyHeader:certData];
[self addPeerPublicKey:publickKeyRef keyBits:headerStrippedData];
SecKeyRef ref= [self getPublicKeyReference:publickKeyRef];
最后使用 ref
实现所有目的。
NSString* publickKeyRef = @"key_name_against_which_you_want_to_save_your_der";
此代码向您展示了添加、取回和使用它的方法。几个月前我从互联网上获取了这段代码——如果你找到了,请添加源代码链接。在 Xcode8 中,您必须添加钥匙串(keychain)的名称(publicKeyRef
),您将在功能部分中使用此 der 文件。
关于ios - 无法以编程方式在 iOS 上安装 .der 证书,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39776417/
我听说最好不要从您系统的 Perl 版本所在的 CPAN 安装模块。我知道如何使用命令行安装模块,我只是想知道是否有办法将 CPAN 与系统核心 Perl 分开。 我应该: 下载源代码并专门为这些模块
我听说最好不要从系统的 Perl 版本所在的 CPAN 安装模块。我知道如何使用命令行安装模块,我只是想知道是否有办法将 CPAN 与系统的核心 Perl 分开。 我应该: 下载源代码并专门为这些模块
单独安装 electron 与通过 electron-builder 安装有什么区别?我正在使用 React 构建一个 Electron 应用程序,并且已经找到了一些教程。它们安装 Electron
两者安装有什么区别?我按照安装页面上的说明在全局范围内安装了 webpack,然后我转到了入门指南,据说在那里可以在本地安装 webpack-cli。 CLI = Command Line Inter
我在 OS X Yosemite 上用 PHP 安装了默认的 Apache 服务器,安装了 pear,用 brew 安装了 Solr (brew install solr),现在我正在尝试使用 PEC
我解压并编译了 Ruby 2.1 并安装了几个支持工具。 但是当我安装了 libssl-dev 时,OpenSSL 不会安装。 我在支持 openssl 时遇到这个错误: make: *** No r
我在 android studio 2.3.1 和 gradle 3.2 中设计了 2 到 3 个应用程序。当我从它运行应用程序到任何设备或模拟器时,一切都工作正常。但是当我从构建文件夹中获取该 ap
我注意到我正在读一本书提到通过 apt-get 安装 numpy 和 opencv apt-get install python-numpy python-opencv 但我可以通过以下方式在 pip
我正在尝试在 Windows 8.1 上安装 ansicon。我提取了文件并达到了我需要调用 ansicon -i 的级别。当我在 cmd 中输入此内容并运行 python 脚本时效果很好,但是当我通
我有 linux MINT 17.3 Kernel 4.4.0-81 所有更新可用。 (由于不同的原因,我无法迁移到更新版本的 ubuntu/mint) 我已经通过 PPA 安装了 FFMPEG(不是
尝试在本地运行我的应用程序时出现错误: 我只在 chrome 浏览器中收到此错误。我尝试过不同的东西,但我不确定为什么它是 Chrome 特定的。 最佳答案 我怀疑这不是 Firebase 问题,而是
这是我第一次开发 AngularJS 应用程序并使用脚手架工具 Yeoman ( http://yeoman.io/ )。我想对我的一些图标使用 fontawesome ( http://fortaw
我知道您通常“应该”$ pip install 如果包没有 brew ,但如果有一个你想安装的 python 包,你可以使用 $ pip install或 $ brew install为了?例如,通过
我正在尝试通过 RVM 安装 Ruby 1.9.3。然而,当谈到安装 RubyGems 时,我得到了这个: curl: (22) The requested URL returned error: 4
我是真正提出问题的新手,但你去吧。 我一直在尝试按照安装指南添加 dnsname: https://github.com/containers/dnsname https://github.com/c
Studio更新至0.4.0 建筑产量为“需要1.8版Gradle”;将设置设置为1.8 bin目录; 建立 “要求1.9级”;将设置设置为1.9 bin; 建立 “要求1.8级” 啊。不知道该怎么做
我刚刚注意到 kernel.org 因维护而停机。是否有使用不同镜子的不同公式?或者我可以向 Homebrew 软件添加不同的来源(如 bundler ?)? 谢谢你的帮助! 最佳答案 快速解决方法:
当我运行时: peardev install phpunit/PHPUnit 我得到以下信息: No releases available for package "pear.phpunit.de/P
服务器操作系统为Fedora 24. 64bit。 我想安装 Git 2.6.6。 所以下载源码并安装。 此服务器离线。所以我不使用“yum”。 ./configure --prefix=/usr/l
我正在尝试在我自己的服务器(操作系统:Linux Ubuntu Server 12.04)上安装 OpenEdX,但我遇到了同样的错误。谁能帮帮我? TASK: [ insights | insta
我是一名优秀的程序员,十分优秀!