1

我有一个指数和一个模数如何使用 RSA 算法加密 NSString。我浏览过很多论坛。但还是觉得很混乱。谁能给我正确的方法来使用具有指数和模数的RSA 算法加密NSString ?

我目前正在尝试这个。但仍然得到一个错误的加密字符串

publicTag = [self PublicKeyItems];
SecKeyRef publicKeyData = [self getPublicKeyRef];

NSString* result = (NSString*)[self encryptRSA:@"Shob" key:publicKeyData];

以及以下实现

- (NSData *)PublicKeyItems
{
    NSMutableArray *publicarray = [[NSMutableArray alloc] init];
    [publicarray addObject:encryptionExponent];
    [publicarray addObject:encryptionModulus];
    NSData *testData = [publicarray berData];
    NSLog(@"testdata = %@",testData);
    return testData;
}

-(SecKeyRef)getPublicKeyRef 
{

OSStatus sanityCheck = noErr;
SecKeyRef publicKeyReference = NULL;

if (publicKeyReference == NULL) {
    [self generateKeyPair:512];
    NSMutableDictionary *queryPublicKey = [[NSMutableDictionary alloc] init];

    // Set the public key query dictionary.
    [queryPublicKey setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass];
    [queryPublicKey setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];
    [queryPublicKey setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
    [queryPublicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];


    // Get the key.
    sanityCheck = SecItemCopyMatching((__bridge CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKeyReference);


    if (sanityCheck != noErr)
    {
        publicKeyReference = NULL;
    }


    //        [queryPublicKey release];

} else { publicKeyReference = publicKey; }

return publicKeyReference;
}

- (void)generateKeyPair:(NSUInteger)keySize {
OSStatus sanityCheck = noErr;
publicKey = NULL;
privateKey = NULL;

//  LOGGING_FACILITY1( keySize == 512 || keySize == 1024 || keySize == 2048, @"%d is an invalid and unsupported key size.", keySize );

// First delete current keys.
//  [self deleteAsymmetricKeys];

// Container dictionaries.
NSMutableDictionary * privateKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary * publicKeyAttr = [[NSMutableDictionary alloc] init];
NSMutableDictionary * keyPairAttr = [[NSMutableDictionary alloc] init];

// Set top level dictionary for the keypair.
[keyPairAttr setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[keyPairAttr setObject:[NSNumber numberWithUnsignedInteger:keySize] forKey:(__bridge id)kSecAttrKeySizeInBits];


// Set the public key dictionary.
[publicKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecAttrIsPermanent];
[publicKeyAttr setObject:publicTag forKey:(__bridge id)kSecAttrApplicationTag];
// See SecKey.h to set other flag values.

// Set attributes to top level dictionary.
[keyPairAttr setObject:publicKeyAttr forKey:(__bridge id)kSecPublicKeyAttrs];

// SecKeyGeneratePair returns the SecKeyRefs just for educational purposes.
sanityCheck = SecKeyGeneratePair((__bridge CFDictionaryRef)keyPairAttr, &publicKey, &privateKey);
//  LOGGING_FACILITY( sanityCheck == noErr && publicKey != NULL && privateKey != NULL, @"Something really bad went wrong with generating the key pair." );
if(sanityCheck == noErr  && publicKey != NULL && privateKey != NULL)
{
    NSLog(@"Successful");
}
//  [privateKeyAttr release];
//  [publicKeyAttr release];
//  [keyPairAttr release];
}

-(NSString *)encryptRSA:(NSString *)plainTextString key:(SecKeyRef)publicKeyNext {
size_t cipherBufferSize = SecKeyGetBlockSize(publicKeyNext);
uint8_t *cipherBuffer = malloc(cipherBufferSize);
uint8_t *nonce = (uint8_t *)[plainTextString UTF8String];
SecKeyEncrypt(publicKeyNext,
              kSecPaddingOAEP,
              nonce,
              strlen( (char*)nonce ),
              &cipherBuffer[0],
              &cipherBufferSize);
NSData *encryptedData = [NSData dataWithBytes:cipherBuffer length:cipherBufferSize];
NSString* encryptedString       =   [NSString stringWithFormat:@"%@",encryptedData];
return encryptedString;
}
4

1 回答 1

0

简单的方法

使用 Chilkat iOS RSA 库。一个主要缺点:售价 189 美元!:O

艰难的路

解析 XML,使用SCZ-BasicEncodingRules-iOS从模数和指数中生成公钥数据。如果可行,请使用该公钥创建一个虚拟钥匙串(在此处遵循示例代码),现在以 SecKeyRef 格式提取公钥并将其传递给问题中的 encryptRSA 方法。最后,清理,删除虚拟钥匙串。理论上听起来不错,但我从未彻底测试过,如果你这样做了,请告诉我!

于 2013-11-11T10:19:42.467 回答