2014-05-12 2 views
0

공개 키를 사용하여 RSA로 텍스트를 암호화하려고합니다. 다음 명령을 사용하여 이후xcode에 RSA 암호화

#import "EncViewController.h" 

UInt8 privateKeyIdentifier[] = "-----BEGIN RSA PRIVATE KEY-----\n" 
"MIIEowIBAAKCAQEAqRU6LMhcarK6sgaTgpPEgldUbyBsszsKKpSCDoYqH8fNDpin\n" 
"puYhgR/NDurrZ6t1n3AsyACmmEMbkaxbjJ4Ee8U3zXy3dsbhsshaGWdktlfIipUw\n" 
"4b+ybi4M3T/AcKHSonWw6NWKPLmA/R5nARQMg4tIlRQF6qQPlBaVxk1kHE5NEKxz\n" 
"JaCC01ODsFHEAglDaEMZtGvjGl/hLxI8nqhgLgQsQpU+5ysM4/cmjgqVrU8YzFHp\n" 
"9oMGWdcgQhZR3oJxdrWPn7/Vs5gWKuO6369Pc2kMLv8Tba64uAkNYMQXnMNM+TFy\n" 
"DzNGOAUHkHS70pntrnufsGb8/hRv5nEcZxfd6QIDAQABAoIBAGdUfKfvjmL6dRPk\n" 
"5vLuwTHykrwS8bsawpzBAzZDEa04Wn2oFxTtIN6bg6KxOEmzw/86+3MCyszUfh2p\n" 
"Wo116EGHhhHDPQ+OfVHYFQ/fWvIAdaMTh7r+ftnMtLnlgwKSMnpsOEAieAeiSkzl\n" 
"7ob/LKKbVTEd+nup5YdXwhJdK2gMB1xFLURYi3/ziNXXAb/MxUkldB0B9ZOdDa6Y\n" 
"Ezh1HD2KT3PedZOGuHfXoU2yDi10KeXFjoN6KsOwEJJmicJ1KWevuzYr5zBvZC2N\n" 
"xy6CUHp9iDQONdem1C1cMg/ht4QZpR0Rrz2wRvOxjwUfXd0qel3tBMttHiitRS4u\n" 
"sCF3YwECgYEA3Jj94d1kb0XM5k6y5eS/DODBW+QRI2JRudoQOCnrMnNNYdv6KHvO\n" 
"WfmIDXyw4gi//5NoEDcNf6BPgb487ImXB4AcjMOI0Ox0vNhH300yKbYHF9XgkrvI\n" 
"1aCwE/4QvyBb4zLdt/QxYVxJU9qRC5CsSlqjpsqUBvMhH5mb5DdlMckCgYEAxDfP\n" 
"pFOYHRYYCYDj+Plldf6Z9wSbfp7mOm7j2VvXMgVAlG1HixIcXW10GG0vq3Obpl4Z\n" 
"Li8bik4aX9pN/rRGEgZxNbOc92QkzwkNO00W4L2yHdwD5ONXT8IB8KW7uq3BILld\n" 
"nPm3H9lR+eoLYCbGBJVVAux43uFJHmip8dSKWyECgYAyAxV8AX9losODa1Avwp51\n" 
"wvbTaG9iQEYbBo8qzIYgF/fxObgLOZZc26+2rxBDDozI2ph7JKAQ0T11QrX5QnBV\n" 
"KPxQBXydMR5+OeKBg7TdtAEDrF+PpLcxh46j2bPeQO3UIpIVxGz1j8CoHCNKJfCJ\n" 
"oub7R24r7S8TRPYM1WpB0QKBgBgepC+W9wPcS2gfp+ZbAdXXTiXHMzYFYlecefWm\n" 
"DHXhn2afaEP4HfR+F99IzKtOsrtopb+/mqsNnsBZnWzJzDM7B3+KbKkcbknk2vOH\n" 
"LmDB8Lsq6G+iYoEzX/ms5b60zSCwqIk7SP9pP2JxGqTfH0hA8wpA9zquhsZuJzXK\n" 
"4pcBAoGBAKDJhWP7pM66jrSuxX8+dOlQpb+u6oRkcwEFLEXP7Blz45MJVGGAdjCj\n" 
"hYgz9bg5pNywBiwE1MbBDw/CZejcQk5CgSY0AfDqsBRipHJ7N7KR8aZfpJi4JSgy\n" 
"c5qnAC1sBY/zDjERsOX0CJQfumr5/ae9y637ezvDXVkHcIoNjRxx\n" 
"-----END RSA PRIVATE KEY-----"; 
SecKeyRef privateKey; 
NSData *privateTag; 

