2012-04-09 11 views
23

Ich konvertiere ein UIImage zu NSData. Jetzt muss ich diese NSData mit einem öffentlichen Schlüssel verschlüsseln und ich muss mit einem privaten Schlüssel entschlüsseln. Bitte geben Sie eine Schritt für Schritt Anleitung. Welchen Algorithmus brauche ich? Gibt es eine gute Bibliothek für die Verschlüsselung und Entschlüsselung? Stellen Sie auch ein Code-Snippet für die Verschlüsselung und Entschlüsselung bereit.Iphone - Wie NSData mit öffentlichen Schlüssel zu verschlüsseln und mit privaten Schlüssel zu entschlüsseln?

+0

Sobald Sie verschenken Ihre öffentlicher Schlüssel, du hast keine Kontrolle mehr darüber. Jeder kann es an andere weitergeben, das heißt, die Verschlüsselung von Daten mit Ihrem privaten Schlüssel ist Zeitverschwendung. –

+0

@ParthBhatt wirklich ich bin fest. Ja sicher, aber wird es in Ordnung sein, wenn ich es dir am Abend senden kann: u kann das Codebeispiel auf meinen persönliche Mail-ID – sachi

+0

@sachi senden? Bitte geben Sie Ihre E-Mail-ID an. –

Antwort

18

Ich habe RSA-Verschlüsselung und Entschlüsselung versucht, für NSString und Sie können es auch ändern und es für NSData

hinzufügen Security.Framework zu einem Projekt Bündel arbeiten.

ViewController.h Code ist wie folgt:

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

@interface ViewController : UIViewController 
{ 
SecKeyRef publicKey; 
SecKeyRef privateKey; 
    NSData *publicTag; 
    NSData *privateTag; 
} 
- (void)encryptWithPublicKey:(uint8_t *)plainBuffer cipherBuffer:(uint8_t *)cipherBuffer; 
- (void)decryptWithPrivateKey:(uint8_t *)cipherBuffer plainBuffer:(uint8_t *)plainBuffer; 
- (SecKeyRef)getPublicKeyRef; 
- (SecKeyRef)getPrivateKeyRef; 
- (void)testAsymmetricEncryptionAndDecryption; 
- (void)generateKeyPair:(NSUInteger)keySize; 
@end 

ViewController.m Datei Code lautet wie folgt:

#import "ViewController.h" 

const size_t BUFFER_SIZE = 64; 
const size_t CIPHER_BUFFER_SIZE = 1024; 
const uint32_t PADDING = kSecPaddingNone; 
static const UInt8 publicKeyIdentifier[] = "com.apple.sample.publickey"; 
static const UInt8 privateKeyIdentifier[] = "com.apple.sample.privatekey"; 

@implementation ViewController 

-(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)didReceiveMemoryWarning 
{ 
    [super didReceiveMemoryWarning]; 
    // Release any cached data, images, etc that aren't in use. 
} 




- (void)testAsymmetricEncryptionAndDecryption { 

    uint8_t *plainBuffer; 
    uint8_t *cipherBuffer; 
    uint8_t *decryptedBuffer; 



    const char inputString[] = "How to Encrypt data with public key and Decrypt data with private key"; 
    int len = strlen(inputString); 
    // 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 = (uint8_t *)calloc(BUFFER_SIZE, sizeof(uint8_t)); 
    cipherBuffer = (uint8_t *)calloc(CIPHER_BUFFER_SIZE, sizeof(uint8_t)); 
    decryptedBuffer = (uint8_t *)calloc(BUFFER_SIZE, sizeof(uint8_t)); 

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

    NSLog(@"init() plainBuffer: %s", plainBuffer); 
    //NSLog(@"init(): sizeof(plainBuffer): %d", sizeof(plainBuffer)); 
    [self encryptWithPublicKey:(UInt8 *)plainBuffer cipherBuffer:cipherBuffer]; 
    NSLog(@"encrypted data: %s", cipherBuffer); 
    //NSLog(@"init(): sizeof(cipherBuffer): %d", sizeof(cipherBuffer)); 
    [self decryptWithPrivateKey:cipherBuffer plainBuffer:decryptedBuffer]; 
    NSLog(@"decrypted data: %s", decryptedBuffer); 
    //NSLog(@"init(): sizeof(decryptedBuffer): %d", sizeof(decryptedBuffer)); 
    NSLog(@"====== /second test ======================================="); 

    free(plainBuffer); 
    free(cipherBuffer); 
    free(decryptedBuffer); 
} 

/* 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); 
    size_t cipherBufferSize = 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], 
          &cipherBufferSize 
          ); 
    NSLog(@"encryption result code: %ld (size: %lu)", status, cipherBufferSize); 
    NSLog(@"encrypted text: %s", cipherBuffer); 
} 

- (void)decryptWithPrivateKey:(uint8_t *)cipherBuffer plainBuffer:(uint8_t *)plainBuffer 
{ 
    OSStatus status = noErr; 

    size_t cipherBufferSize = strlen((char *)cipherBuffer); 

    NSLog(@"decryptWithPrivateKey: length of buffer: %lu", BUFFER_SIZE); 
    NSLog(@"decryptWithPrivateKey: length of input: %lu", cipherBufferSize); 

    // DECRYPTION 
    size_t plainBufferSize = BUFFER_SIZE; 

    // Error handling 
    status = SecKeyDecrypt([self getPrivateKeyRef], 
          PADDING, 
          &cipherBuffer[0], 
          cipherBufferSize, 
          &plainBuffer[0], 
          &plainBufferSize 
          ); 
    NSLog(@"decryption result code: %ld (size: %lu)", status, plainBufferSize); 
    NSLog(@"FINAL decrypted text: %s", plainBuffer); 

} 



- (SecKeyRef)getPrivateKeyRef { 
    OSStatus resultCode = noErr; 
    SecKeyRef privateKeyReference = NULL; 
// NSData *privateTag = [NSData dataWithBytes:@"ABCD" length:strlen((const char *)@"ABCD")]; 
// if(privateKey == NULL) { 
     [self generateKeyPair:512]; 
     NSMutableDictionary * queryPrivateKey = [[NSMutableDictionary alloc] init]; 

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

     // Get the key. 
     resultCode = SecItemCopyMatching((__bridge CFDictionaryRef)queryPrivateKey, (CFTypeRef *)&privateKeyReference); 
     NSLog(@"getPrivateKey: result code: %ld", resultCode); 

     if(resultCode != noErr) 
     { 
      privateKeyReference = NULL; 
     } 

//  [queryPrivateKey release]; 
// } else { 
//  privateKeyReference = privateKey; 
// } 

    return privateKeyReference; 
} 


#pragma mark - View lifecycle 



- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view, typically from a nib. 
} 

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    // Release any retained subviews of the main view. 
    // e.g. self.myOutlet = nil; 
} 

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    privateTag = [[NSData alloc] initWithBytes:privateKeyIdentifier length:sizeof(privateKeyIdentifier)]; 
    publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)]; 
    [self testAsymmetricEncryptionAndDecryption]; 

} 

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:animated]; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
} 

- (void)viewDidDisappear:(BOOL)animated 
{ 
    [super viewDidDisappear:animated]; 
} 

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    // Return YES for supported orientations 
    if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 
     return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 
    } else { 
     return YES; 
    } 
} 

- (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"); 
    } 
// [privateKeyAttr release]; 
// [publicKeyAttr release]; 
// [keyPairAttr release]; 
} 


@end 

Lassen Sie mich wissen, wenn Sie weitere Hilfe benötigen.

Hoffe, das hilft.

+2

@sachi: Hat diese Antwort Ihnen geholfen? –

+1

ich erhalte diesen Text als verschlüsselten Text - 4ÑÂÊá; è »-vJNàØmY-ú: º ‰ æ- ™ ¬> qS • ¿] ~ Î £ OI ™ via% Sja ... ◊5¬s'6ÒW .. aber ich brauche Base64-Text. Hast du eine Lösung dafür? .. Dank –

+1

@ParthBhatt - wie diese erhalten -> static const UInt8 publicKeyIdentifier [] = "com.apple.sample.publickey"; statisch const UInt8 privateKeyIdentifier [] = "com.apple.sample.privatekey"; Ich habe alle Schlüssel in der Datei .der & .pem. –

14

NSData + AESCrypt.h

#import <Foundation/Foundation.h> 

@interface NSData (AESCrypt) 

- (NSData *)AES256EncryptWithKey:(NSString *)key; 
- (NSData *)AES256DecryptWithKey:(NSString *)key; 

+ (NSData *)dataWithBase64EncodedString:(NSString *)string; 
- (id)initWithBase64EncodedString:(NSString *)string; 

- (NSString *)base64Encoding; 
- (NSString *)base64EncodingWithLineLength:(NSUInteger)lineLength; 

- (BOOL)hasPrefixBytes:(const void *)prefix length:(NSUInteger)length; 
- (BOOL)hasSuffixBytes:(const void *)suffix length:(NSUInteger)length; 

NSData + AESCrypt.m

#import "NSData+AESCrypt.h" 
#import <CommonCrypto/CommonCryptor.h> 

static char encodingTable[64] = 
{ 
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 
    'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 
    'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 
    'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' 
}; 

@implementation NSData (AESCrypt) 

- (NSData *)AES256EncryptWithKey:(NSString *)key{ 
    // 'key' should be 32 bytes for AES256, will be null-padded otherwise 
    char keyPtr[kCCKeySizeAES256 + 1]; // room for terminator (unused) 
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) 

    // fetch key data 
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 

    NSUInteger dataLength = [self length]; 

    //See the doc: For block ciphers, the output size will always be less than or 
    //equal to the input size plus the size of one block. 
    //That's why we need to add the size of one block here 
    size_t bufferSize = dataLength + kCCBlockSizeAES128; 
    void *buffer = malloc(bufferSize); 

    size_t numBytesEncrypted = 0; 
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, 
             keyPtr, kCCKeySizeAES256, 
             NULL /* initialization vector (optional) */, 
             [self bytes], dataLength, /* input */ 
             buffer, bufferSize, /* output */ 
             &numBytesEncrypted); 
    if(cryptStatus == kCCSuccess) 
    { 
    //the returned NSData takes ownership of the buffer and will free it on deallocation 
    return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; 
    } 

    free(buffer); //free the buffer 
    return nil; 
} 

- (NSData *)AES256DecryptWithKey:(NSString *)key{ 

    // 'key' should be 32 bytes for AES256, will be null-padded otherwise 
    char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) 
    bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) 

    // fetch key data 
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding]; 

    NSUInteger dataLength = [self length]; 

    //See the doc: For block ciphers, the output size will always be less than or 
    //equal to the input size plus the size of one block. 
    //That's why we need to add the size of one block here 
    size_t bufferSize = dataLength + kCCBlockSizeAES128; 
    void *buffer = malloc(bufferSize); 

size_t numBytesDecrypted = 0; 
CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, 
             keyPtr, kCCKeySizeAES256, 
             NULL /* initialization vector (optional) */, 
             [self bytes], dataLength, /* input */ 
             buffer, bufferSize, /* output */ 
             &numBytesDecrypted); 

    if(cryptStatus == kCCSuccess) 
    { 
    //the returned NSData takes ownership of the buffer and will free it on deallocation 
    return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; 
    } 

    free(buffer); //free the buffer 
    return nil; 
} 

#pragma mark - 

+ (NSData *)dataWithBase64EncodedString:(NSString *)string 
{ 
    return [[[NSData allocWithZone:nil] initWithBase64EncodedString:string] autorelease]; 
} 

- (id)initWithBase64EncodedString:(NSString *)string 
{ 
    NSMutableData *mutableData = nil; 

    if(string) 
    { 
     unsigned long ixtext = 0; 
     unsigned long lentext = 0; 
     unsigned char ch = 0; 
     unsigned char inbuf[4], outbuf[3]; 
     short i = 0, ixinbuf = 0; 
     BOOL flignore = NO; 
     BOOL flendtext = NO; 
     NSData *base64Data = nil; 
     const unsigned char *base64Bytes = nil; 

     // Convert the string to ASCII data. 
     base64Data = [string dataUsingEncoding:NSASCIIStringEncoding]; 
     base64Bytes = [base64Data bytes]; 
     mutableData = [NSMutableData dataWithCapacity:base64Data.length]; 
     lentext = base64Data.length; 

     while(YES) 
    { 
     if(ixtext >= lentext) break; 
     ch = base64Bytes[ixtext++]; 
     flignore = NO; 

     if((ch >= 'A') && (ch <= 'Z')) ch = ch - 'A'; 
     else if((ch >= 'a') && (ch <= 'z')) ch = ch - 'a' + 26; 
     else if((ch >= '0') && (ch <= '9')) ch = ch - '0' + 52; 
     else if(ch == '+') ch = 62; 
     else if(ch == '=') flendtext = YES; 
     else if(ch == '/') ch = 63; 
     else flignore = YES; 

     if(! flignore) 
     { 
      short ctcharsinbuf = 3; 
      BOOL flbreak = NO; 

      if(flendtext) 
      { 
       if(! ixinbuf) break; 
       if((ixinbuf == 1) || (ixinbuf == 2)) ctcharsinbuf = 1; 
       else ctcharsinbuf = 2; 
       ixinbuf = 3; 
       flbreak = YES; 
      } 

      inbuf [ixinbuf++] = ch; 

      if(ixinbuf == 4) 
      { 
       ixinbuf = 0; 
       outbuf [0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4); 
       outbuf [1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2); 
       outbuf [2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F); 

       for(i = 0; i < ctcharsinbuf; i++) 
       [mutableData appendBytes:&outbuf[i] length:1]; 
      } 

      if(flbreak) break; 
     } 
    } 
} 

    self = [self initWithData:mutableData]; 
    return self; 
} 

#pragma mark - 

    - (NSString *)base64Encoding 
    { 
     return [self base64EncodingWithLineLength:0]; 
    } 

    - (NSString *)base64EncodingWithLineLength:(NSUInteger)lineLength 
    { 
     const unsigned char *bytes = [self bytes]; 
     NSMutableString *result = [NSMutableString stringWithCapacity:self.length]; 
     unsigned long ixtext = 0; 
     unsigned long lentext = self.length; 
     long ctremaining = 0; 
     unsigned char inbuf[3], outbuf[4]; 
     unsigned short i = 0; 
     unsigned short charsonline = 0, ctcopy = 0; 
     unsigned long ix = 0; 

     while(YES) 
     { 
      ctremaining = lentext - ixtext; 
      if(ctremaining <= 0) break; 

      for(i = 0; i < 3; i++) 
      { 
       ix = ixtext + i; 
       if(ix < lentext) inbuf[i] = bytes[ix]; 
       else inbuf [i] = 0; 
      } 

      outbuf [0] = (inbuf [0] & 0xFC) >> 2; 
      outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4); 
      outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6); 
      outbuf [3] = inbuf [2] & 0x3F; 
      ctcopy = 4; 

      switch(ctremaining) 
      { 
       case 1: 
       ctcopy = 2; 
       break; 
       case 2: 
       ctcopy = 3; 
       break; 
      } 

      for(i = 0; i < ctcopy; i++) 
       [result appendFormat:@"%c", encodingTable[outbuf[i]]]; 

      for(i = ctcopy; i < 4; i++) 
       [result appendString:@"="]; 

      ixtext += 3; 
      charsonline += 4; 

      if(lineLength > 0) 
      { 
      if(charsonline >= lineLength) 
      { 
       charsonline = 0; 
       [result appendString:@"\n"]; 
      } 
      } 
    } 

    return [NSString stringWithString:result]; 
    } 
#pragma mark - 
- (BOOL)hasPrefixBytes:(const void *)prefix length:(NSUInteger)length 
{ 
    if(! prefix || ! length || self.length < length) return NO; 
     return (memcmp([self bytes], prefix, length) == 0); 
    } 

    - (BOOL)hasSuffixBytes:(const void *)suffix length:(NSUInteger)length 
    { 
     if(! suffix || ! length || self.length < length) return NO; 
     return (memcmp(((const char *)[self bytes] + (self.length - length)), suffix, length) == 0 ); 
    } 

können Sie den folgenden Code verwenden:

NSData *encryptedData = [UIImagePNGRepresentation(/*your image*/) AES256EncryptWithKey:/*your enc key*/]; 

NSData *plainData = [encryptedData AES256DecryptWithKey:/*your enc key*/]; 

UIImage *img =[UIImage imageWithData:plainData]; 
+1

/* Ihr enc-Schlüssel */kann durch Reverse-Engineering der App abgerufen werden, wenn sie in App direkt als String gespeichert ist. –

+0

Auch keine zwei Schlüssel verwenden –

Verwandte Themen