IOS中RSA的加密解密

来源:互联网 发布:核辐射测量仪 淘宝 编辑:程序博客网 时间:2024/05/01 00:47

最近闲了在网上看看别人的RSA的加密解密,自己也做了做。


1.     DOS框下输入命令行openssl req -x509 -days 3650 -new -newkey rsa:2048 -keyout private_key_self_signed_cert.pem 

-out private_key_self_signed_cert.pem生成私钥。接下来就是公司名字,省市,还有名字的一些信息按着给下填就行。

2.    openssl pkcs12 -export -out pkcs.p12 -in private_key_self_signed_cert.pem  生成p12格式的文件。

3.   openssl x509 -in private_key_self_signed_cert.pem -inform PEM -out public_key.der -outform DER 生成自签名证书。

4.  //证书获取公钥

- (OSStatus)extractPublicKeyFromCertificateFile {    OSStatus status = -1;    if (_publicKey == nil) {        SecTrustRef trust;        SecTrustResultType trustResult;         NSDate *derData = [NSData dataWithContentsOfFile:[NSBundle mainBundle] pathForResource:@"public_key" ofType:@"der"]];        if (derData) {            SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)derData);            SecPolicyRef policy = SecPolicyCreateBasicX509();            status = SecTrustCreateWithCertificates(cert, policy, &trust);            if (status == errSecSuccess && trust) {                NSArray *certs = [NSArray arrayWithObject:(id)cert];                status = SecTrustSetAnchorCertificates(trust, (CFArrayRef)certs);                if (status == errSecSuccess) {                    status = SecTrustEvaluate(trust, &trustResult);                    // 自签名证书可信                    if (status == errSecSuccess && (trustResult == kSecTrustResultUnspecified || trustResult == kSecTrustResultProceed)) {                        _publicKey = SecTrustCopyPublicKey(trust);                        if (_publicKey) {                            NSLog(@"Get public key successfully~ %@", _publicKey);                        }                        if (cert) {                            CFRelease(cert);                        }                        if (policy) {                            CFRelease(policy);                        }                        if (trust) {                            CFRelease(trust);                        }                    }                }            }        }    }    return status;}


5. 用公钥对数据加密。

//加密- (NSMutableData *)encryptWithPublicKey:(NSData *)plainData {    // 分配内存块,用于存放加密后的数据段    size_t cipherBufferSize = SecKeyGetBlockSize(_publicKey);    uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));    double totalLength = [plainData length];    size_t blockSize = cipherBufferSize - 12;    size_t blockCount = (size_t)ceil(totalLength / blockSize);    NSMutableData *encryptedData = [NSMutableData data];    // 分段加密    for (int i = 0; i < blockCount; i++) {        NSUInteger loc = i * blockSize;        // 数据段的实际大小。最后一段可能比blockSize小。        int dataSegmentRealSize = MIN(blockSize, [plainData length] - loc);        // 截取需要加密的数据段        NSData *dataSegment = [plainData subdataWithRange:NSMakeRange(loc, dataSegmentRealSize)];        OSStatus status = SecKeyEncrypt(_publicKey, kSecPaddingPKCS1, (const uint8_t *)[dataSegment bytes], dataSegmentRealSize, cipherBuffer, &cipherBufferSize);        if (status == errSecSuccess) {            NSData *encryptedDataSegment = [[NSData alloc] initWithBytes:(const void *)cipherBuffer length:cipherBufferSize];            // 追加加密后的数据段            [encryptedData appendData:encryptedDataSegment];            [encryptedDataSegment release];        } else {            if (cipherBuffer) {                free(cipherBuffer);            }            return nil;        }    }    if (cipherBuffer) {        free(cipherBuffer);    }    return encryptedData;}



6. 获取私钥。

   //从p12文件中获取私钥 ,密码是你生成私钥的时候生成的

- (OSStatus)extractEveryThingFromPKCS12File:(NSString *)pkcsPath passphrase:(NSString *)pkcsPassword {    SecIdentityRef identity;    SecTrustRef trust;    OSStatus status = -1;        if (_privateKey == nil) {        NSData *p12Data = [NSData dataWithContentsOfFile:pkcsPath];        if (p12Data) {            CFStringRef password = (CFStringRef)pkcsPassword;            const void *keys[] = {                kSecImportExportPassphrase            };            const void *values[] = {                password            };            CFDictionaryRef options = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 1, NULL, NULL);            CFArrayRef items = CFArrayCreate(kCFAllocatorDefault, NULL, 0, NULL);            status = SecPKCS12Import((CFDataRef)p12Data, options, &items);            if (status == errSecSuccess) {                CFDictionaryRef identity_trust_dic = CFArrayGetValueAtIndex(items, 0);                identity = (SecIdentityRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemIdentity);                trust = (SecTrustRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemTrust);                // certs数组中包含了所有的证书                CFArrayRef certs = (CFArrayRef)CFDictionaryGetValue(identity_trust_dic, kSecImportItemCertChain);                if ([(NSArray *)certs count] && trust && identity) {                    // 如果没有下面一句,自签名证书的评估信任结果永远是kSecTrustResultRecoverableTrustFailure                    status = SecTrustSetAnchorCertificates(trust, certs);                    if (status == errSecSuccess) {                        SecTrustResultType trustResultType;                        // 通常, 返回的trust result type应为kSecTrustResultUnspecified,如果是,就可以说明签名证书是可信的                        status = SecTrustEvaluate(trust, &trustResultType);                        if ((trustResultType == kSecTrustResultUnspecified || trustResultType == kSecTrustResultProceed) && status == errSecSuccess) {                            // 证书可信,可以提取私钥与公钥,然后可以使用公私钥进行加解密操作                            status = SecIdentityCopyPrivateKey(identity, &_privateKey);                            if (status == errSecSuccess && _privateKey) {                                // 成功提取私钥                                NSLog(@"Get private key successfully~ %@", _privateKey);                            }                        }                    }                }            }            if (options) {                CFRelease(options);            }        }    }    return 0;}


7.数据解密。

- (NSData *)decryptWithPrivateKey:(NSData *)cipherData {    // 分配内存块,用于存放解密后的数据段    size_t plainBufferSize = SecKeyGetBlockSize(_privateKey);    NSLog(@"plainBufferSize = %zd", plainBufferSize);    uint8_t *plainBuffer = malloc(plainBufferSize * sizeof(uint8_t));    // 计算数据段最大长度及数据段的个数    NSLog(@"totalLength = %d", [cipherData length]);    int totalLength = [cipherData length];    NSLog(@"totalLength = %d", totalLength);    size_t blockSize = plainBufferSize;    size_t blockCount = (size_t)ceil(totalLength / blockSize);    NSMutableData *decryptedData = [NSMutableData data];    // 分段解密    for (int i = 0; i < blockCount; i++) {        NSUInteger loc = i * blockSize;        // 数据段的实际大小。最后一段可能比blockSize小。        int dataSegmentRealSize = MIN(blockSize, totalLength - loc);        // 截取需要解密的数据段        NSData *dataSegment = [cipherData subdataWithRange:NSMakeRange(loc, dataSegmentRealSize)];        OSStatus status = SecKeyDecrypt(_privateKey, kSecPaddingPKCS1, (const uint8_t *)[dataSegment bytes], dataSegmentRealSize, plainBuffer, &plainBufferSize);        if (status == errSecSuccess) {            NSData *decryptedDataSegment = [[NSData alloc] initWithBytes:(const void *)plainBuffer length:plainBufferSize];            [decryptedData appendData:decryptedDataSegment];            [decryptedDataSegment release];        } else {            if (plainBuffer) {                free(plainBuffer);            }            return nil;        }    }    if (plainBuffer) {        free(plainBuffer);    }    return decryptedData;}