【问题标题】:Encrypt a NSString using RSA algorithm使用 RSA 算法加密 NSString
【发布时间】:2013-11-23 01:03:06
【问题描述】:

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

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

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

【问题讨论】:

  • 如果你改用[testPubKey bytes]会怎样?
  • 这真的只是在黑暗中刺伤,因此是评论....您将提供 NSData 对象作为一个整体。在调用encryptRSA... 实现时,我肯定会尝试提供它包装的原始数据(也就是使用bytes)。

标签: ios objective-c encryption


【解决方案1】:

简单的方法

Use Chilkat iOS RSA Library。一个主要缺点:售价 189 美元! :O

艰难的路

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

【讨论】:

  • 为什么它不适用于像 CCCrypt 这样的简单缓冲区?
猜你喜欢
  • 1970-01-01
  • 2013-04-04
  • 1970-01-01
  • 2019-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-08
  • 2019-05-04
相关资源
最近更新 更多