使用苹果的安全框架导入导出RSA SecKeyRef密钥。

问题描述 投票:1回答:2

我正在创建一个iPhone Objective-C应用程序,它使用服务器和客户端之间的安全通信。我想遵循的协议是这样的。

  1. 客户端被编译并分发了服务器的公共RSA密钥(硬编码)。我们把它叫做Kspub。(代表Key Server Public)

  2. 客户端随机生成一个AES密钥。让我们把这个密钥称为Kcaes(Key Client AES的缩写)。

  3. 客户端使用Kspub对Kcaes进行加密,并生成加密后的文本。Kspub(Kcaes)

  4. 客户端向服务器发送Kspub(Kcaes)。

  5. 服务器使用服务器的私钥Kspri对Kspub(Kcaes)进行解密。这样就恢复了Kcaes。现在客户端和服务器都共享一个共同的AES密钥Kcaes。

  6. 为了验证这一点,服务器使用Kcaes对Kcaes进行加密。这将产生加密的文本Kcaes(Kcaes)。

  7. 服务器将Kcaes(Kcaes)发送给客户端。

  8. 客户端使用Kcaes密钥解密Kcaes(Kcaes)。这将产生Kcaes。如果这与原始的Kcaes相匹配,那么客户端知道它已经建立了一个安全连接。

  9. 现在客户端和服务器可以使用对称密钥Kcaes安全地交换信息。

我已经实现了服务器端和客户端的密钥生成、加密和解密方法。目前,iPhone上生成的密钥对被存储在它的密钥链中。问题是这样的。

我似乎无法在苹果的钥匙链或安全API中找到一种方法来从文本文件中导入一个公共RSA密钥。我如何通过文本文件导入密钥并将其存储在SecKeyRef对象中?

谢谢!我正在创建一个iPhone的Objective API。

ios objective-c security encryption rsa
2个回答
0
投票

你可以通过以下方式来实现 SecItemAdd,传递。

一个包含项目类键值对(Keychain Item Class Keys and Values)和可选的属性键值对(Attribute Item Keys and Values)的字典,指定项目的属性值。

OSStatus err = SecItemAdd((CFDictionaryRef)
    [NSDictionary dictionaryWithObjectsAndKeys:
     (id)kSecClassKey,         kSecClass,
     kSecAttrKeyTypeRSA,       kSecAttrKeyType,
     keyTagUTF8,               kSecAttrApplicationTag,
     kSecAttrKeyClassPrivate,  kSecAttrKeyClass, 
     keyData,                  kSecValueData,
     nil],
 NULL);

确保要存储和检索的属性完全匹配。


0
投票

SecKeyCreateWithData 将接受PKCS#1的RSA数据以及x509公钥格式。

因为问题中提到的是文本文件而不是二进制文件,我假设公钥是标准的PEM格式。首先你要把PEM头和新的行去掉。

NSMutableString *pemString = [textFileString mutableCopy];
[pemString replaceOccurrencesOfString:@"-----BEGIN PUBLIC KEY-----" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [pemString length])];
[pemString replaceOccurrencesOfString:@"-----END PUBLIC KEY-----" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [pemString length])];
[pemString replaceOccurrencesOfString:@"\n" withString:@"" options:NSCaseInsensitiveSearch range:NSMakeRange(0, [pemString length])];

现在你剩下的是一个Base64字符串 你可以将其解码成二进制数据。我想指出的是,苹果原生的Base64方法是不能容忍的。填充问题其他标准.

CFDataRef data = (__bridge CFDataRef) [NSData dataWithBase64EncodedString... // Your preferred base64 method here

现在你可以得到 SecKeyRef 通过 SecKeyCreateWithData.

if (data)
{
    CFMutableDictionaryRef dictionary = CFDictionaryCreateMutable(kCFAllocatorDefault, 3, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    if (dictionary)
    {
        CFDictionarySetValue(dictionary, kSecAttrKeyClass, kSecAttrKeyClassPublic);
        CFDictionarySetValue(dictionary, kSecAttrIsPermanent, kCFBooleanFalse);
        CFDictionarySetValue(dictionary, kSecAttrKeyType, kSecAttrKeyTypeRSA);
        CFErrorRef error = NULL;
        SecKeyRef publicKey = SecKeyCreateWithData(data, dictionary, &error);
        if (publicKey)
        {
            if (error)
            {
                CFShow(error);
                CFRelease(error);
            }
            //...
            CFRelease(publicKey);
        }
        CFRelease(dictionary);
    }
}

在这里,你可以选择保留参考资料,或者决定将其保存在钥匙链中,通过 SecItemAdd 等等。

© www.soinside.com 2019 - 2024. All rights reserved.