Encrypting a string with RSA using only the modulus and exponent in iOS

烂漫一生 提交于 2019-12-13 04:25:17

问题


I know there is a lot of questions and answers similar on here, but I have searched and cannot find one that works for me.

I have a service I want to consume in IOS (6), provided by a third party of which I have no control.

In order to authenticate with the service I need to send my user credentials as an RSA encrypted string, encrypted with their RSA public key.

They have supplied me with an XML file with the following format

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

What do I need to do in order to encrypt the string? I am from a DOTNET background so most of the complexity has been obscured for me up to now.

I have tried examples such as this: RSA implementations in Objective C but there is no way to build the objects from what I have, they seem to need a cert

i have tried using this tool to convert it to a PEM file, but again the code will not build the cert object. https://superdry.apphb.com/tools/online-rsa-key-converter

Thanks in advance for any help.

**** EDIT **** This is part of a method I have created using the examples provided, it runs without error but I cant decode the output:

   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);

// return accumulatedEncryptedData; return [accumulatedEncryptedData base64EncodedString];


回答1:


Get the PEM string for the public key using the converter you mentioned, or write some code to do the transformation yourself.

EDIT: Sorry, I pasted the wrong link. Changed it now: Then, Grab the code found here and use it to add the public key to the iOS keychain.

You can get the public key reference back from the keychain using the following code:

+ (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;
}

Now you can use the code I wrote to encrypt data using a public key, found here. Note that I am using PKCS1 padding and you may not be. If you are, then depending on whether you want your code to work for iOS 5 or just iOS 6, the rest of the information in the blog post I just linked to will be relevant or not.




回答2:


In the end we went with http://chilkatsoft.com/rsa-objc.asp as is was completely seamless, and for the price, I was burning more money trying to get iOS to do it natively.

It will take the modulus and exponent parts and or a cert. Mathews code did seem to work when I encrypted on IOS but never got it to decrypt on the service successfully.



来源:https://stackoverflow.com/questions/14607635/encrypting-a-string-with-rsa-using-only-the-modulus-and-exponent-in-ios

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!