문제

문자열을 암호화하고 암호화된 데이터가 포함된 다른 문자열을 반환할 수 있도록 올바른 방향을 알려줄 수 있는 사람이 있나요?(저는 AES256 암호화를 시도했습니다.) 두 개의 NSString 인스턴스를 사용하는 메서드를 작성하고 싶습니다. 하나는 암호화할 메시지이고 다른 하나는 암호화할 '비밀번호'입니다. 비밀번호가 암호화된 데이터와 함께 제공되는 경우 역전될 수 있는 방식으로 비밀번호가 포함된 암호화 키.그런 다음 메서드는 암호화된 데이터에서 생성된 NSString을 반환해야 합니다.

나는 에 자세히 설명된 기술을 시도했습니다. 이 글의 첫댓글, 하지만 지금까지 운이 없었어요.애플의 암호화폐운동 확실히 뭔가가 있긴 한데, 이해가 안 가네요...제가 참고한 내용을 많이 봤는데 CCC크립트, 그러나 내가 사용한 모든 경우에 실패했습니다.

또한 암호화된 문자열을 해독할 수 있어야 하지만 kCCEncrypt/kCCDecrypt만큼 간단하기를 바랍니다.

도움이 되었습니까?

해결책

코드를 게시하지 않았기 때문에 어떤 문제가 발생했는지 정확히 알기가 어렵습니다.하지만 링크한 블로그 게시물은 꽤 괜찮은 것 같습니다...각 호출의 추가 쉼표를 제외하고 CCCrypt() 이로 인해 컴파일 오류가 발생했습니다.

해당 게시물에 대한 이후 댓글에는 다음이 포함됩니다. 이 적응 코드, 그것은 나에게 효과적이며 좀 더 간단해 보입니다.NSData 카테고리에 대한 코드를 포함하면 다음과 같이 작성할 수 있습니다.(메모:그만큼 printf() 호출은 다양한 지점의 데이터 상태를 보여주기 위한 것일 뿐입니다. 실제 애플리케이션에서는 이러한 값을 인쇄하는 것이 의미가 없습니다.)

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    NSString *key = @"my password";
    NSString *secret = @"text to encrypt";

    NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding];
    NSData *cipher = [plain AES256EncryptWithKey:key];
    printf("%s\n", [[cipher description] UTF8String]);

    plain = [cipher AES256DecryptWithKey:key];
    printf("%s\n", [[plain description] UTF8String]);
    printf("%s\n", [[[NSString alloc] initWithData:plain encoding:NSUTF8StringEncoding] UTF8String]);

    [pool drain];
    return 0;
}

이 코드와 암호화된 데이터가 항상 NSString으로 잘 변환되지는 않는다는 사실을 고려하면 필요한 기능을 정방향 및 역방향으로 래핑하는 두 가지 메서드를 작성하는 것이 더 편리할 수 있습니다.

- (NSData*) encryptString:(NSString*)plaintext withKey:(NSString*)key {
    return [[plaintext dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptWithKey:key];
}

- (NSString*) decryptData:(NSData*)ciphertext withKey:(NSString*)key {
    return [[[NSString alloc] initWithData:[ciphertext AES256DecryptWithKey:key]
                                  encoding:NSUTF8StringEncoding] autorelease];
}

이것은 확실히 Snow Leopard에서 작동합니다. @보즈 CommonCrypto가 iPhone의 핵심 OS의 일부라고 보고합니다.10.4와 10.5 모두 /usr/include/CommonCrypto, 10.5에는 다음에 대한 매뉴얼 페이지가 있지만 CCCryptor.3cc 10.4는 그렇지 않으므로 YMMV입니다.


편집하다: 보다 이 후속 질문 안전한 무손실 변환을 사용하여 암호화된 데이터 바이트를 문자열(원하는 경우)로 표현하기 위해 Base64 인코딩을 사용하는 방법에 대해 설명합니다.

다른 팁

나는 NSData 및 NSString에 대한 카테고리 모음을 구성했습니다. Jeff Lamarche의 블로그 그리고 일부 힌트 스택 오버플로에서 Quinn Taylor에 의해.

카테고리를 사용하여 NSDATA를 확장하여 AES256 암호화를 제공하고 Base64- 인코드 암호화 데이터로의 NSString 확장을 문자열로 안전하게 제공합니다.

다음은 암호화 문자열의 사용법을 보여주는 예입니다.

NSString *plainString = @"This string will be encrypted";
NSString *key = @"YourEncryptionKey"; // should be provided by a user

NSLog( @"Original String: %@", plainString );

NSString *encryptedString = [plainString AES256EncryptWithKey:key];
NSLog( @"Encrypted String: %@", encryptedString );

NSLog( @"Decrypted String: %@", [encryptedString AES256DecryptWithKey:key] );

여기에서 전체 소스 코드를 가져옵니다.

https://gist.github.com/838614

유용한 힌트에 감사드립니다!

- 마이클

@Owlstead, "주어진 답변 중 하나의 암호적으로 안전한 변형"에 대한 귀하의 요청에 관한 @Owlstead는 참조하십시오. rncryptor. 그것은 당신이 요청하는 것을 정확하게 수행하도록 설계되었으며 (여기에 나열된 코드의 문제에 대한 응답으로 구축되었습니다).

RNCryptor는 소금과 함께 PBKDF2를 사용하고, 임의의 IV를 제공하며, HMAC (자체 염으로 PBKDF2에서 생성 된 경우도 동기 및 비동기 조작을 지원합니다.

나는 @quinntaylor에서 그의 답변을 업데이트하기 위해 조금 기다렸다. 코코아 응용 프로그램에서 이것을 사용했지만 iOS 응용 프로그램에서도 잘 작동 할 것입니다. 아크 오류가 없습니다.

AppDelegate.m 또는 AppDelegate.mm 파일의 @implementation 섹션 전에 붙여 넣으십시오.

#import <CommonCrypto/CommonCryptor.h>

@implementation NSData (AES256)

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

@end

원하는 @implementation 클래스 에이 두 기능을 붙여 넣으십시오. 제 경우에는 appdelegate.mm 또는 appdelegate.m 파일에서 @implementation appdelegate를 선택했습니다.

- (NSString *) encryptString:(NSString*)plaintext withKey:(NSString*)key {
    NSData *data = [[plaintext dataUsingEncoding:NSUTF8StringEncoding] AES256EncryptWithKey:key];
    return [data base64EncodedStringWithOptions:kNilOptions];
}

- (NSString *) decryptString:(NSString *)ciphertext withKey:(NSString*)key {
    NSData *data = [[NSData alloc] initWithBase64EncodedString:ciphertext options:kNilOptions];
    return [[NSString alloc] initWithData:[data AES256DecryptWithKey:key] encoding:NSUTF8StringEncoding];
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top