C# 如何从iOS SecKeyRef中提取RSA参数?

C# 如何从iOS SecKeyRef中提取RSA参数?,c#,ios,xamarin.ios,cryptography,rsa,C#,Ios,Xamarin.ios,Cryptography,Rsa,我正在调用iOSSecKeyGeneratePair方法来生成RSA密钥对。现在我想从中提取RSA参数(公共和私有数据)。我该怎么做 我已经找到了这个示例,但我看不出它实际上是在将密钥导出到它们的原始数据中。此外,这是客观的C,我真的很努力摸索 我在Xamarin.iOS(C#)移动应用程序中实现了这一点,因此我需要用C#编写最终解决方案,方法是在iOS中调用必要的互操作API(就像调用SecKeyGeneratePair) 对于那些熟悉Xamarin的人,是的,我知道我可以使用new rsac

我正在调用iOS
SecKeyGeneratePair
方法来生成RSA密钥对。现在我想从中提取RSA参数(公共和私有数据)。我该怎么做

我已经找到了这个示例,但我看不出它实际上是在将密钥导出到它们的原始数据中。此外,这是客观的C,我真的很努力摸索

我在Xamarin.iOS(C#)移动应用程序中实现了这一点,因此我需要用C#编写最终解决方案,方法是在iOS中调用必要的互操作API(就像调用
SecKeyGeneratePair


对于那些熟悉Xamarin的人,是的,我知道我可以使用
new rsacryptserviceprovider()
更轻松地完成这项工作。当我使用本机API生成RSA密钥(甚至加密位本身)时,不同之处在于性能提高了2-3个数量级。因此,虽然我必须使用本机API进行RSA工作,但我还需要获取原始数据,以便跨平台。

AFAIK您不能直接提取参数。苹果开发者论坛上有一些关于这方面的讨论(你可能想查看一下)。遗憾的是,(关于发布代码的)假设是实现细节,随时可能发生更改

您仍然可以使用可用的API间接地执行此操作,例如,将其导出为PKCS#12,然后从中获取RSA参数

更新:验证后,您只能导入PKCS#12-因此这无助于导出私钥。我又回到了“没有支持的方法”的问题上。除了使用托管代码之外,我能想到的唯一安全的选择是包含本机代码(第三方库)以生成密钥对

我曾经尝试过类似的方法(导入,而不是导出),但额外操作所需的时间使我的代码比只使用C#慢。你的情况很不一样


注意:在我看来,钥匙链访问(进程外,加密…)造成了大部分的减速。导入公钥一次性使用是不值得的,但是如果您多次(重新)使用它,那么(一次性)成本对您来说可能是可以接受的。SecKeyGeneratePair是一个较旧的API,由只在iOS 10中可用的
SecKeyCreateRandomKey
取代。因此,我将使用问题所涉及的旧函数进行回答。我将坚持核心基础API来与C语言的互操作性。

通过将公钥和私钥原始数据添加到密钥链并以数据字节的形式返回,可以导出公钥和私钥数据。下面是一个例子:

//Convert key object into data
SecKeyRef givenKey = publicOrPrivateFromSecKeyGeneratePair;
static const uint8_t publicKeyIdentifier[] = "com.company.myTempRSAKey"; //make it unique per key
CFDataRef publicTag = CFDataCreate(kCFAllocatorDefault, publicKeyIdentifier, sizeof(publicKeyIdentifier));
if (publicTag)
{
    OSStatus sanityCheck = noErr;
    CFDataRef publicKeyBits = NULL;

    //Create a dictionary info object describing that we are using RSA
    CFMutableDictionaryRef queryPublicKey = CFDictionaryCreateMutable(kCFAllocatorDefault, 5, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
    if (queryPublicKey)
    {
        CFDictionaryAddValue(queryPublicKey, kSecClass, kSecClassKey);
        CFDictionaryAddValue(queryPublicKey, kSecAttrApplicationTag, publicTag);
        CFDictionaryAddValue(queryPublicKey, kSecAttrKeyType, kSecAttrKeyTypeRSA);
        CFDictionaryAddValue(queryPublicKey, kSecAttrKeyClass, kSecAttrKeyClassPublic); //for public or:
        //CFDictionaryAddValue(queryPublicKey, kSecAttrKeyClass, kSecAttrKeyClassPrivate); //for private
        CFDictionaryAddValue(queryPublicKey, kSecAttrAccessible, kSecAttrAccessibleWhenUnlockedThisDeviceOnly); //other options...

        CFMutableDictionaryRef attributes = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 7, queryPublicKey);
        if (attributes)
        {
            // Temporarily add key to the Keychain, return as data:
            CFDictionaryAddValue(attributes, kSecValueRef, givenKey);
            CFDictionaryAddValue(attributes, kSecReturnData, kCFBooleanTrue);

            CFTypeRef result = NULL;
            sanityCheck = SecItemAdd(attributes, &result);
            if (sanityCheck == errSecSuccess)
            {
                publicKeyBits = (CFDataRef)result; // Use the RAW key here

                // Remove the temp key from the Keychain
                sanityCheck = SecItemDelete(queryPublicKey);
                if (sanityCheck != errSecSuccess)
                {
                    //... Error deleting temporary public key from keychain
                }
            }
            // else - failsafe code if key exists, try to delete first and then add item etc.

            CFRelease(attributes);
        }
        CFRelease(queryPublicKey);
    }
     CFRelease(publicTag);
}
这将获得原始数据。它是原始的,因为它缺少了苹果以外的大多数系统所期望的标题。例如,RSA公钥的ASN.1 OID值后跟一个终止的空字节

//HEX: 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00

/*
 SEQUENCE {
 OBJECTIDENTIFIER 1.2.840.113549.1.1.1 (rsaEncryption)
 NULL
 }
 */

因此,如果你在寻找原始数据,你就有了它。如果您试图通过“参数”从原始数据中提取模数和指数,您也可以这样做(例如,位流:mod+exp)。如果这是您想要的,请告诉我。

导出到PKCS#12是完全可以接受的。我正在生成一个4096位密钥,对于托管实现,它有时可能需要几个小时,因此我确信与生成本机密钥相比,过程和导出开销将是微不足道的。如果您有如何导出密钥的链接,请共享。ThanksApple文档可能已经过时了,但是文档长度限制是2048位——现在我知道4096位可以工作(我的5S大约需要1分钟),但是我不能说它是否可以在所有设备上工作(或者在iOS7之前)。链接到apple dev的论坛帖子:谢谢。我很乐意把目标锁定在7号。