const size_t BUFFER_SIZE = 64; 
const size_t CIPHER_BUFFER_SIZE = 1024; 
size_t FINAL_CIPHER_BUFFER_SIZE; 
const uint32_t PADDING = kSecPaddingPKCS1; 

UInt8 publicKeyIdentifier[] = "-----BEGIN PUBLIC KEY-----\n" 
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqRU6LMhcarK6sgaTgpPE\n" 
"gldUbyBsszsKKpSCDoYqH8fNDpinpuYhgR/NDurrZ6t1n3AsyACmmEMbkaxbjJ4E\n" 
"e8U3zXy3dsbhsshaGWdktlfIipUw4b+ybi4M3T/AcKHSonWw6NWKPLmA/R5nARQM\n" 
"g4tIlRQF6qQPlBaVxk1kHE5NEKxzJaCC01ODsFHEAglDaEMZtGvjGl/hLxI8nqhg\n" 
"LgQsQpU+5ysM4/cmjgqVrU8YzFHp9oMGWdcgQhZR3oJxdrWPn7/Vs5gWKuO6369P\n" 
"c2kMLv8Tba64uAkNYMQXnMNM+TFyDzNGOAUHkHS70pntrnufsGb8/hRv5nEcZxfd\n" 
"6QIDAQAB\n" 
"-----END PUBLIC KEY-----\n"; 

@interface EncViewController() 

@end 

@implementation EncViewController 

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 
{ 
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 
    if (self) { 
     // Custom initialization 
    } 
    return self; 
} 

- (void)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

/* 
#pragma mark - Navigation 

// In a storyboard-based application, you will often want to do a little preparation before navigation 
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender 
{ 
// Get the new view controller using [segue destinationViewController]. 
// Pass the selected object to the new view controller. 
} 
*/ 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    privateTag = [[NSData alloc] initWithBytes:privateKeyIdentifier length:sizeof(privateKeyIdentifier)]; 
    publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)]; 

    const char *plainBuffer; 
    const char *cipherBuffer; 

    NSString *textToEncrypt = @"super secret text"; 



    //const char inputString[] = "How to Encrypt data with public key and Decrypt data with private key"; 
    int len = strlen(textToEncrypt.UTF8String); 
    // TODO: this is a hack since i know inputString length will be less than BUFFER_SIZE 
    if (len > BUFFER_SIZE) len = BUFFER_SIZE-1; 

    plainBuffer = calloc(BUFFER_SIZE, sizeof(uint8_t)); 
    cipherBuffer = calloc(CIPHER_BUFFER_SIZE, sizeof(uint8_t)); 
    plainBuffer = [textToEncrypt UTF8String]; 
    NSLog(@"init() plainBuffer: %s", plainBuffer); 
    [self encryptWithPublicKey:plainBuffer cipherBuffer:cipherBuffer]; 
    NSLog(@"encrypted data: %s", cipherBuffer); 

    const char *d = cipherBuffer; 
    int l = strlen(d); 
    NSLog(@"final length: %d",l); 

    NSData *encodeData = [[NSData alloc] initWithBytes:cipherBuffer length:FINAL_CIPHER_BUFFER_SIZE]; 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); 
    NSString *cachePath = [paths objectAtIndex:0]; 
    NSLog(@"cache dir: %@",cachePath); 

    BOOL written = [encodeData writeToFile:[NSString stringWithFormat:@"%@%@",cachePath,@"/test.txt"] atomically:NO]; 
    NSLog(@"File was writtend: %d",written); 

    NSString *base64String = [encodeData base64EncodedStringWithOptions:0]; 
    NSLog(@"Encode String Value: %@", base64String); 

    free(plainBuffer); 
    free(cipherBuffer); 
} 

