简体   繁体   English

在iOS中仅使用模数和指数使用RSA加密字符串

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

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. 我有一个我想在IOS(6)中使用的服务,该服务由我无法控制的第三方提供。

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. 为了对服务进行身份验证,我需要将用户凭据作为RSA加密字符串发送,并使用其RSA公钥加密。

They have supplied me with an XML file with the following format 他们向我提供了以下格式的XML文件

<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. 我来自DOTNET背景,因此到目前为止,大多数复杂性对我来说还是模糊不清的。

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 我已经尝试过这样的示例: Objective C中的RSA实现,但是无法从我已有的对象中构建对象,它们似乎需要证书

i have tried using this tool to convert it to a PEM file, but again the code will not build the cert object. 我曾尝试使用此工具将其转换为PEM文件,但是代码仍然无法构建cert对象。 https://superdry.apphb.com/tools/online-rsa-key-converter 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; //返回accumatedEncryptedData; return [accumulatedEncryptedData base64EncodedString]; 返回[accumulatedEncryptedData base64EncodedString];

Get the PEM string for the public key using the converter you mentioned, or write some code to do the transformation yourself. 使用您提到的转换器获取公共密钥的PEM字符串,或者编写一些代码自己进行转换。

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. 立即更改:然后,获取此处找到的代码并使用它将公钥添加到iOS钥匙串中。

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. 请注意,我正在使用PKCS1填充,而您可能没有。 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. 如果是这样,则取决于您是希望代码适用于iOS 5还是仅适用于iOS 6,我刚刚链接到的博客文章中的其余信息是否相关。

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. 最后,我们使用了http://chilkatsoft.com/rsa-objc.asp,因为它是完全无缝的,并且为了价格,我花了更多的钱试图让iOS原生地做。

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. 当我在IOS上加密时,Mathews代码似乎确实起作用了,但从未成功解密该代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM