0

我知道这里有很多类似的问题和答案,但我已经搜索并找不到适合我的问题。

我有一个我想在 IOS (6) 中使用的服务,由我无法控制的第三方提供。

为了通过服务进行身份验证,我需要将我的用户凭据作为 RSA 加密字符串发送,并使用他们的 RSA 公钥加密。

他们为我提供了以下格式的 XML 文件

<BitStrength>1024</BitStrength>
<RSAKeyValue>
<Modulus>xxxxxxxxxxxxxxxxxxxxx</Modulus>
<Exponent>xxxx</Exponent>
</RSAKeyValue>

为了加密字符串,我需要做什么?我来自 DOTNET 背景,所以到目前为止,大部分复杂性对我来说都是模糊的。

我试过这样的例子: RSA implementations in Objective C but there is no way to build objects from what I have, they're seem to need a cert

我曾尝试使用此工具将其转换为 PEM 文件,但代码不会再次构建 cert 对象。 https://superdry.apphb.com/tools/online-rsa-key-converter

提前感谢您的帮助。

**** 编辑 **** 这是我使用提供的示例创建的方法的一部分,它运行没有错误,但我无法解码输出:

   SStatus status = noErr;

size_t cipherBufferSize;
uint8_t *cipherBuffer;

// [cipherBufferSize]
size_t dataSize = [plainTextString lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
const uint8_t* textData = [[plainTextString dataUsingEncoding:NSUTF8StringEncoding] bytes];

NSAssert(publicKey, @"The public key being referenced by tag must have been stored in the keychain before attempting to encrypt data using it!");

//  Allocate a buffer

cipherBufferSize = SecKeyGetBlockSize(publicKey);
// plain text block size must be 11 less than cipher buffer size because of
// the PKSC1 padding used:
const size_t blockSizeMinusPadding = cipherBufferSize - 11;
cipherBuffer = malloc(cipherBufferSize);

NSMutableData* accumulatedEncryptedData = [NSMutableData dataWithCapacity:0];

for (int ii = 0; ii*blockSizeMinusPadding < dataSize; ii++) {
    const uint8_t* dataToEncrypt = (textData+(ii*blockSizeMinusPadding));
    const size_t subsize = (((ii+1)*blockSizeMinusPadding) > dataSize) ? blockSizeMinusPadding-(((ii+1)*blockSizeMinusPadding) - dataSize) : blockSizeMinusPadding;

    // Encrypt using the public key.
    status = SecKeyEncrypt(publicKey,
                           kSecPaddingOAEP,
                           dataToEncrypt,
                           subsize,
                           cipherBuffer,
                           &cipherBufferSize
                           );

    [accumulatedEncryptedData appendBytes:cipherBuffer length:cipherBufferSize];
}

if (publicKey) CFRelease(publicKey);

free(cipherBuffer);

// 返回累积加密数据;返回 [accumulatedEncryptedData base64EncodedString];

4

2 回答 2

1

使用您提到的转换器获取公钥的 PEM 字符串,或编写一些代码自己进行转换。

编辑:对不起,我粘贴了错误的链接。现在更改它:然后,获取在此处找到的代码并使用它将公钥添加到 iOS 钥匙串。

您可以使用以下代码从钥匙串中获取公钥引用:

+ (SecKeyRef)copyPublicKeyForTag:(NSString*)tag
{
    SecKeyRef publicKey = NULL;

    NSData * publicTag = [NSData dataWithBytes:[tag cStringUsingEncoding:NSUTF8StringEncoding]
                                        length:[tag length]];

    NSMutableDictionary *queryPublicKey =
    [[NSMutableDictionary alloc] init];

    [queryPublicKey setObject:(id)kSecClassKey forKey:(id)kSecClass];
    [queryPublicKey setObject:publicTag forKey:(id)kSecAttrApplicationTag];
    [queryPublicKey setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType];
    [queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(id)kSecReturnRef];

    OSStatus status = SecItemCopyMatching
    ((CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKey);

    if (status != noErr) {
        return nil;
    }

    return publicKey;
}

现在您可以使用我编写的代码使用公钥加密数据,在此处找到。请注意,我正在使用PKCS1填充,而您可能不会。如果您是,那么取决于您是否希望您的代码适用于 iOS 5 或仅适用于 iOS 6,我刚刚链接到的博客文章中的其余信息将是相关的或不相关的。

于 2013-01-30T23:34:41.833 回答
0

最后,我们选择了http://chilkatsoft.com/rsa-objc.asp,因为它是完全无缝的,而且对于价格,我花了更多的钱试图让 iOS 原生地做到这一点。

它将采用模数和指数部分和/或证书。当我在 IOS 上加密但从未成功在服务上解密时,Mathews 代码似乎确实有效。

于 2013-02-26T15:49:57.007 回答