- (NSString *)encryptText:(NSString *)textToEncrypt 
{ 
    uint8_t *plainBuffer; 
    uint8_t *cipherBuffer; 
    const char *input = [textToEncrypt UTF8String]; 

    int len = strlen(input); 

    plainBuffer = (uint8_t *)calloc(len, sizeof(uint8_t)); 
    cipherBuffer = (uint8_t *)calloc(CIPHER_BUFFER_SIZE, sizeof(uint8_t)); 

    strncpy((char *)plainBuffer, input, len); 

    NSLog(@"init() plainBuffer: %s", plainBuffer); 
    //NSLog(@"init(): sizeof(plainBuffer): %d", sizeof(plainBuffer)); 
    [self encryptWithPublicKey:(UInt8 *)plainBuffer cipherBuffer:cipherBuffer]; 
    NSLog(@"encrypted data: %s", cipherBuffer); 
    NSString *s = [NSString stringWithUTF8String:(char *)cipherBuffer]; 
    NSLog(@"encrypted nsstring %@",s); 
    NSData *data = [[NSData alloc] initWithBytes:cipherBuffer length:sizeof(cipherBuffer)]; 
    NSLog(@"====== /second test ======================================="); 

    free(plainBuffer); 
    //free(cipherBuffer); 
    return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
} 

/* Borrowed from: 
* https://developer.apple.com/library/mac/#documentation/security/conceptual/CertKeyTrustProgGuide/iPhone_Tasks/iPhone_Tasks.html 
*/ 
- (void)encryptWithPublicKey:(uint8_t *)plainBuffer cipherBuffer:(uint8_t *)cipherBuffer 
{ 

    NSLog(@"== encryptWithPublicKey()"); 

    OSStatus status = noErr; 

    NSLog(@"** original plain text 0: %s", plainBuffer); 

    size_t plainBufferSize = strlen((char *)plainBuffer); 

    FINAL_CIPHER_BUFFER_SIZE = CIPHER_BUFFER_SIZE; 

    NSLog(@"SecKeyGetBlockSize() public = %lu", SecKeyGetBlockSize([self getPublicKeyRef])); 
    // Error handling 
    // Encrypt using the public. 
    status = SecKeyEncrypt([self getPublicKeyRef], 
          PADDING, 
          plainBuffer, 
          plainBufferSize, 
          &cipherBuffer[0], 
          &FINAL_CIPHER_BUFFER_SIZE 
          ); 
    NSLog(@"encryption result code: %ld (size: %lu)", status, FINAL_CIPHER_BUFFER_SIZE); 
    NSLog(@"encrypted text: %s", cipherBuffer); 
} 

-(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 private key dictionary. 
    [privateKeyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecAttrIsPermanent]; 
    [privateKeyAttr setObject:privateTag forKey:(__bridge id)kSecAttrApplicationTag]; 
    // See SecKey.h to set other flag values. 

    // 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:privateKeyAttr forKey:(__bridge id)kSecPrivateKeyAttrs]; 
    [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"); 
    } 
} 

@end 

내가 생성 된 암호화 된 파일 (TEST.TXT)을 해독하기 위해 노력하고있어 :

//EncViewController.h  
#import <UIKit/UIKit.h> 

@interface EncViewController : UIViewController 
{ 
    SecKeyRef publicKey; 
    NSData *publicTag; 
} 

- (void)encryptWithPublicKey:(uint8_t *)plainBuffer cipherBuffer:(uint8_t *)cipherBuffer; 
- (SecKeyRef)getPublicKeyRef; 

@end 

및 구현 파일 :

이 지금까지 코드는 터미널에서 :

고양이 test.txt | OpenSSL을 rsautl -pkcs -decrypt -inkey private.pem 출력 나의 해독 된 메시지 가 있지만 대신 다음과 같은 오류 받아야한다 :

RSA 연산 오류 15328 : 오류 : 0407106B가 : RSA 루틴 : RSA_padding_check_PKCS1_type_2가 : 블록 타입이 아닌 02 : /SourceCache/OpenSSL098/OpenSSL098-50/src/crypto/rsa/rsa_pk1.c : 190 : 15328 : 오류 : 04065072 : rsa 루틴 : RSA_EAY_PRIVATE_DECRYPT : 패딩 검사 실패 :/SourceCache/OpenSSL098/OpenSSL098-50/src/crypto /rsa/rsa_eay.c:614 :

I하지받을 이유는 ... 엑스 코드의 암호화 및 openssl 명령을 사용하여 암호 해독에 모두 같은 패딩을 사용하기 때문에

답변

0

문자를 사용하여 키를 처리하는 것은 매우 까다로운 작업이었습니다.

CommonCrypto에서 이미 지원하므로 공개 키/인증서의 .DER 형식을 사용하는 것이 훨씬 쉽습니다. .DER를 직접 사용하여 문제를 해결했습니다. 이처럼로드 할 수

SecCertificateRef certificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)publicKeyFileContent);

을 publicKeyFileContent이 .der과 내용을 포함하는있는 NSData 인스턴스입니다.